How to group mixins in Dart? - dart

I have a base package that defines A:
class A {}
Then a package that defines this:
mixin Aa on A {}
mixin Ab on A {}
abstract class First extends A with Aa, Ab{}
and another that defines this:
mixin Ax on A {}
mixin Ay on A {}
abstract class Last extends A with Ax, Ay {}
Then the package that gets that together with the problem
abstract class Clazz extends A with First, Last {} // <- Can't have those mixins bc they don't extend from Object
Question: Is there a way of grouping mixins or are we forced to implement them one by one?

You are forced to implement the one-by-one.
There is currently no way to combine mixins into units that can be applied as one.
Hopefully there will eventually be something like that. It's one the language team's radar (https://github.com/dart-lang/language/issues/540), but so is a lot of other enhancements.

Related

Second order generics in Dart

Can you have second order generics in Dart?
abstract class Foo<T, ContainerType<T>> {}
class FooList<T> extends Foo<T, List<T>> {}
Yes, and some more characters to make it 30
I think what you want is something like:
abstract class Foo<T, C extends Iterable<T>> {}
class FooList<T> extends Foo<T, List<T>> {}
(If not, try refining the question and say what you want to achieve).

Mixins in dart 2.1 - "on" keyword

From:
https://medium.com/dartlang/announcing-dart-2-1-improved-performance-usability-9f55fca6f31a
Under Mixins:
mixin SomeClass<T extends SomeOtherClass>
on State<T>
implements ThirdClass
What is "on"?
This mixin can only be applied to classes that extend or implement State<T> which is effectively the state of a stateful widget.
Figuratively speaking on is the extends for mixins.
mixin A on B
is like
class A extends B
To choose which one to use is like to choose between composition or inheritance. More on that composition vs inheritance thing.
What is the difference?
class ExtraPowers{}
class ClassPowers extends ExtraPowers{}
mixin MixinPowers on ExtraPowers{}
Let's say our main character is class "C" and we want to give it some extra capabilities and powers. We can do that in two ways:
// e.g. inheritance
class C extends ClassPowers{}
or
// e.g. composition
class C with ExtraPowers, MixinPowers{}
So if we choose to extend we may need to comply to some requirements. And we can do that by passing arguments to super.
If we choose to gain powers by using with can't use super to pass requirements. The requirements are satisfied by having the same extra powers as our mixin (nothing is left hidden e.g composition) and that on keyword tells us what extra powers our mixin has. So in order to get powers from MixinPowers we first must get ExtraPowers.
class C with ExtraPowers, MixinPowers{}
In conclusion on just like extends gives access to members of another object but on is for mixins extends for classes. The difference is when you use mixin you must implement the objects after the on keyword.
More info

Is this a class based on map? or maybe class with two types?

On a flutter example project I stumbled upon those lines:
abstract class BlocEvent extends Object {}
abstract class BlocState extends Object {}
abstract class BlocEventStateBase<BlocEvent, BlocState> {}
Is this a class based on map? or maybe class with two types?
What is the meaning of <BlocEvent, BlocState>?
It's a generic type declaration, but as #yelliver pointed out, the example you posted is not correct, since BlocEvent and BlocState inside <> are just interpreted as generic type identifiers (unrelated to the classes with the same name).
This would make sense:
abstract class BlocEvent extends Object {}
abstract class BlocState extends Object {}
abstract class BlocEventStateBase<T extends BlocEvent, S extends BlocState> {}
Also, note that there are conventions for naming type parameters.

mixin whose super class is not Object

i want to do something like the following so bad
abstract class A{}
abstract class B extends A{}
abstract class C extends A{}
abstract class D extends B with C{} //C cannot be used as a mixin because it extends a class other than object
is there any solution other than copying the content of C in D?
the real names of my classes, to give you an idea of what i am trying to do
//A Observable
//B DynamicObservable
//C ObservableWithValidationErrors
//D DynamicObservableWithValidationErrors
There are some restrictions on the class you can use as mixin (See Mixins in Dart - Syntax and semantics).
However, in this proposal, a mixin may only be extracted from a class that obeys the following restrictions:
The class has no declared constructors.
The class’ superclass is Object.
The class contains no super calls.
Those restrictions may be removed in the future.
The semantics are deliberately restricted in several ways, so as to reduce disruption to our existing implementations, while allowing future evolution toward a full-fledged mixin implementation. This restricted version already provides considerable value.
In some circumstances it might be possible to restructure your class to use multiple mixins instead:
abstract class Observable{}
abstract class Dynamic{}
abstract class ValidationErrors{}
abstract class DynamicObservable extends Observable with Dynamic{}
abstract class ObservableWithValidationErrors extends Observable with ValidationErrors{}
abstract class DynamicObservableWithValidationErrors extends Observable with Dynamic, ValidationErrors{}
Of course, if Dynamic or ValidationErrors cannot be isolated this way, and rely on inheriting from Observable, this will not be possible.

What are some good workarounds for dart's lack of static typing semantics?

I'm coming from C#/F#/Haskell so I'm trying to come up with solutions to programming problems I'm used to solving with types.
class A where T : new() in C#, this is mainly so I can do new T() somewhere. This creates a malformed type error in Dart. Is there a reasonably idiomatic way to solve this? Perhaps with factories?
I did some experiments with mixins, in the case of name conflicts for inherited mixin members, the last mixin wins. So for the following:
abstract class mixA { void foo(); }
abstract class mixB { void foo(); }
class C extends Object with mixA, mixB {}
new C().foo();
this would end up calling mixB.foo() whereas
class C extends Object with mixB, mixA {}
would end up calling mixA.foo()
Is there anyway to access the members of the hidden mixins?
Suppose I mix 2 mixins with a field of the same name. Does the subclass instance have 2 fields at runtime (just 1 is inaccessible) or is the object like a dictionary and there is only 1 slot for each name?
1 is not possible. You can't call new on a generic type (or variable for that matter). The most common workaround is to create a closure that allocates the object instead.
The answers for 2 fall out of the fact that Mixins can be seen as super-classes: A extends Object with B, C is basically equivalent to:
class B' extends Object { <copy over code inside B> }
class C' extends B' { <copy over code inside C> }
class D extends C' { ... }
With this in mind:
no. there is no way to access hidden super elements.
yes. you would end up with multiple fields.
Small note: the <copy over code inside X> part is not completely correct since that would change the library-scope. Code from mixin B is conceptually in the library the mixin is declared in.

Resources