-
Notifications
You must be signed in to change notification settings - Fork 214
[Class Modifiers] Should final classes from other libraries be usable as on
types?
#2933
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
I think we do achieve a small amount of additional expressive power if we can ensure that this kind of declaration is allowed. However, I tend to think that the simplicity achieved by making it an error may be more valuable. In particular, this means that we don't have any special exceptions for Let's see if we can come up with an example where we'd really want to do it, anyway: // --- Library 'lib.dart'.
final class FinalClass {}
@reopen base class Sub1 implements FinalClass {}
... // Lots of classes Sub2 ... SubN-1
@reopen base class SubN implements FinalClass {}
// --- Library 'other.dart'.
import "lib.dart" show FinalClass;
base mixin M on FinalClass { void foo() {} }
// Yes!!! We can add `foo` to any of those `Sub...` classes as we please!
base class MySubJ extends SubJ with M {} The desirable property of this set up would be that However, if we explicitly do not wish to provide any exhaustiveness guarantees based on a |
I realized last night that if we allow this, then it's still technically a breaking change to add a method to a |
Ouch, I think that alone is enough reason that we should disallow it. |
I don't think it's worth disallowing. If someone writes Disallowing that will prevent something that's potentially useful. The alternative is that you're making a mixin that you can't use for anything. I don't think you should worry about "breaking" useless code, it won't exist in code-bases that are worth caring about. And therefore I don't think we should consider it a problem to worry about. |
Why would you do this? Do we have any real examples? And specifically where declaring
I'm not convinced there is any real loss here. And conceptually at least, I think it's a win. When I write a |
We'd have the option to allow this in a later version if someone discovers a valid use case. I do think users who try writing this will be better served by an immediate error than by having to discover the limitations in other ways. |
The arguments here suggests that we intend a That's not true if it has non- Whether it's worth having a It's correct that having a (completely useless) (It is also true that having a But it's yet another non-orthogonal restriction, and I don't think it will ever solve a real problem. |
Decided: We disallow it for now. I actually came up with a good reason for disallowing. It makes a final type be completely opaque, which makes it possible to change it to, e.g., an inline class in a future change. (We should make sure that a |
I think we should close this issue now that we have a decision. |
Currently, I believe the specification allows the following:
Do we want to allow this?
It's more or less harmless (I think), in that the only way to use
M
is to apply it toFinalClass
or a subtype thereof. The former can only be done inside of the library that declaresFinalClass
. The latter could potentially be done outside of the library that declaresFinalClass
if the subtype re-opens the class.But it also feels surprising, and not especially useful. We've chosen to disallow this for
sealed
classes.cc @dart-lang/language-team
The text was updated successfully, but these errors were encountered: