> On Jan 24, 2017, at 3:51 PM, Christopher Kornher <[email protected]> wrote:
>
>>
>> On Jan 24, 2017, at 4:24 PM, Xiaodi Wu via swift-evolution
>> <[email protected] <mailto:[email protected]>> wrote:
>>
>> I'm now confused who is arguing for what. Enums cases cannot have the same
>> name. As far as I'm aware, this proposal does not seek to change that. Each
>> case must still be unique. It only changes whether labels are regarded as
>> part of the name or part of the associated type.
>
> Labels are currently neither part of the name nor part of the associated
> type. See my example (it runs in the playground in Xcode 8.2.1).
>
> Forgive any lack of precise terminology: Labels for enums with associated
> values are currently only used to create a "function signature" for
> constructing values for the enum. They are ignored in all other uses of the
> enum AFAIK.
Here’s how the labels can be used elsewhere in Swift 3, following your example:
switch theCurrentWay {
case .a(a: let x):
switch x {
case .anInt(value: let x):
break
case .aString(value: let x):
break
}
}
Note changing the label `a` or `value` before `:` to anything else results in
compile error.
>
> My proposal is a way to allow multiple cases with the same name without
> breaking existing code. It has the benefit of giving enums a richer meaning,
> in simple English:
>
> Here is an example of a way to handle this currently and what it would become:
>
> // Runs now
> enum MultipleTypes {
> case anInt( value: Int )
> case aString( value: String )
> }
>
> enum E {
> case a( a: MultipleTypes )
> }
>
> let theCurrentWay = E.a( a: .aString( value: "str") )
>
> switch theCurrentWay {
> case .a( let x ) :
> switch x {
> case .anInt( let x ) :
> break
>
> case .aString( let x ) :
> break
> }
> }
>
> // Proposed:
>
> /*
> enum theNewWay {
> case a( value: Int ) :
> case a( value: String ) :
> }
>
> switch theCurrentWay {
> case .a( let x: Int ) :
> break
>
> case .a( let x: String ) :
> break
> }
> */
>
>
>>
>>
>> On Tue, Jan 24, 2017 at 17:16 Christopher Kornher via swift-evolution
>> <[email protected] <mailto:[email protected]>> wrote:
>>> On Jan 24, 2017, at 4:02 PM, Daniel Duan <[email protected]
>>> <mailto:[email protected]>> wrote:
>>>
>>>
>>>
>>> Daniel Duan
>>> Sent from my iPhone
>>>
>>> On Jan 24, 2017, at 2:53 PM, Daniel Duan via swift-evolution
>>> <[email protected] <mailto:[email protected]>> wrote:
>>>
>>>>
>>>>
>>>> Daniel Duan
>>>> Sent from my iPhone
>>>>
>>>> On Jan 24, 2017, at 2:18 PM, Christopher Kornher via swift-evolution
>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>
>>>>> I agree that this rule would be consistent with the handing of Swift
>>>>> function signatures, but my proposal is self-consistent and:
>>>>>
>>>>> 1) It is more powerful, matching on the case name or not as required.
>>>>> 2) Is consistent with existing switches that ignore associated values
>>>>> 3) Is constant with ignored labels in other Swift constructs (proposed
>>>>> and in past versions of Swift, at least)
>>>>> 4) Avoids a possible API change for current enums. This is currently
>>>>> legal but would not be if the enum case “name” is the entire signature
>>>>> for constructing it:
>>>>>
>>>>> ```
>>>>> enum E {
>>>>> case a( a: Int )
>>>>> case b( a: Int )
>>>>> }
>>>>>
>>>>> let anEmum = E.a( a: 4 )
>>>>>
>>>>>
>>>>> switch anEmum {
>>>>> case .a( let x ) :
>>>>> break
>>>>> case .b( let x ) :
>>>>> break
>>>>> }
>>>>>
>>>>> switch anEmum {
>>>>> case .a( let y ) :
>>>>> break
>>>>>
>>>>> case .b( let y ) :
>>>>> break
>>>>> }
>>>>> ```
>>>>> So is this proposal worth creating a breaking change? I don’t think so.
>>>>> it would be possible to ignore the associated parameter name, but not the
>>>>> type, but that would further confuse case matching, I believe.
>>>>>
>>>>> I personally don’t see much purpose in having two enum cases with the
>>>>> same name if they are always treated as distinct and there is no way to
>>>>> reason on the case name.
>>>>
>>>> Would you say the same for functions? Our opinions differ in what
>>>> constitute a "name". In Swift, function names include parameters. Each
>>>> enum case declares a function that creates a enum value. That's why it's
>>>> *more* consistent for enum to have a similar definition of "name".
>>>>
>>>> As for pattern matching, number of patterns the number of cases being
>>>> matched have a many-to-one relationships. This is true in Swift and many
>>>>
>>>
>>> (Ah, accidentally sent it on my iPhone. My apologies.)
>>>
>>> … other languages. What you are proposing complicates the rules by making
>>> this untrue. We'd have to special-case this feature in our pattern matching
>>> algorithm.
>>
>> I am not proposing a breaking change. I believe that it is the best way to
>> handle “overloading” enum names without breaking existing code. I don’t
>> believe that this proposal changes any existing logic or rules.
>>
>> The use of the terms "name” and "signature" is well established in many
>> languages. e.g.: https://en.wikipedia.org/wiki/Type_signature
>> <https://en.wikipedia.org/wiki/Type_signature> I am trying to use the terms
>> in this context.
>>
>> Sharing a function name (with different signatures) is an aid to
>> understanding the purpose of functions and is part of many languages. I do
>> not believe that extending the concept to enums is worth the cost,
>> especially since it will break existing Swift code.
>>
>> You are proposing a source breaking change and I do not agree that is is an
>> improvement. What is the benefit of this change?
>>
>>
>>
>>>
>>>>> If they are always distinct, then requiring different names eliminates
>>>>> unnecessary cognitive load. There is a good reason for functions to have
>>>>> the same “name” and different signatures, and there are precedents in
>>>>> many languages.
>>>>>
>>>>> You may disagree, but I believe that enums exist to support reasoning on
>>>>> distinct cases and that muddying that by treating the associated value as
>>>>> part of the “signature" increases the language “surface area” while
>>>>> adding no tangible benefit.
>>>>>
>>>>>
>>>>>> On Jan 24, 2017, at 2:23 PM, Matthew Johnson via swift-evolution
>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>
>>>>>>>
>>>>>>> On Jan 24, 2017, at 3:10 PM, Christopher Kornher via swift-evolution
>>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>>
>>>>>>> Your example is only has only one case, which is not typical. Perhaps I
>>>>>>> am missing something, but the only reason that I can imagine for having
>>>>>>> a case with multiple ways to “construct” it is to have all variants of
>>>>>>> the case to match. If you don’t want them to match, use a different
>>>>>>> case name.
>>>>>>
>>>>>> It sounds like you are missing something. The `bar(a:)` and `bar(b:)`
>>>>>> are the full case names. These are *not* the same case. The `bar`
>>>>>> shorthand is allowed when there is no ambiguity, however for an enum
>>>>>> with both `bar(a:)` and `bar(b:)` there *is* ambiguity and therefore the
>>>>>> `bar` shorthand is not allowed. The programmer is required to spell out
>>>>>> the full name of the case they wish to match.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> It would still be possible to match on the different types of bar when
>>>>>>> needed:
>>>>>>>
>>>>>>> ```
>>>>>>> enum Foo {
>>>>>>> case bar(a: Int)
>>>>>>> case bar(b: String)
>>>>>>> case notAbar
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> switch aFoo {
>>>>>>> case .bar( let a: Int) : // matches Ints only
>>>>>>> ...
>>>>>>>
>>>>>>> case .bar( let b: String) : // matches Strings only
>>>>>>> ...
>>>>>>> }
>>>>>>>
>>>>>>> switch aFoo {
>>>>>>> case .bar : // Matches both cases and that is a good thing
>>>>>>> …
>>>>>>>
>>>>>>> case notAbar:
>>>>>>> ….
>>>>>>> }
>>>>>>>
>>>>>>> ```
>>>>>>>
>>>>>>>> On Jan 24, 2017, at 5:27 AM, Xiaodi Wu via swift-evolution
>>>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>>>
>>>>>>>> I would imagine it would be logical to have it work just like it does
>>>>>>>> now with functions. If case bar is distinct, then that should still
>>>>>>>> work, but if bar is "overloaded," then case bar should be invalid for
>>>>>>>> ambiguity. Seems fine to me, shouldn't break any existing code and
>>>>>>>> therefore we don't lose anything.
>>>>>>>>
>>>>>>>>
>>>>>>>> On Tue, Jan 24, 2017 at 01:13 David Hart via swift-evolution
>>>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 24 Jan 2017, at 00:52, Joe Groff via swift-evolution
>>>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>>>
>>>>>>>>> We're not terribly principled about this right now with non-pattern
>>>>>>>>> declaration references. You can still reference an unapplied function
>>>>>>>>> by its base name alone without its labels, if it's unambiguous:
>>>>>>>>>
>>>>>>>>> func foo(x: Int, y: Int) {}
>>>>>>>>>
>>>>>>>>> let foo_x_y: (Int, Int) -> () = foo
>>>>>>>>>
>>>>>>>>> so it'd be consistent to continue to allow the same in pattern
>>>>>>>>> references.
>>>>>>>>
>>>>>>>> WRT ambiguity, do we loose the ability to pattern match on the naked
>>>>>>>> case name when two cases share the same base name?
>>>>>>>>
>>>>>>>> enum Foo {
>>>>>>>> case bar(a: Int)
>>>>>>>> case bar(b: String)
>>>>>>>> }
>>>>>>>>
>>>>>>>> switch aFoo {
>>>>>>>> case .bar: // matches both cases
>>>>>>>> break
>>>>>>>> }
>>>>>>>> _______________________________________________
>>>>>>>> swift-evolution mailing list
>>>>>>>> [email protected] <mailto:[email protected]>
>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>> _______________________________________________
>>>>>>>> swift-evolution mailing list
>>>>>>>> [email protected] <mailto:[email protected]>
>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> swift-evolution mailing list
>>>>>>> [email protected] <mailto:[email protected]>
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>
>>>>>> _______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> [email protected] <mailto:[email protected]>
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> [email protected] <mailto:[email protected]>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> [email protected] <mailto:[email protected]>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>_______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution