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