Re: [swift-evolution] The Non-Exhaustive Enums proposal kills one of Swift's top features - change proposal

2017-12-23 Thread Thomas Roughton via swift-evolution
Hi Slava,

I think we may be referring to different things. For whatever it’s worth, I 
agree with your reasoning on all the points you brought up. I also don’t think 
having a 'default: fatalError()’ case is a good idea because then a library 
change can cause crashes in a running version of an application.

What I mean by some sort of ‘complete switch’ statement is that it would be 
compiled as per a normal ‘switch’ but error at compile time if it’s not 
complete against the known set of cases as compile time. Assuming an enum with 
known cases [a, b] at compile time,

switch nonExhaustiveEnum {
case a:
print(“a”)
case b:
print(“b”)
default:
break
}

would be exactly equivalent to:

complete switch nonExhaustiveEnum {
case a:
print(“a”)
case b:
print(“b”)
unknown:  // the ‘unknown’ case would only be required for 
non-exhaustive enums
break
}

where the keywords ‘complete’ and ‘unknown’ are up for debate. If, however, the 
programmer wrote:

complete switch nonExhaustiveEnum {
case a:
print(“a”)
unknown:
break
}

the compiler would give an error that there are unhandled cases in the switch 
statement, whereas

switch nonExhaustiveEnum {
case a:
print(“a”)
default:
break
}

would compile without issue. If a user didn’t know about the existence of the 
‘complete switch’ construct, they could just use normal ‘switch’ statements and 
miss out on the completeness checking.

Thomas

> On 24/12/2017, at 1:15 PM, Slava Pestov  wrote:
> 
> 
> 
>> On Dec 23, 2017, at 3:47 PM, Thomas Roughton via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> On 24/12/2017, at 9:40 AM, Cheyo Jimenez via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> What are your thoughts on `final switch` as a way to treat any enum as 
>>> exhaustible?
>>> https://dlang.org/spec/statement.html#FinalSwitchStatement 
>>> <https://dlang.org/spec/statement.html#FinalSwitchStatement>___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> I’d be very much in favour of this (qualms about the naming of the ‘final’ 
>> keyword aside - ‘complete’ or ‘exhaustive’ reads better to me). 
>> 
>> Looking back at the proposal, I noticed that something similar was mentioned 
>> that I earlier missed. In the proposal, it says:
>> 
>>> However, this results in some of your code being impossible to test, since 
>>> you can't write a test that passes an unknown value to this switch.
>> 
>> Is that strictly true? Would it be theoretically possible for the compiler 
>> to emit or make accessible a special ‘test’ case for non-exhaustive enums 
>> that can only be used in test modules or e.g. by a 
>> ‘EnumName(testCaseNamed:)’, constructor? There is  potential for abuse there 
>> but it would address that particular issue. 
>> 
>> Regardless, I still feel something like a ‘final switch’ is necessary if 
>> this proposal is introduced, and that it fits with the ‘progressive 
>> disclosure’ notion; once you learn this keyword you have a means to check 
>> for completeness, but people unaware of it could just use a ‘default’ case 
>> as per usual and not be concerned with exhaustiveness checking. 
> 
> My general philosophy with syntax sugar is that it should do more than just 
> remove a constant number of tokens. Basically you’re saying that
> 
> final switch x {}
> 
> just expands to
> 
> swift x {
> default: fatalError()
> }
> 
> I don’t think a language construct like this carries its weight.
> 
> For example, generics have a multiplicative effect on code size — they 
> prevent you from having to write an arbitrary number of versions of the same 
> algorithm for different concrete types.
> 
> Another example is optionals — while optionals don’t necessarily make code 
> shorter, they make it more understandable, and having optionals in the 
> language rules out entire classes of errors at compile time.
> 
> On the other hand, a language feature that just reduces the number of tokens 
> without any second-order effects makes code harder to read, the language 
> harder to learn, and the compiler buggier and harder to maintain without much 
> benefit. So I think for the long term health of the language we should avoid 
> ‘shortcuts’ like this.
> 
> Slava

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


Re: [swift-evolution] The Non-Exhaustive Enums proposal kills one of Swift's top features - change proposal

2017-12-23 Thread Thomas Roughton via swift-evolution

> On 24/12/2017, at 9:40 AM, Cheyo Jimenez via swift-evolution 
>  wrote:
> 
> What are your thoughts on `final switch` as a way to treat any enum as 
> exhaustible?
> https://dlang.org/spec/statement.html#FinalSwitchStatement
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution


I’d be very much in favour of this (qualms about the naming of the ‘final’ 
keyword aside - ‘complete’ or ‘exhaustive’ reads better to me). 

Looking back at the proposal, I noticed that something similar was mentioned 
that I earlier missed. In the proposal, it says:

> However, this results in some of your code being impossible to test, since 
> you can't write a test that passes an unknown value to this switch.

Is that strictly true? Would it be theoretically possible for the compiler to 
emit or make accessible a special ‘test’ case for non-exhaustive enums that can 
only be used in test modules or e.g. by a ‘EnumName(testCaseNamed:)’, 
constructor? There is  potential for abuse there but it would address that 
particular issue. 

Regardless, I still feel something like a ‘final switch’ is necessary if this 
proposal is introduced, and that it fits with the ‘progressive disclosure’ 
notion; once you learn this keyword you have a means to check for completeness, 
but people unaware of it could just use a ‘default’ case as per usual and not 
be concerned with exhaustiveness checking. 

Thomas

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


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

2017-12-23 Thread Thomas Roughton via swift-evolution
Looking at the feedback to this proposal, it looks like a common thread is 
people wanting to make sure they’re notified when new cases are introduced (the 
‘future’ keyword’). However, if I’m understanding correctly, the resistance to 
adding such a keyword is that it becomes complicated when there’s e.g. both a 
‘future’ and ‘default’ case, with two different sets of behaviour. I missed the 
earlier discussion around this proposal so forgive me if this is a concept 
that’s been brought up before.

A possible alternative would be to build on that concept, but place the weight 
on the ‘switch’ statement. I’d propose something like the following for a 
non-exhaustive enum that currently has cases ‘a’ and ‘b’.

@complete switch nonExhaustiveEnum {
case a:
print(“a”)
case b:
print(“b”)
future:
break
}

where the semantics would be that in a @complete switch statement, all known 
cases must be explicitly switched. The ‘future’ case would have the same 
run-time semantics as a default case for a non-@complete switch (I’m sticking 
with the ‘future’ name here since I think it’s clearer, but continuing to use 
‘default’ would also work). If the external library is modified and the user 
code is then recompiled, Swift would error at compile time saying that there 
were unhandled cases.

Obviously, this still requires adding keywords to the language and some degree 
of complexity, but does mean the behaviour change is isolated to a fairly 
simple compile-time check.

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