-
Notifications
You must be signed in to change notification settings - Fork 213
Mixin composition #540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This comment was originally written by @simonpai link to discussion: |
Yes, mixin composition is a useful notion and it would be nice to have it. It won't happen in the first release though. Set owner to @gbracha. |
Removed this from the Later milestone. |
Removed Oldschool-Milestone-Later label. |
It would be great if we could have it (say for version 2.0, whenever that comes), since it - along with removing some of the restrictions - would allow the libraries to use mixins in a more consistent and usable manner. Currently, in order to have a proper ListMixin that is usable by itself, we have to copy (textually) the implementation of IterableMixin, because otherwise the user would have to know to extend with both IterableMixin and ListMixin to get the full behavior. (Remove some more restrictions, and we won't have to have separate Mixin and Base classes, which would be awesome!) |
@leafpetersen - is this covered by the super mixins proposal? |
@lrhn I think this is still on your wishlist, but I don't think we really need this to track the feature do we? Feel free to re-open if you want to keep this one around. |
I think I'll keep it open for now. It is a wish, even for the platform libraries (our The new syntax will definitely make it easier to define composite mixins. |
Marking as request since this does not specify a specific approach to introducing composite mixins, just the issue that you can't. |
Having something as:
Would be a very nice refinement on the language |
will have access to imported fragment declarations. This is necessary because there is no mixin composition in dart: dart-lang/language#540
Another issue related to mixin composition is that we can't express a generic type T that extends more than one interface. So if I have four mixins, and I want to create a generic method that only accepts objects that implement two of those mixins, I can't do that. Java supports multiple bounds with |
I'm trying to do |
@lukepighetti Depends on what you want it to do, but if you want the the mixin |
That's exactly it. My use case was attaching |
For the record, the SDK contains a |
If you need to extend the mixin, which contains only abstract methods, you can use
|
I need mixin composition in my work right now. Since @lrhn mentioned, could anybody help me what's the hard way to implement it in the current version? I think mixin is a thing meant to be composed. It's wired that they cannot compose their own kinds. |
No more words needed 😉 |
This would be great! Maybe on the 10 year anniversary of this issue? 😆 |
Not quite the same, but you can do: mixin A { void testA() => print("Hello from A"); }
mixin B on A { void testB() => testA(); }
class C with A, B { }
void main() => C().testB(); // "Hello from A" The only difference is that |
It would be great to see the issue description updated to make it more relevant to the state that Dart is in today and not 2013.
Since the amount of upvotes has been used before to highlight the importance of new language features, I think the state that this issue is in right now is unfair to those who want to see Dart support mixin composition. |
@modulovalue Just FYI, the original ticket of the second broken link also got ported to GitHub, but it's mostly irrelevant now: |
It would be really great to have this, as currently i am working on an app that includes custom features, where each feature can change a different part of the app. essentially, I have mixins that define certain methods that allow each function, but I also have mixins that abstract other mixins for example, if i have a mixin that handles a websocket and pipes the data into relevant methods (say, i dont really see any reason why this cant be easily implemented, as it just abstracts this unnecessary boilerplate. i really want to be able to just define a class CustomFeature extends BaseFeature with WebsocketDialogMixin, FileEditorGuiMixin, SomeOtherFeatureMixin {} as it is i have to do class CustomFeature extends BaseFeature with WebsocketMixin, WebsocketDialogMixin, FileDetailsMixin, FileEditorGuiMixin, SomeOtherBaseFeatureMixin, SomeOtherFeatureMixin {} which genuinely sucks |
I have the same situation and feeling. It's suck when I defining my class like this. class ZombieModel extends GameObject<ZombieModel> with IsBody, IsCharacter, IsMonster, Breakable, Movable {
} instead of class ZombieModel extends GameObject<ZombieModel> with IsMonster, Breakable, Movable {
} while |
Are there any new developments in this issue? I remembered it after the medium post for Dart 3 release, in my opinion, this could be a great time to add some focus to it. |
Didn't happen, let's hope for the 15 years anniversary! |
What does it take to make this happen? Isn't it a simple task to have mixin Bar1 {}
mixin Bar2 {}
mixin Foo with Bar1, Bar2 {}
class A with Foo {} be syntax sugar for mixin Bar1 {}
mixin Bar2 {}
mixin Foo on Bar1, Bar2 {}
// or abstract mixin class Foo implements Bar1, Bar2 {}
class A with Foo, Bar1, Bar2 {} Or is there something I'm missing here? |
@TekExplorer It almost is that simple, at the core. It's all the details that cost. If you do mixin Foo on Super1, Super2 with Bar1, Bar2 { members } then the compiler will have to check that the combined interface Should be doable, but might need a little spec-work to apply a mixin to a combined supertinterface, without requiring that the result is fully defined yet. Every mixin remembers which We need to compute that for Also, can you do Then, as you say, the mixin application of class C extends SomeSuper with Bar1, Bar2, Foo { } where The static checking is a little more complicated, because we want to phrase errors in terms of the user's So, if If We should also define what happens when you combine composite mixins, like: mixin Baz on Super1, Super2, Super3 with Foo, Qux {} where Then we should consider whether this change would interact badly with other possible future language changes. Obviously that's mainly the ones we've actually thought about, like adding constructors to mixin (can't find issue specifically for it, mentioned here: #1605 (comment), and also things like #3242). I actually think the specified behavior here is very compatible with the design for constructors (it's simple and based on just doing repeated mixin application, so if we can do it once, we probably can do it repeatedly), so that shouldn't be a problem. All in all, I think it's doable, but a language change is never trivial. |
I feel like we can almost treat a combined mixin as though the composite (the mixin that mixes other mixins) is treated like a normal mixin that happens to have all of the code from the other mixins, pre-applied as through normal mixin rules, and just so happens to there's nothing actually wrong with this code: mixin Foo1 {
int i = 0;
}
mixin Foo2 {
void doThing() => print('hi');
}
/// mixin Foo3 with Foo1, Foo2 {}
mixin Foo3 implements Foo1, Foo2 { // mixin class works the same
@override
int i = 0;
@override
void doThing() => print('hi');
}
class RealClass with Foo3 { // includes Foo1 and Foo2
int idk() {
doThing();
return i++;
}
} It just violates DRY therefore, we could say that any compiler checking is done on this virtual "flattened" mixin the only real concern as far as I can tell is that each method just needs to remember where it actually came from. All mixin rules apply exactly as they do now, since its effective syntax sugar. There is very little additional logic, on the high level. I do recognize that the analyzer would not necessarily see this as a trivial change, but as far as the language itself is concerned, we can mostly reuse logic. |
from time to time I end up needing mixin composition. is there any workaround to this? |
Exactly what I have shown. |
Any updates if this could happen in the near future? |
Mixin composition is not part of any current plans. |
It'll make code gen easier by writ of not needing to duplicate implementations (which you can't do with macros anyway) when trying to make composite mixins. So... Yes, it can help code gen do something it currently physically cannot. Not without a lot of wrapper-indirection BS that's dependant on implementation. |
@lrhn Now that macros are deprecated (per 29th of January) does that change the priority of mixin composition? Wrt. codegen, then mixins in general can help with keeping the generated code small, and mixin composition will improve that a tad as well. |
This issue was originally filed by @simonpai
Currently Dart does not support direct mixin composition as mentioned in the document (http://www.dartlang.org/articles/mixins/). However if we have a way to either define M1 * M2 or just make
X, Y valid mixin candidates, it will come in very handy to build flexible class plugins.
Algebraically there is no loophole to define the composition operator, and the association will work perfectly.
Related issue:
http://www.dartbug.com/8127
The text was updated successfully, but these errors were encountered: