"final"'s on my list of possible names! But it's not quite the same as 'final' for classes: "closed" only talks about what might change in the future, while 'final'-on-a-class also states something about the class in the present: it has no subclasses now as well as not gaining any new ones in the future. Still, it could be closed enough that it ends up being the best bet.
Jordan > On Aug 10, 2017, at 22:23, Rod Brown <rodney.bro...@icloud.com> wrote: > > Hi all, > > I thought I’d chime in with my own 2c… > > I’d probably prefer something more like “final” and vs non-final. It’s the > concept we’re dancing around - can you add something to extend it? > > In which case, final would allow exhaustive use, and non-final would require > handling the default case. Currently all Swift API would convert as “final”, > and all imported Obj-C API (with perhaps exceptions) would import as is and > require a default handling case. This negates the open vs public issue. But > it does also mean that it would become a manual issue inside the module to > mark the API as final to allow exhaustive switches, unless we say “exhaustive > switches allowed on internal/fileprivate/private types”. > > Unsure how this plays into the web of things, though… > > Thanks, > > Rod > > > >> On 11 Aug 2017, at 9:41 am, Jordan Rose via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> >> >>> On Aug 10, 2017, at 13:00, David Hart <da...@hartbit.com >>> <mailto:da...@hartbit.com>> wrote: >>> >>> >>> >>> On 10 Aug 2017, at 19:19, Jordan Rose <jordan_r...@apple.com >>> <mailto:jordan_r...@apple.com>> wrote: >>> >>>> >>>> >>>>> On Aug 9, 2017, at 22:46, David Hart <da...@hartbit.com >>>>> <mailto:da...@hartbit.com>> wrote: >>>>> >>>>> >>>>>> On 10 Aug 2017, at 02:42, Jordan Rose <jordan_r...@apple.com >>>>>> <mailto:jordan_r...@apple.com>> wrote: >>>>>> >>>>>> :-) As you've all noted, there are some conflicting concerns for the >>>>>> default: >>>>>> >>>>>> - Source compatibility: the existing behavior for an unannotated enum is >>>>>> "closed". >>>>>> - Intuition: if you show someone an enum without an explicit annotation, >>>>>> they'll probably expect they can switch over it. (I'm going to say this >>>>>> is why Zach calls it a "sensible default".) >>>>>> - Consistency: switches on an enum in the same module can always be >>>>>> exhaustive, so having it be different across modules is a bit annoying. >>>>>> (But 'public' already acts like this.) >>>>>> >>>>>> vs. >>>>>> >>>>>> - Library evolution: the default should promise less, so that you have >>>>>> the opportunity to change it. >>>>>> - Flexibility: you can emulate an exhaustive switch with a >>>>>> non-exhaustive switch using fatalError, but not the other way around. >>>>>> >>>>>> All of this is why I suggested it be an explicit annotation in either >>>>>> direction, but Matthew brought up the "keyword soup" problem—if you have >>>>>> to write (say) "public finite enum" and "public infinite enum", but >>>>>> would never write "private finite enum" or "private infinite enum", >>>>>> something is redundant here. Still, I'm uncomfortable with the default >>>>>> case being the one that constrains library authors, so at least for >>>>>> binary frameworks (those compiled "with resilience") I would want that >>>>>> to be explicit. That brings us to one more concern: how different should >>>>>> binary frameworks be from source frameworks? >>>>> >>>>> In terms of intuition and consistency, I think we should really try to >>>>> learn from the simplicity of public/open: >>>>> >>>>> * When internal, classes are sub-classable by default for convenience, >>>>> but can be closed with the final keyword >>>>> * When public, classes are closed to sub-classing for safety, but can be >>>>> opened up with the open keyword (which implies public). >>>>> >>>>> If we try to mirror this behaviour (the keywords are just suggestions, >>>>> not important): >>>>> >>>>> * When internal, enums are exhaustive by default for convenience, but can >>>>> be opened-up with the partial keyword >>>>> * When public, enums are non-exhaustive by default for safety, but can be >>>>> made exhaustive with the exhaustive keyword (which implies public). >>>> >>>> This is not a correct understanding of the internal/public distinction for >>>> classes, though. From inside a module, a public-but-not-open class is >>>> still subclassable, and similarly a public-but-not-"closed" enum will >>>> still be exhaustively switched. You don't have to worry about your own >>>> module changing out from under you. >>> >>> Correct. Thanks for the clarification! But you still agree with the >>> argument, right? Convenience for same module enums (exhaustive by default), >>> safety for clients of the module (not-exhaustive when public from outside >>> the module), with the option to be explicit? >> >> That's the "library evolution" criterion above, yes. But the behavior of >> enums inside the module doesn't need to affect what we do across modules. >> >>> And what do you think of the idea of having the « exhaustiveness » modifier >>> imply public, like open does? >> >> I'm a little less sure about that. It does help with the keyword soup >> problem, but it's also not as obviously about access as "open" was, and >> "open" can also appear where other access modifiers can appear (on methods, >> properties, and subscripts). >> >> Jordan >> >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution