Allow "abstract" mixin application classes with missing parts in augmentations?
Thanks to @sgrekhov for bringing up this topic. This issue is similar to https://github.com/dart-lang/language/issues/4025 and https://github.com/dart-lang/language/issues/4008 in that it is concerned with incomplete declarations whose semantics can be well-defined because the missing elements are provided by augmentations.
In this issue it's about mixin application classes (the class declarations with an =):
class A {}
mixin M1 {}
mixin M2 {}
class B = A with M1;
augment class B1 = A with M2; // Allowed? Means `B1 = A with M1, M2`.
augment class B2 = with M2; // Allowed? Means `B2 = A with M1, M2`.
I'd recommend that we keep this in mind, but don't do anything at this time. It should not be a problem to add support for this kind of augmentation later on, and it will not be a breaking change.
@dart-lang/language-team, WDYT?
The syntax is annoying.
We could allow you to augment
class B = A with M;
as
augment class B with M2;
Here class B is a class with no declared body, one declared superclass and one declared mixin. The concrete syntax doesn't matter (but it's the only syntax that allows having no class body).
The augmentation is allowed to add further declared mixins and interfaces, and does that with the same syntax as for any other augmenting class declaration, but it can add no members and no class body, since B has no member scope to augment.
Yeah I think we should not do this at this time, but we could always allow it later and figure out the syntax at that point (although I much prefer something like the proposed alternate fwiw).
I think my proposal would be to remove the mixin application class syntax in an upcoming language versioned release (or the next major release), and then we don't have to worry about this at all.
If we drop this syntax then we might want to introduce some other way to request the implicit provision of a bunch of forwarding constructors:
abstract class A {
A.constructor1(); // This would be verbose: Lots of parameters and stuff.
A.constructor2(); // Ditto.
// ... lots more
void foo();
}
mixin M1 {
void foo() => print('One implementation of `foo`.');
}
mixin M2 {
void foo() => print('Another implementation of `foo`.');
}
class B1 = A with M1;
class B2 = A with M2;
Class B1 and B2 would be rather verbose if we didn't have this mechanism, and they would contain a lot of redundant elements that we can't otherwise abstract away.
we might want to introduce some other way to request the implicit provision of a bunch of forwarding constructors
I'm not opposed to that, but I honestly wouldn't lose sleep if we removed mixin application classes and didn't do this either. Mixin applications are very rare and the few I've seen don't have much in the way of constructors.
Closing, not planned.