-
Notifications
You must be signed in to change notification settings - Fork 209
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
class declaration shorthand syntax doesn't allow implementing simple interfaces #3120
Comments
A workaround is to make a temporary mixin mixin _A implements A {}
class C = B with _A; |
Well, that is more boilerplate than just doing the regular class declaration. Mostly I just filed this issue because it seems like a bit of an unnecessary restriction, there are certainly workarounds. |
Note that this primary constructor proposal includes the ability to use class C extends B implements A; The semantics is different (because |
Note that the more annoying part about this is actually that you end up having to duplicate any constructors. In my actual use case there is a single unnamed constructor with 5 parameters that I end up having to duplicate using the standard class pattern with Using the mixin trick does let me avoid that, but ultimately I own the interface and so I can just make it be a mixin, even though its really just an interface and it makes me cringe to do so. |
It depends. Since the class shorthand also copies constructors But overall I agree. Although I don't think that syntax is used a lot. |
Yeah, once I realized my actual use case was relying on the constructor also (probably the only reason I used this syntax to begin with), I switched to the mixin workaround. |
There is no "class declaration shorthand", the syntax is called "mixin application class declaration" which is why the It's not the declaration which copies constructors, every mixin application adds forwarding constructors, and that is why class S {
S.foo();
}
class C extends S with M {
C() : super.foo();
} works - the The problem with Or we can allow a class to not apply a mixin on top of its superclass, while still adding more interfaces. It's not inconceivable, but it may require changing the internal model of some tools. I'd prefer to not touch this now, and see if we can go with the primary-constructor |
Ah ok, the details of how it works makes sense why But I agree it doesn't need to be highly prioritized or anything. It just feels like an arbitrary restriction as a user of the feature, who thinks of this as just a "class declaration shorthand syntax". |
There is nothing fundamentally preventing us from just allowing For example, we could just say that Basically, it's the same as It can easily work. class C extends S with {
int foo() => 42;
} which then acts like a mixin application and inherits constructors, but cannot write any of its own. If we want to make that change, and are therefore making changes at all, I'd prefer to also change the So: class C extends S; // forwarding constructors.
class C extends S with M; // forwarding constructors.
class C extends S {} // No forwarding constructors, only default constructor `C(): super();`
// **Maybe**
class C extends S implements I with { int foo() => 42; } // forwarding constructors again. Then we can still explain that class S_M1 extends S with M1;
class S_M1_M2 extends S_M1 with M2;
class C extends S_M1_M2 { ... } where each declaration introduces a class, with a superclass and something added on top. |
@lrhn wrote: class C extends S; // forwarding constructors. That's a very interesting idea! But we might want to give ourselves as developers more power, say, covering the case where we want to obtain some forwarding constructors, but not all; or we want to get some/all forwarding constructors, but the class body is not empty (because we want to declare all kinds of other things). Sounds like a job for class A { A.one(); A.two(); }
class B extends A {
static export show A.one, A.two; // Ad-hoc syntax, but you get the idea.
... // Other declarations.
} We could then specify a particular default class B2 extends A {
static export show A.*; // Possible default for a class body specified as `;`.
} |
Consider the following example:
This gives the following errors for the class C:
The interface class
A
cannot be mixed in, so you are forced to instead use the full class syntax:This isn't the end of the world or anything, but it does also seem like the requirement for a
with
clause isn't actually necessary, and with class modifiers you can't use the workaround (with). You have to resort to the full class syntax.The text was updated successfully, but these errors were encountered: