[swift-evolution] Handling unknown cases in enums [RE: SE-0192]

John McCall rjmccall at apple.com
Fri Jan 12 21:43:26 CST 2018


> On Jan 12, 2018, at 6:47 PM, Dave DeLong via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I feel like we’re talking past each other right now, so I’ll give a concrete example:
> 
> Let’s say MyAwesomeFramework.framework defines this enum:
> 
> enum Access {
> 	case none
> 	case readOnly
> 	case readWrite
> }
> 
> This framework is compiled, built, and embedded in to MyAwesomeApp.app/Frameworks.
> 
> Somewhere in MyAwesomeApp, I switch on the access of a thing:
> 
> switch aThing.access {
> 	case .none: break
> 	case .readOnly: print(“I can read”)
> 	case .readWrite: print(“I can write”)
> }
> 
> Let’s here observe some things:
> 
> 1️⃣ the enum “Access” is *not* declared as frozen, because it might get a new case in the future (such as “writeOnly”)
> 2️⃣ the switch on an Access value is exhaustive
> 3️⃣ under the proposal, I’m going to get a warning on the switch because Access is not frozen. That warning will tell me to add “unknown case:”
> 
> This is the problem I’m talking about. The warning I’ll get on the switch is technically correct (I’m switching on a non-frozen enum), but semantically incorrect (it’s ok because the framework CANNOT introduce a new case without recompilation of the switch statement, because they are packaged together). The compiler will tell me to add an unknown case statement to the switch when it will be completely unnecessary. Since MyAwesomeFramework.framework is embedded in my app, there is no binary compatibility concern here, and I will never come across an unknown case.
> 
> I think this false positive is going to be very common, because lots of people embed frameworks in their apps, and those frameworks declare enums. Until the frameworks are updated to freeze the enums, the app authors will be forced to add “unknown case” statements to their switches for places where it is entirely unnecessary. (This brings up the question: does this proposal include a fixit to remove an “unknown case” statement from switches where it’s unnecessary?)
> 
> So, what I’m asking for is a part in the proposal (likely under “Future Directions”) where you acknowledge this problem (the “false positive problem for embedded modules”) and list it as something we’d like to solve in the future.

I agree that it's important to discuss this in the proposal.

I think the point that Jordan is trying to make is that this kind of resilience problem can come up as a source-compatibility issue, not just a binary-compatibility issue.  Of course an app can be version-locked to its non-OS dependencies and nobody will care.  However, it's problematic for a library to be version-locked to its dependencies even if both the library and its dependencies are only ever distributed as source: you ought to be able to upgrade the dependencies without having to revise all the dependent libraries.  If our library ecosystem doesn't let you pull a new version of BaseLib without simultaneously pulling new versions of everything else you use that requires BaseLib — or, alternatively, hand-fixing them all yourself if that library hasn't gotten updated yet — that's a pretty frustrating experience.

Conversely, an app ought to be able to be version-locked to its non-OS dependencies whether they're binaries or source.  So this really has almost nothing to do with binary vs. source distribution and everything to do with whether version-locking makes sense for a specific project.

John.

> 
> Dave
> 
>> On Jan 12, 2018, at 4:27 PM, Dave DeLong via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>>> On Jan 12, 2018, at 4:22 PM, Jordan Rose <jordan_rose at apple.com <mailto:jordan_rose at apple.com>> wrote:
>>> 
>>> No, it's "Revision-locked imports”.
>> 
>> Ah, yeah I can see how the rev-locked imports is a variation on “I’ve copied in this library”.
>> 
>>> A source-breaking change is one in which updating the library at compile time will break clients at compile time. That's relevant for libraries distributed with an app as well as for libraries that are part of the OS. You may not care, but I do, and I think other package authors will too.
>> 
>> ??? Of course I care about getting warnings when I’ve chosen to update a dependency. Where did I ever imply otherwise?
>> 
>> What I’m saying is that if I’m embedding such a library in my app *now* and I’m importing it *now*, I shouldn’t get a warning about handling unknown cases off non-frozen enums *now*. 
>> 
>> And if I am going to see such warnings now, then the document needs to include how those “false positives” will be eliminated in the future.
>> 
>> Dave
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20180112/43305577/attachment.html>


More information about the swift-evolution mailing list