[swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums

Howard Lovatt howard.lovatt at gmail.com
Wed Jan 3 07:12:08 CST 2018


Despite having suggested the @version syntax I do agree with people that have said any @annotation is both a burden on the programmer and severely reduces readability. 

Therefore a 4th option, carrying on from the numbering in my previous email is:

  4. The compiler issues a description of the public enums in a module. Application code that uses the enums knows what version of the enum they were compiled against. When the application launches the runtime writes a translation between the module enum and the application enum and vice versa. When an enum goes into or comes out of the application code to/from the module code it goes through the translation functions. EG:

    // Module version 1. 
    public enum E {
        case A, B, C
    }
    ...
    switch e {
    case A: a()
    default: d() // Could alternatively have cases B and C instead of default. 
    unknown case: u() // Must have unknown case for a public enum. 
    }

    // Application code compiled against module version 1. 
    // Stored in the code is the description of E having cases A, B, and C. 
    switch e {
    case A: a()
    default: d() // Could alternatively have cases B and C instead of default. 
    unknown case: u() // Must have unknown case for a public enum. 
    }

The translation functions in each direction are trivial since the two enums match and therefore have the same numbering and the same number range. 

Now the module is changed. 

    // Module version 2.
    public enum E {
        case A, C, D // B deleted and D added. 
    }
    ...
    // switch as before but now D calls d() and B calls u(). Previously B called d() but since B is deleted it is now an unknown case. 

The translation between module 2 code and application compiled against 1 code is:

  Module 2 <—> Application 1
  A               <—> A
  U               <—   B
  C               <—> C
  D                 —> U

IE all the old cases, from the application, are translated into unknown on the module side and all the new cases, from the module, are translated to unknown on the application side. 

This way neither the module programmer nor the application programmer has to version their code since the runtime provides the translation. 

It is source breaking however, since all switches of public enums require an unknown case both in the module code and application code. 

-- Howard. 

> On 3 Jan 2018, at 3:54 am, Jason Merchant via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Is it hard to imagine that most everyone can get what they want and keep the syntax clean and streamlined at the same time? Without any "@" signs or other compiler hints?
> 
>> "Rather, we are how to enable the vendor of a nonexhaustive enum to add new cases without breaking binaries compiled against previous versions"
> 
> When an enum changes, and the change causes the code to break, the user can be presented with migration options from an automated IDE tool. In what specific way does this not solve the issue about having to upgrade your code when using someone else's code library? This very notion implies your disgruntled about doing work when things are upgraded, is that really what this fuss is all about?
> 
> A well written language interpreter and auto-tooling IDE would not need hints embedded in the code syntax itself. Migration hints from version to version should not be a part of either the past or future version of the code library.
> 
> ...
> 
> I don't expect the community to agree on language grammar, but the common sense here on how to achieve the intended goals seems to be out of wack.
> 
> If someone can present a clear logical statement as to how an automated migration tool behind the scenes in the IDE to handle all your versioning worries, does not make this whole discussion about adding more convoluted syntax additions irrelevant, I'd love to hear it.
> 
> ___________________
> 
> Sincerely,
> Jason
> 
> 
> 
> 
> 
> 
>> On Tue, Jan 2, 2018 at 12:36 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>> On Tue, Jan 2, 2018 at 12:11 PM, Jason Merchant via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>>> I think this whole thing has been unnecessarily convoluted. As a result, the majority of the replies are rabbit holes.
>>> 
>>> In my opinion, the true root of the concept in question is as follows:
>>> 
>>> A list of something is desired:
>>> 1 - Pancake
>>> 2 - Waffle
>>> 3 - Juice
>>> 
>>> Developer wishes to be able to:
>>> A) Add new things to the list of choices in the future as they come up with new ideas
>>> B) Sometimes select one of the choices to be chosen as the normal choice if no choice is made by the user
>>> 
>>> A and B are separate desires. In some circumstances a developer may want to add a new choice and make it the normal choice when there was no normal choice was clarified before.
>> 
>> I don't think this is an accurate summary of the problem being tackled here. Rather, we are how to enable the vendor of a nonexhaustive enum to add new cases without breaking binaries compiled against previous versions. There is little here to do with what a "default" should be. Indeed, it is an explicit design decision of Swift not to support types having an implicit default value.
>>  
>>> ____________________
>>> 
>>> Part 2:
>>> 
>>> After this simple desire is clear, there should be two discussions:
>>> A) In a text only coding language, what would we like the syntax to look like? (Without regard to past-bias. What should it really be, forget what mistaken design choices were made in Swift in the past)
>>> B) How do we approach making this happen behind the scenes?
>>> 
>>> Bonus: Given that some of us have changed our approach to programming significantly beyond text based coding, and into more dynamic mediums of programming in other niches, and even here and there in Xcode - I would recommend considering how the IDE would show a modern version of this concept. I feel too often that Swift design syntax has a lack of awareness between the distinctions of what the IDE should do, as opposed to what the syntax of the language should be, and what should be handled behind the scenes by automated tooling.
>>> 
>>> _____________________
>>> 
>>> My opinion, in answering the above questions is in preference to a simple easy to read and write syntax, something like the following:
>>> 
>>> choices Breakfast {
>>>     Pancake, Waffle, Juice
>>> }
>>> 
>>> If a "default" choice is desired, it is obvious to me that I would select the choice from the IDE, and it would be visually indicated that it was the default.
>>> 
>>> When changes occur, whether new choices are added, old ones are removed or changed, or a default is added, changed, or removed - a behind the scenes automated tool analyzes the changes and presents migration options through the IDE.
>>> 
>>> _____________________
>>> 
>>> Sincerely,
>>> Jason
>>> 
>>>> 
>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> 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/20180103/65360b00/attachment.html>


More information about the swift-evolution mailing list