-
Notifications
You must be signed in to change notification settings - Fork 205
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
Can we temporarily remove "cannot extend mixins" limitation? #32
Comments
Personally I have no objection to being able to use "with" with a true class. I would not want a lint that discourages such use. |
Yeah, I should have mentioned that @Hixie and I do not agree on everything mixin-related (e.g. I disagree with #32 (comment)). However, we both agree that the restriction on Update: added "do not" in a critical place of the previous paragraph! 😄 |
I think the language is/was relaxing class Foo with Bar {} ... negating the need to use |
@matanlurey this is mentioned as a future possible feature, but that's not what's launching in Dart 2.1. The second trouble with |
🤕
It seems reasonable that, for Dart To be honest though, are there concrete reasons to prevent (I don't know if the new |
FYI, I filed #33 to discuss whether the |
In this issue I suggest that |
I do believe |
Let's be specific. mixin M {}
class B {}
class C1 extends M {}
class C2 with M {}
class C3 extends B {}
class C4 with B {} Here the line Should we also allow: mixin M2 {}
class C5 extends M with M2 {}
class C6 extends M, M2 {} ? The former would mean that we are not just reinterpreting So, yes, we can definitely allow |
@lrhn I agree that, ignoring existing Dart code for a moment, We could have an analyzer hint suggesting that users replace Because this is mostly for migration (I agree that
|
This comment and surrounding discussion had led me to think your desire was to migrate all mixins to the new syntax. If this is not the case, we should just change the lint to match up what you want. My main goal is to get the super mixins migrated over. |
@lrhn can you elaborate on why? Maybe it's just late, but I'm not sure I'm seeing how you can observe the difference in the non-super-mixin case. |
My take on this:
|
Yeah, looks like I was wrong in my comment last August, there are classes that make sense to use as both a superclass and a mixin. My bad. I don't see much value in being able to extend a |
@Hixie what properties of the |
One value is that we can change non-supermixin-classes-meant-to-be-mixins to the Making everything that's meant to be a mixin use the
A simpler approach is:
|
Update: updated the description of the issue to reflect the discussion. |
The word " I don't think " The actual alternatives as I see them are: Either:
or:
|
Purely being literal here. If we interpret The rule would be to rewrite |
My main worry about introducing a temporary permission to extend a mixin is that I don't see a good way to pick a duration for it, or a simple way to phase it out again. It's a feature that we don't actually want. Adding it temporarily is extra work, so that work had better pay off, but not so well that we get stuck with the feature. So, we want to incorporate an inconvenient feature. If we allow extending mixins, we will immediately make it cause a warning to do so. The warning will be a "deprecation" warning, so people are encouraged to migrate their code. That still doesn't tell us when the deprecation/migration period ends. The "correct" choice would likely be Dart 3.0 - it is a breaking change to remove the feature. We don't have a schedule for reaching 3.0. It's just a number, we can pick it as a version number any time we feel like we have a big enough change (I'd probably use it for non-null by default, if we get that feature). Another option is to make it a "migration only" feature, and remove it after a fixed period, say six months. We can "encourage" migration by making it increasingly more inconvenient to use the feature. The issue here is that the person building is not necessarily the person who needs to migrate the offending package. It would put indirect some pressure on package writers to update their code (from |
@Hixie thanks for the details. So, there's no loss in technical generality from moving from @lrhn I think Dart 3.0 timeline would work for the temporary My own position is still that we should convert all mixins to the At the end of the day, this is the language team's call. Please let us know how to proceed. The only issue I'm currently struggling with is that I'm technically prevented from converting non-supermixins to the new |
I understand the pain, and I'd personally love to see classes used as
mixins go the way of the dodo.
However, we are not in a position to make such a change at this time. The
features for Dart 2.1 are being finalized, and we don't have the time and
available man-power to make a change at this point, even one as small as
this (and things are never as small as they seem).
For now, if you want to have something that can both be extended and mixed
in, it will have to stay as a class.
/L
…On Tue, Oct 2, 2018 at 8:18 PM Yegor ***@***.***> wrote:
@Hixie <https://github.com/Hixie> thanks for the details. So, there's no
loss in technical generality from moving from class to mixin that we're
worried about. You prefer class as a matter of personal preference, which
is fine and should be taken into account by the language team.
@lrhn <https://github.com/lrhn> I think Dart 3.0 timeline would work for
the temporary extends M1 with M2 => with M1, M2 rewrite + prefer_mixin
lint. It will give a long enough period both for stability and migration. I
believe the prefer_mixin lint is sufficient for steering the ecosystem
towards the desired outcome. Perhaps by Dart 2.2, if we observe that
old-style mixins are rarely used in poorly maintained packages (e.g. using
pub's scoring system), the warning can be elevated from a lint to a
compiler warning to accelerate the process.
My own position is still that we should convert all mixins to the mixin
syntax. As a personal preference, I think it gives developers a much
simpler framework (you don't have to explain to anyone that a class may
also be a mixin in certain situations). As a technical reason, I like a lot
the idea that the compiler can use the mixin keyword to enforce mixin
invariants, making sure mixin authors do not break users accidentally. This
is not possible with classes.
At the end of the day, this is the language team's call. Please let us
know how to proceed. The only issue I'm currently struggling with is that
I'm *technically* prevented from converting *non-supermixins* to the new
mixin syntax because it breaks the usages of extends, and therefore I'm
asking for a softer transition strategy.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#32 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AEo9B3DjZ0EuVins5wiriyHaKADgci43ks5ug64NgaJpZM4W9p2i>
.
--
Lasse R.H. Nielsen - lrn@google.com
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K
- Denmark - CVR nr. 28 86 69 84
|
Leaving them as classes then. I'll instead file an issue for |
(branched off #31 (comment))
Goal
Migrate all mixins (not only super-mixins) to the new
mixin
syntax.Background
Classes that were meant to be super-mixins already had restrictions matching those of the new
mixin
keyword. This makes the migration fromclass
tomixin
for super-mixins simple. That's not the case for non-super-mixins. Those classes are extended, implemented, and mixed in in the wild. Therefore changing what previously was declared as aclass
to amixin
breaks classes that usedextends
instead ofwith
.Proposal: temporarily allow extending mixins
extends
andwith
have no semantic differences observable by the developermixin
semanticsBeyond that, this allows us to remove the ability to derive a mixin as a non-breaking change. To do that we will have to overload what
extends
means.Imagine this declaration:
The compiler first checks whether
Bar
is amixin
or aclass
.If
Bar
is amixin
, then the compiler desugars the above declaration into:More generally,
class Foo extends M1 with M2, ..., Mk
desugars intoclass Foo extends Object with M1, M2, ..., Mk
.If
Bar
is aclass
, then it's a normal derivation. The lintprefer_mixin
then can be used to help authors find classes used as mixins and convert them tomixin
syntax without breaking their users.This approach will allow converting the vast majority of mixins present in the Dart ecosystem to the new
mixin
syntax without breaking existing user code. For example, Flutter can updateabstract class WidgetsBindingObserver
tomixin WidgetsBindingObserver
as a non-breaking change.Changing from
class
tomixin
still comes withmixin
restrictions, just like new mixin proposal wants, such as:These properties will protect mixin authors from accidentally breaking their users.
Discussions elsewhere
This topic was discussed on these other threads:
mixin
for non-supermixins a good idea? #33Updates
A extends M
is simpler syntactically due to existence ofA with M
@leafpetersen @lrhn @eernstg @Hixie
The text was updated successfully, but these errors were encountered: