I think this design does not avoid you writing something like `private enum Foo 
{ default ... }`, which is redudant as Jordan already pointed out in his 
previous post, nor does it have a consistent way of declaration:  

enum Foo {  
 case abc
 case def
 default
}

enum Foo {  
 case abc
 default
 case def
}


enum Foo {  
 default
 case abc
 case def
}

----  

On the other hand I'd be very much in favor of the design David has pitched, 
which makes `public` as a soft default for public API's and adds a stronger 
constraints with an extra keyword OR a different access modifier. In case of an 
access modifier it would be really interesting if someone knows other use cases 
where we could reuse `closed` for similar purposes.  

Long story short:  
- public is the soft default and all uses of an enum from module A in module B 
would require `default` in swithch statements
- closed is the stronger implied `public` which makes the enum finite and does 
not require `default` if you switch on all cases
--  
Adrian Zubarev
Sent with Airmail  

Am 10. August 2017 um 16:55:00, Matthew Johnson via swift-evolution 
(swift-evolution@swift.org(mailto:swift-evolution@swift.org)) schrieb:

>  
>  
> > On Aug 10, 2017, at 9:25 AM, Vladimir.S 
> > <sva...@gmail.com(mailto:sva...@gmail.com)> wrote:  
> > On 10.08.2017 16:46, Matthew Johnson via swift-evolution wrote:
> > > > On Aug 10, 2017, at 7:46 AM, James Froggatt via swift-evolution
> > > > <swift-evolution@swift.org(mailto:swift-evolution@swift.org)> wrote:
> > > > Since it seems to have been lost in the noise, I want to second with 
> > > > support for
> > > > Xiaodi's syntax of having `default` appearing in the enum declaration 
> > > > itself.
> > > > It's much clearer in its intention, feels very ‘Swifty’, and more 
> > > > importantly it
> > > > doesn't prompt whole threads debating the semantics of `open` vs 
> > > > `public`.
> > > I think Xiaodi’s syntax is very elegant if we want to avoid the access 
> > > control
> > > style syntax. However, it does one problem: the “error of omission” (not 
> > > thinking
> > > about open vs closed) leaves a library author with a closed enum, 
> > > preventing them
> > > from adding cases in the future without breaking compatibility. I’m not 
> > > sure this
> > > is acceptable.
> >  
> > Then, doesn't this mean that any 'usual' enum should be 'open' by default, 
> > and only enum declared with some marker (like 'final' or 'enum(sealed)') 
> > can be 'closed'?
> >  
> > Otherwise we need to require an explicit marker for *each* enum, and so 
> > break the source compatibility? (we'll have to append that marker to each 
> > enum in your current code)
>  
> This is a good point. A good first decision is whether we prioritize source 
> compatibility or the more conservative “default”. If source compatibility is 
> prioritized Xiaodi’s proposed syntax is probably hard to beat.  
> >  
> > Also I'd suggest this for closed enum:
> >  
> > enum MyClosedEnum {
> > case a
> > case b
> > case c
> > final
> > }
> >  
> > So, for public closed enum it will looks like:
> >  
> > public enum MyClosedEnum {
> > case a
> > case b
> > case c
> > final
> > }
> >  
> > Also, if we need to explicitly mark open enum, probably we can consider 
> > 'continue' keyword, as IMO is not clear what 'default' is saying on 
> > declaration site('you must insert `default` in switch'? 'there are other 
> > `default` cases'?) :
> >  
> > public enum MyOpenEnum {
> > case a
> > case b
> > case c
> > continue // to be continue...
> > }
> >  
> >  
> > > > ------------ Begin Message ------------ Group: 
> > > > gmane.comp.lang.swift.evolution MsgID: 
> > > > <CAGY80u=kVQA1q=5tmxxxfgm4tlgfuqh61en1daepemaa_fo...@mail.gmail.com(mailto:CAGY80u=kVQA1q=5tmxxxfgm4tlgfuqh61en1daepemaa_fo...@mail.gmail.com)>
> > > > On Tue, Aug 8, 2017 at 5:27 PM, Jordan Rose via swift-evolution < 
> > > > swift-evolution-m3fhrko0vlzytjvyw6y...@public.gmane.org(mailto:swift-evolution-m3fhrko0vlzytjvyw6y...@public.gmane.org)>
> > > >  wrote:
> > > > > Hi, everyone. Now that Swift 5 is starting up, I'd like to circle 
> > > > > back to an
> > > > > issue that's been around for a while: the source compatibility of 
> > > > > enums. Today, it's an error to switch over an enum without handling 
> > > > > all the cases, but this breaks down in a number of ways:
> > > > > - A C enum may have "private cases" that aren't defined inside the 
> > > > > original
> > > > > enum declaration, and there's no way to detect these in a switch 
> > > > > without
> > > > > dropping down to the rawValue. - For the same reason, the 
> > > > > compiler-synthesized
> > > > > 'init(rawValue:)' on an imported enum never produces 'nil', because 
> > > > > who knows
> > > > > how anyone's using C enums anyway? - Adding a new case to a *Swift* 
> > > > > enum in a
> > > > > library breaks any client code that was trying to switch over it.
> > > > > (This list might sound familiar, and that's because it's from a 
> > > > > message of mine on a thread started by Matthew Johnson back in 
> > > > > February called "[Pitch]
> > > > > consistent public access modifiers". Most of the rest of this email 
> > > > > is going
> > > > > to go the same way, because we still need to make progress here.)
> > > > > At the same time, we really like our exhaustive switches, especially 
> > > > > over enums we define ourselves. And there's a performance side to 
> > > > > this whole thing
> > > > > too; if all cases of an enum are known, it can be passed around much 
> > > > > more
> > > > > efficiently than if it might suddenly grow a new case containing a 
> > > > > struct with
> > > > > 5000 Strings in it.
> > > > > *Behavior*
> > > > > I think there's certain behavior that is probably not *terribly* 
> > > > > controversial:
> > > > > - When enums are imported from Apple frameworks, they should always 
> > > > > require a
> > > > > default case, except for a few exceptions like NSRectEdge. (It's 
> > > > > Apple's job
> > > > > to handle this and get it right, but if we get it wrong with an 
> > > > > imported enum
> > > > > there's still the workaround of dropping down to the raw value.) - 
> > > > > When I
> > > > > define Swift enums in the current framework, there's obviously no 
> > > > > compatibility issues; we should allow exhaustive switches.
> > > > > Everything else falls somewhere in the middle, both for enums defined 
> > > > > in Objective-C:
> > > > > - If I define an Objective-C enum in the current framework, should it 
> > > > > allow
> > > > > exhaustive switching, because there are no compatibility issues, or 
> > > > > not,
> > > > > because there could still be private cases defined in a .m file? - If 
> > > > > there's
> > > > > an Objective-C enum in *another* framework (that I built locally with 
> > > > > Xcode,
> > > > > Carthage, CocoaPods, SwiftPM, etc.), should it allow exhaustive 
> > > > > switching,
> > > > > because there are no *binary* compatibility issues, or not, because 
> > > > > there may
> > > > > be *source* compatibility issues? We'd really like adding a new enum 
> > > > > case to
> > > > > *not* be a breaking change even at the source level. - If there's an
> > > > > Objective-C enum coming in through a bridging header, should it allow
> > > > > exhaustive switching, because I might have defined it myself, or not, 
> > > > > because
> > > > > it might be non-modular content I've used the bridging header to 
> > > > > import?
> > > > > And in Swift:
> > > > > - If there's a Swift enum in another framework I built locally, 
> > > > > should it allow exhaustive switching, because there are no binary 
> > > > > compatibility issues,
> > > > > or not, because there may be source compatibility issues? Again, we'd 
> > > > > really
> > > > > like adding a new enum case to *not* be a breaking change even at the 
> > > > > source
> > > > > level.
> > > > > Let's now flip this to the other side of the equation. I've been 
> > > > > talking about
> > > > > us disallowing exhaustive switching, i.e. "if the enum might grow new 
> > > > > cases
> > > > > you must have a 'default' in a switch". In previous (in-person) 
> > > > > discussions
> > > > > about this feature, it's been pointed out that the code in an 
> > > > > otherwise-fully-covered switch is, by definition, unreachable, and 
> > > > > therefore
> > > > > untestable. This also isn't a desirable situation to be in, but it's 
> > > > > mitigated
> > > > > somewhat by the fact that there probably aren't many framework enums 
> > > > > you
> > > > > should exhaustively switch over anyway. (Think about Apple's 
> > > > > frameworks
> > > > > again.) I don't have a great answer, though.
> > > > > For people who like exhaustive switches, we thought about adding a 
> > > > > new kind of
> > > > > 'default'—let's call it 'unknownCase' just to be able to talk about 
> > > > > it. This
> > > > > lets you get warnings when you update to a new SDK, but is even more 
> > > > > likely to
> > > > > be untested code. We didn't think this was worth the complexity.
> > > > > *Terminology*
> > > > > The "Library Evolution 
> > > > > <http://jrose-apple.github.io/swift-library-evolution/>" doc (mostly 
> > > > > written
> > > > > by me) originally called these "open" and "closed" enums ("requires a 
> > > > > default"
> > > > > and "allows exhaustive switching", respectively), but this predated 
> > > > > the use of
> > > > > 'open' to describe classes and class members. Matthew's original 
> > > > > thread did
> > > > > suggest using 'open' for enums as well, but I argued against that, 
> > > > > for a few
> > > > > reasons:
> > > > > - For classes, "open" and "non-open" restrict what the *client* can 
> > > > > do. For
> > > > > enums, it's more about providing the client with additional 
> > > > > guarantees—and
> > > > > "non-open" is the one with more guarantees. - The "safe" default is 
> > > > > backwards:
> > > > > a merely-public class can be made 'open', while an 'open' class 
> > > > > cannot be made
> > > > > non-open. Conversely, an "open" enum can be made "closed" (making 
> > > > > default
> > > > > cases unnecessary), but a "closed" enum cannot be made "open".
> > > > > That said, Clang now has an 'enum_extensibility' attribute that does 
> > > > > take 'open' or 'closed' as an argument.
> > > > > On Matthew's thread, a few other possible names came up, though 
> > > > > mostly only
> > > > > for the "closed" case:
> > > > > - 'final': has the right meaning abstractly, but again it behaves 
> > > > > differently
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to