I think that the main confusion here stems from the word library as we are 
addressing something that can be divided further (and this is IMHO as many 
macOS/iOS devs see it):

- libraries that come with the OS - here, it absolutely makes sense to make the 
enums non-exhaustive as the apps are linked against these libraries and the 
user installs a binary that will load these at launch and they are not bundled 
with the app - the developer can't control future OS releases and he wants the 
app to run on a future OS release.
- libraries that are bundled with the app - be it PM, CocoaPods or something 
else - you typically update your dependencies once in a while and they change. 
And you want to be notified by the compiler about possible changes - extended 
enums, in this case. Because let's be honest - if your app has a dozen 
dependencies and you come to the app after a year of no development, Swift 5 
came along during that period, you want to update these libraries to 
Swift-5-compatible versions. And no one has the time to go through all change 
logs - even if they were kept up-to-date and thorough, which I can't say that 
I've seen in many instances.

I know that this is a limited view from the perspective of an app developer and 
that potentially, e.g. on Linux, there may be libraries written in Swift that 
you may want to install via package managers and depend on them once the ABI is 
stable, but the choice to make them non-exhaustive by default is not in line 
with everything else in Swift - everything else is generally closed by default 
- public (-> final in other modules), no access modified (-> internal), ...

For me, it's a -1 as it is now. I'd prefer exhaustive-by-default, ObjC/C-import 
non-exhaustive by default (the way ObjC classes are open by default vs. 
public). When it comes to the switch statement, there definitely needs to be an 
option to make an exhaustive switch over all compile-time-known values with a 
warning shall a new one be added. Without that, the code will become incredibly 
prone to errors and hard to maintain.

> On Dec 20, 2017, at 9:35 PM, Karl Wagner via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
> 
>> On 20. Dec 2017, at 19:54, Jordan Rose <jordan_r...@apple.com 
>> <mailto:jordan_r...@apple.com>> wrote:
>> 
>> 
>> 
>>> On Dec 20, 2017, at 05:36, Karl Wagner via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>> 
>>>> On 19. Dec 2017, at 23:58, Ted Kremenek via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> The review of "SE 0192 - Non-Exhaustive Enums" begins now and runs through 
>>>> January 3, 2018.
>>>> 
>>>> The proposal is available here:
>>>> 
>>>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>>>>  
>>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md>+1,
>>>>  it needs to happen (and ASAP, since it _will_ introduce source-breaking 
>>>> changes one way or the other).
>>> 
>>> I think non-exhaustive is the correct default. However, does this not mean 
>>> that, by default, enums will be boxed because the receiver doesn’t know 
>>> their potential size?
>> 
>> It's not always boxing, but yes, there will be more indirection if the 
>> compiler can't see the contents of the enum. (More on that below.)
>> 
>> 
>>> That would mean that the best transition path for multi-module Apps would 
>>> be to make your enums @exhaustive, rather than adding “default” statements 
>>> (which is unfortunate, because I imagine when this change hits, the way 
>>> you’ll notice will be complaints about missing “default” statements).
>> 
>> Yep, that's going to be the recommendation. The current minimal-for-review 
>> implementation does not do this but I'd like to figure out how to improve 
>> that; at the very least it might be a sensible thing to do in the migrator.
>> 
>>> 
>>> I do have some thoughts about how we could ease the transition (for this 
>>> and other resilience-related changes), but it’s best to leave that to a 
>>> separate discussion.
>>> 
>>> The one thing I’m still not overly fond of is the name - I would like us to 
>>> keep the set of resilience/optimisation related keywords to a minimum. 
>>> “exhaustive” for enums feels an awful lot like “fixed_contents” for structs 
>>> - couldn’t we come up with a single name which could be used for both? I 
>>> don’t think anybody’s going to want to use “exhaustive” for structs.
>> 
>> The core team was very focused on this too, but I contend that "exhaustive" 
>> is not about optimization and really isn't even about "resilience" (i.e. the 
>> ability to evolve a library's API while preserving binary compatibility). 
>> It's a semantic feature of an enum, much like 'open' or 'final' is for 
>> classes, and it affects what a client can or can't do with an enum. For 
>> libaries compiled from source, it won't affect performance at all—the 
>> compiler still knows the full set of cases in the current version of the 
>> library even if the programmer is forced to consider future versions.
>> 
>> I'm working on the fixed-contents proposal now, though it won't be ready for 
>> a while, and the same thing applies there: for structs compiled from source, 
>> the compiler can still do all the same optimizations. It's only when the 
>> library has binary compatibility concerns that we need to use extra 
>> indirection, and then "fixed-contents" becomes important. (As currently 
>> designed, it doesn't affect what clients can do with the struct at all.) 
>> This means that I don't expect a "normal" package author to write 
>> "fixed-contents" at all (however it ends up being spelled), whereas 
>> "exhaustive" is a fairly normal thing to consider whenever you make an enum 
>> public.
>> 
>> I hope that convinces you that "fixed-contents" and "exhaustive" don't need 
>> to have the same name. I don't think anyone loves the particular name 
>> "exhaustive", but as you see in the "Alternatives considered" we didn't 
>> manage to come up with anything significantly better. If reviewers all 
>> prefer something else we'd consider changing it.
>> 
>> Thanks for responding!
>> Jordan
>> 
> 
> When you say “libraries compiled from source”, what do you mean?
> 
> As for whether its a resilience feature: actually it is completely a 
> resilience feature. The effects on switching are only side-effects; really 
> what “exhaustive” or “nonexhaustive” are saying is literally that cases may 
> be added later. Even if we added private cases, you wouldn’t need to mark 
> those enums as specially exhaustive or not; that would be implied. It’s an 
> accommodation for things which don’t exist yet, so really, it is all about 
> resilience IMO.
> 
> Anyway, as I see it, library authors in general ought to be happy about this:
> + Their libraries become safer by default, so they can make changes in the 
> future without having to worry about breakage
> + It doesn’t affect your code inside of a module, so it only affects types 
> they already explicitly marked “public”
> 
> The only people who lose are multi-module App developers, because they are 
> “library authors” who don’t need to care about evolution, and now need to add 
> attributes to things they wouldn’t have to before, or suffer language and 
> performance penalties. Their libraries become less reusable and not 
> resilient-by-default.
> 
> For example, I have an App for which I wrote a cross-platform model framework 
> in Swift. When I compile it as a framework inside my App, it is bundled there 
> forever. However, I use the same code to build libraries for Linux, which I 
> would like to ship in binary form to 3rd-parties. Am I supposed to litter my 
> code with annotations to mark those types as final, just to make the App fast 
> and convenient to code? What happens when I need to fix a bug and distribute 
> an updated copy, this means the 3rd-parties need to recompile (which they 
> won’t do…).
> 
> Typically, for such a problem, I would recommend using a static library 
> instead. But we don’t have those, and anyway they’re not always the best 
> thing these days. So that’s why I started a new thread about creating a 
> “@static” import, so App developers can go back to all the conveniences they 
> had before.
> 
> - Karl
> 
> 
> 
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to