Yes, it’s binary compatiblity (ABI).
  

  
And yes, you’re right that inlineable code is especially fragile to changes 
made in later versions of the library.
  

  
See:   
https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst#inlineable-code
  
  
>   
> On Sep 23, 2017 at 2:50 am,  <Rex Fenley via swift-evolution 
> (mailto:swift-evolution@swift.org)>  wrote:
>   
>   
>   
>   
> > It’s really only an issue for people whose frameworks are used across 
> > variously-distributed apps (your own, or other peoples’). The typical 
> > dynamic library use-case. Those people already know to be careful, so why 
> > make non-exhaustive the default for everybody? It’s a fair point.
>   
>   
>   
> > Getting this right can be pretty hard. For example, I expect that 
> > @_inlineable functions within the enum’s declaring module will also be 
> > affected by this (a client could inline the code, then you add an enum 
> > case…). At the same time, it’s difficult for a shared library vendor to say 
> > definitively that a particular enum will never change (unless it really is 
> > a very simple thing, like NSComparisonResult) - almost anything with 
> > meaning to how the library works is usually subject to change in case 
> > edge-cases are discovered. The analysis of Apple’s frameworks is good data 
> > to prove it, but it also makes sense that vendors like to retain as much 
> > implementation freedom as possible.
>   
>
>   
> Just for clarity, this seems like the binary compatibility piece correct? As 
> far as I understand this could only affect a dynamically linked library, but 
> if you're linking a library dynamically, how could you inline a function, 
> since if it's dynamically linked you don't know what to inline?
>   
>
>   
> Also, I've never heard of these kinds of issues in other languages with 
> exhaustive pattern matching. Would be very interested to know how OCaml or 
> Haskell solve this problem?
>   
>
>   
> Thanks for your input
>   
>   
>   
>   
>
>   
> On Fri, Sep 22, 2017 at 8:20 AM, Karl Wagner  <razie...@gmail.com 
> (mailto:razie...@gmail.com)>  wrote:
>   
> >   
> >
> >   
> >   
> > >   
> > > On 21. Sep 2017, at 00:51, Rex Fenley via swift-evolution  
> > > <swift-evolution@swift.org (mailto:swift-evolution@swift.org)>  wrote:
> > >   
> > >   
> > >   
> > >   Hi Jordan,
> > >   
> > >  I've been keeping up with most of the discussion since I last emailed 
> > > about my concern about making nonexhaustive the default mode for enums. 
> > > So far I am still strongly in the camp of exhaustive by default.
> > >   
> > >  Most of my understanding comes from the perspective of source 
> > > compatibility; since I'm primarily an iOS app developer and contributor 
> > > to open source through CocoaPods, I don't have enough experience with 
> > > binary compatibility issues to understand the breadth of the effects of 
> > > such a change on binary compatibility - so I will argue from the 
> > > perspective of source compatibility. Additionally, all the following 
> > > applies exclusively to enums from Swift and not Obj-C/C. Largely my 
> > > concerns stem from the   "default effect 
> > > (https://en.m.wikipedia.org/wiki/Default_effect_(psychology))"- whatever 
> > > default is chosen is going to unconsciously bias developers to use that 
> > > default.
> > >   
> > >  To start, I don't follow how nonexhaustive by default leads to more 
> > > secure code or promises less. In a world where nonexhaustive is default, 
> > > hard-to-track bugs will be introduced frequently into many Swift 
> > > developer's code.   
> > >   
> > >   
> > > Evolving contracts - The change you suggest leaves it up to the user to 
> > > remember to add new cases into their code if an enum ever does change in 
> > > a framework, and their code relies on exhaustive pattern matching.   
> > >   
> > >   
> > >   
> > >   
> >   
> > I think this is the right thing to do. Library vendors can still 
> > communicate changes with clients through deprecation notices. Ultimately it 
> > is up to the vendor to maintain compatibility for people switching against 
> > those older cases, and up to the clients to adopt any new behaviour that 
> > gets implemented.
> >     
> >
> >   
> > >   
> > >   
> > >     
> > >   
> > > Unhandled case bugs - This will lead to inconsistencies and hard-to-track 
> > > bugs, since it would require the user to then track down an unhandled 
> > > case that they may not even be aware exists (forcing googling, searching 
> > > through documentation, etc.).
> > >   
> > >   This is something that I certainly have experienced in the past working 
> > > across teams programming in Obj-C, and Swift has so far completely 
> > > eliminated this class of bugs! In a world where exhaustive remains 
> > > default, nothing changes, fewer bugs.
> > >       
> >
> >   
> > I’m not sure that those issues are so difficult to track down. You’ll know 
> > that switch statements which fall-through to a default case are suspicious 
> > - but they already are today, too!. It’s not really any different to having 
> > allowing singular “if”s without a corresponding “else”. I could also see 
> > the debugging value in a “future” case label, but it’s not necessary IMO.
> >   
> >
> >   
> > Although, I can kind of see your point:
> >   
> >
> >   
> > If you’re talking about a private framework (e.g. the multi-module App 
> > scenario), then things are a little different for you because typically, 
> > you’ll ship new versions of the framework and App together. The framework 
> > can be as fragile as you like in that case - you can break all the ABI 
> > stability rules, because there will no apps importing the new version of 
> > the framework who were compiled against older versions of it. In many ways, 
> > those frameworks are really like static libraries (with extras, like 
> > resources).
> >   
> >
> >   
> > It’s really only an issue for people whose frameworks are used across 
> > variously-distributed apps (your own, or other peoples’). The typical 
> > dynamic library use-case. Those people already know to be careful, so why 
> > make non-exhaustive the default for everybody? It’s a fair point.
> >   
> >
> >   
> > Getting this right can be pretty hard. For example, I expect that 
> > @_inlineable functions within the enum’s declaring module will also be 
> > affected by this (a client could inline the code, then you add an enum 
> > case…). At the same time, it’s difficult for a shared library vendor to say 
> > definitively that a particular enum will never change (unless it really is 
> > a very simple thing, like NSComparisonResult) - almost anything with 
> > meaning to how the library works is usually subject to change in case 
> > edge-cases are discovered. The analysis of Apple’s frameworks is good data 
> > to prove it, but it also makes sense that vendors like to retain as much 
> > implementation freedom as possible.
> >   
> >
> >   
> > So I’m in favour of the change, but absolutely not in favour of the 
> > keywords. We need to standardise a minimal set of keywords which broadly 
> > cover the things library authors need to care about (versioning, 
> > sub-typing, inlining, etc). How is “exhaustive” different from “final” or 
> > “@_versioned”? How do they interact? I think we could come up with a more 
> > coherent message.
> >     
> >
> >   
> > - Karl
> >   
> >
> >   
> > >   
> > >   
> > >   
> > >   
> > >   
> > >  Next off is developer usability. As someone who has contributed to 
> > > several frameworks in Swift, one thing I know is that you can always 
> > > count on people complaining about the usability of their library - it's 
> > > something you learn to expect. If it turns out that people are very 
> > > frustrated with an enum constantly changing and breaking compatibility, 
> > > they will voice that concern with a thousand 👍 on github, debate will 
> > > happen, and the appropriate course correction will be made. In this case, 
> > > no real damage done.   
> > >   
> > >  That said, if enums are nonexhaustive by default, frameworks will have 
> > > more nonexhaustive enums (as it becomes convention). The class of bugs 
> > > previously discussed will emerge, causing real damage to users and 
> > > developers. Complaints will arise, but with more hostility. In this case, 
> > > we end up back where we started, since framework developers will then 
> > > mark exhaustive for all their enums. The only difference is that it'll be 
> > > something that must be remembered to be done.
> > >   
> > >  I can understand how someone developing an Apple framework may want 
> > > nonexhaustive by default, since enums from some Apple libraries seem to 
> > > be much larger and change relatively often. Yet, from my experience, this 
> > > doesn't represent what you find in open source libraries that seem to 
> > > land on something consistent and then stick with it. And that consistency 
> > > pairs very well with exhaustiveness.
> > >   
> > >  Given this, it's clear that adding a case to an enum as a source 
> > > breaking change should be the expected behavior. It's safer for those 
> > > using the frameworks, and back propagation from users will correct it if 
> > > it becomes an annoyance. Nonexhaustive as a keyword is a nice additional 
> > > tool to make this correction simpler (as well as protect C enums by 
> > > default), but should not be the standard.
> > >   
> > >  Best,
> > >   
> > > Rex
> > >   
> > >   
> > >   
> > >   
> > > On Fri, Sep 15, 2017 at 5:06 PM, Jordan Rose   <jordan_r...@apple.com 
> > > (mailto:jordan_r...@apple.com)>   wrote:
> > >   
> > > >   
> > > > Hi, Rex. I definitely agree that 'exhaustive' is the right model for a 
> > > > multi-module app; indeed, there's no real reason for a single project 
> > > > to do anything else. However, it is not always the right behavior for 
> > > > libraries that actually get distributed, whether as source or as 
> > > > binary. In this case we want to minimize the error of omission: in the 
> > > > app case, forgetting "exhaustive" is an annoyance that you notice and 
> > > > fix once across your code base, but in the library case forgetting the 
> > > > "default case" means putting out a source-breaking release, and for 
> > > > libraries that have binary compatibility constraints there's no 
> > > > recourse at all.  
> > > >
> > > >   
> > > > While most of the proposal deals with the experience we've had with the 
> > > > Apple SDKs (as written in Objective-C), we actually   have   run into 
> > > > this case in Swift already. The Swift Playgrounds app comes with a 
> > > > framework, PlaygroundSupport, that can be used from within a 
> > > > playground. It's important that when they upgrade the app, existing 
> > > > playgrounds don't break, since the end user may not have access to the 
> > > > entire code of the playground. (Remember that playgrounds are often 
> > > > authored by one developer or group, but then run and modified by 
> > > > someone else with a much lower skill level!)   That   means that 
> > > > PlaygroundSupport can't currently vend any enums that they expect 
> > > > playground authors to exhaustively switch over.
> > > >   
> > > >
> > > >   
> > > > (And to make it even more specific—and appealing—one of the enums they 
> > > > were considering would be a representation of the Swift AST. This can 
> > > > obviously change from release to release, but previous switch 
> > > > statements should stay valid.)
> > > >   
> > > >
> > > >   
> > > > Now, this is an example we know about, so we could certainly make it 
> > > > explicitly non-exhaustive. But in general we're in the same situation 
> > > > as 'open': if we want to be friendly to library authors, we need to 
> > > > make the default thing be the one that promises less, even if it means 
> > > > a bit of extra work in the "I-actually-own-everything" case.
> > > >   
> > > >
> > > >   
> > > > Best,
> > > >   
> > > > Jordan
> > > >   
> > > >   
> > > >   
> > > >   
> > > >
> > > >   
> > > >   
> > > >
> > > >   
> > > > >   
> > > > > On Sep 15, 2017, at 15:47, Rex Fenley  <r...@remind101.com 
> > > > > (mailto:r...@remind101.com)>  wrote:
> > > > >   
> > > > >   
> > > > >   
> > > > > Hey Jordan,  
> > > > >
> > > > >   
> > > > > Thank you for the time writing this up. I've been following along to 
> > > > > the discussion somewhat closely and have kept silent because 
> > > > > `exhaustive` was originally set to be the default for enums. However, 
> > > > > that changed and so I'd like to voice my opinion, I frankly don't 
> > > > > like this idea.
> > > > >   
> > > > >
> > > > >   
> > > > > At remind we use algebraic data types religiously for managing state 
> > > > > and data and rely on exhaustive pattern matching to guarantee we're 
> > > > > handling all states in our code. We're splitting out our code across 
> > > > > modules and having this guarantee has been a joy to work with.
> > > > >   
> > > > >
> > > > >   
> > > > > The benefit of making nonexhaustive the default for Swift 5 across 
> > > > > all multi-module code (besides C code) seems minimal to me. If a 
> > > > > developer feels like they're unnecessarily managing enum cases, they 
> > > > > can simply add a `default` case whenever they please. This is already 
> > > > > the case and I'm curious if there's every been any complaints about 
> > > > > this and what they would be. I'd prefer to be cautious and force 
> > > > > exhaustive pattern matching in all possible cases and leave it up to 
> > > > > the developer to choose not to.
> > > > >   
> > > > >
> > > > >   
> > > > > Ideally in my mind, these keywords won't be necessary. All Swift 
> > > > > enums will remain as they are, exhaustively pattern matched by 
> > > > > default. Enums from C code will be explicitly nonexhaustive in all 
> > > > > cases.
> > > > >   
> > > > >
> > > > >  --   
> > > > >   
> > > > >   
> > > > >   
> > > > >    Rex Fenley       |       IOS DEVELOPER
> > > > >   
> > > > >   
> > > > >     
> > > > >   
> > > > >    Remind.com (https://www.remind.com/)     |    BLOG 
> > > > > (http://blog.remind.com/)       |    FOLLOW US 
> > > > > (https://twitter.com/remindhq)       |       LIKE US 
> > > > > (https://www.facebook.com/remindhq)
> > > > >   
> > > > >   
> > > > >   
> > > > >   
> > > > >   
> > > > >   
> > > >   
> > > >   
> > > >               
> > >   
> > >   
> > >
> > >  --   
> > >   
> > >   
> > >   
> > >    Rex Fenley       |       IOS DEVELOPER
> > >   
> > >   
> > >     
> > >   
> > >    Remind.com (https://www.remind.com/)     |    BLOG 
> > > (http://blog.remind.com/)       |    FOLLOW US 
> > > (https://twitter.com/remindhq)       |       LIKE US 
> > > (https://www.facebook.com/remindhq)
> > >   
> > >   
> > >   
> > >   
> > >   
> > >   _______________________________________________
> > >    swift-evolution mailing list
> > >   swift-evolution@swift.org (mailto:swift-evolution@swift.org)
> > >   https://lists.swift.org/mailman/listinfo/swift-evolution       
> >       
>   
>   
>
>  --
>   
>   
>   
>
>    Rex Fenley       |       IOS DEVELOPER
>
>
>   
>   
>
>     
>
>   
>
>  Remind.com (https://www.remind.com/)     |    BLOG (http://blog.remind.com/) 
>       |    FOLLOW US (https://twitter.com/remindhq)       |       LIKE US 
> (https://www.facebook.com/remindhq)
>
>   
>   
>   
>  _______________________________________________ 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