-
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
Type capability modifiers #2242
Comments
I really, deeply like this proposal! The only I would change is:
I'd prefer something like
I have also read some documentation you've linked but I'm not sure I've understood the meaning of this keyword and the context, Could you please share an example? Thank you |
A With those promises, it's possible for a "type switch", as the one tha is part of the patterns language feature proposal, to know that a the switch is exhaustive. Say the int colorValue = switch (somePrimaryColor) {
case Red r => numberForRed(r);
case Blue b => numberForBlue(b);
case Green g => numberForGreen(g);
} and know that there doesn't need to be a If you later add a new direct subclass in the same module, you break this existing code. That's why it's also an implicit promise not to do that (unless you increase the major version number of your package). |
Yeah, I considered that, as we could use one of those. But I specifically chose a new keyword because those keywords mean something different in some other languages:
|
@munificent is there a reason that someone might want The idea of something being closed for extension outside of a library but extension being allowed internally seems interesting. It's similar to private members that are accessible within the library as well, I suppose. In that case, the same issue of Should there be a concept of imposing restrictions within a library itself? If so, perhaps that should be handled in a separate proposal, as it would also affect private members. |
Dart generally do not try to protect code against other code in the same library. Making something inaccessible or prohibited to the same library is so soft a boundary that it's almost non-existing, because whoever can write code to do the prohibited thing, can also remove the prohibition, or code around it. The only thing that can actually stop editors of the same library from doing things you don't want them to, is social contract, not the compiler. That's why it's not a goal to prevent you from breaking code in the same library. As for keywords - we'll need to new ones, and reusing old ones, to cover all the combinations here. Other languages use Other languages use |
I would add that Dart is very similar to Java and C#, want or don't like this , but it is a fact. So instead of adding new keywords it is always better to use existing ones.. like final / sealed. Still, I strongly believe that all public by default and so on helps Dart and we already have final as a keyword and _ prefix. So I would stick with this two... Finally base is just a bad name... you eighter use super or base keywords and to have both doing different things just creates a fuzz and mess. |
Yes, I think so. This is essentially what you get in other languages by exposing a public interface and a private "impl" class that implements it. It says: "You can implement this protocol yourself from scratch, or you can use this default implementation, but you can't reuse pieces of the code in the default implementation." That combination makes it easier to evolve the implementation of the class since you know there aren't any users subclassing it and overriding random methods in unexpected ways. Or, another use case is "You can mock this class for tests, but if you're using the real thing you have to use exactly this real thing."
I did consider that, but I think it's worth being able to vary the two concepts independently. I think each combination has meaningful use cases:
I admit that "base" isn't ideal. It's the best I've been able to come up with. |
switch class is very syntax-oriented - wouldn't it be better to describe it in terms of what it actually does? And this entire type capability modifiers suggestion -- isn't it sort-of superfluous if we'd have ADTs like in Haskell? |
Closing; this is available in the beta channel, and is scheduled for our next stable release. |
Documentation for this feature is now available at https://dart.dev/language/class-modifiers-for-apis |
EDITED: After quite a bit of discussion, a proposal based off of the description below (but with some different choices in syntax) has been accepted here.
Users have asked for the ability to prevent a class from being extended (#987) and/or implemented (#704). For exhaustiveness checks in pattern matching, we also need the ability to define a type with a known closed set of subtypes.
The Type Modifiers proposal addresses those. It's an alternative to the earlier Packaged Libraries proposal. The very brief summary is:
closed
on a class to disable extending it.base
on a class or mixin to disables its implicit interface.switch
modifier on a class or mixin to defines the root of a sealed type family for exhaustiveness checking. It also impliesabstract
.This issue is to discuss the proposal. Feel free to file other more specific issues too.
The text was updated successfully, but these errors were encountered: