> On Jan 19, 2017, at 4:58 PM, Daniel Duan via swift-evolution 
> <[email protected]> wrote:
> 
> 
>> On Jan 19, 2017, at 2:29 PM, Joe Groff <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>>> 
>>> On Jan 19, 2017, at 1:47 PM, Douglas Gregor via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>> This looks totally reasonable to me. A couple of comments:
>>> 
>>> 1) Because this proposal is breaking the link between the associated value 
>>> of an enum case and tuple types, I think it should spell out the rules that 
>>> switch statements will use when matching an enum value against a a case 
>>> with an associated value. Some kind of rules fell out of them being treated 
>>> as tuple types, but they might not be what we want.
>> 
>> I was about to bring up the same. Right now, an enum pattern works like 
>> .<identifier> <tuple-pattern>, where the <tuple-pattern> then recursively 
>> matches the payload tuple. In this model, it seems like we'd want to treat 
>> it more like .<identifier>(<pattern>, <pattern>, ...). Similar to how we 
>> lost "tuple splatting" to forward a bunch of arguments, we'd have to decide 
>> whether we lose the ability to match all parts of the payload into a tuple.
> 
> I’m leaning towards “no” for simplicity of the language (and implementation). 
> That means this would be source-breaking 😞.  Will update the proposal and see 
> how the rest of the feedback goes.

I lean towards “no” as well.  I like the general direction of departing from 
treating associated values as tuples.  This opens the door to some additional 
features related to associated values that have been discussed from time to 
time.  

For example, one perennial topic seems to be a desire to treat associated 
values more like properties (there have been various different suggestions for 
how to do this).  When all cases define an associated value with the same name 
and type it really can be viewed very much like a property.  In other cases, it 
is possible to view them as read-only, optional properties.  I have encountered 
a number of cases where it has been useful to implement computed properties 
like this manually and could easily envision a language feature eventually 
eliminating the boilerplate.

> 
>> I also don't think we currently enforce matching argument labels, so you can 
>> match a `case foo(x: Int, y: Int)` with a `.foo(let q, let z)` or 
>> `.foo(apples: let x, bananas: let y)` pattern. We should probably tighten 
>> that up as part of this proposal as well.
>> 
>> -Joe
>> 
>>> 2) I wouldn’t blame you if you wanted to slip in default arguments for 
>>> associated values here, because this is really making enum cases with 
>>> associated values much more function-like
>>> 
>>>     - Doug
>>> 
>>>> On Jan 19, 2017, at 10:37 AM, Daniel Duan via swift-evolution 
>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>> 
>>>> Hi all,
>>>> 
>>>> Here’s a short proposal for fixing an inconsistency in Swift’s enum. 
>>>> Please share you feedback :)
>>>> 
>>>> (Updating/rendered version: 
>>>> https://github.com/dduan/swift-evolution/blob/compound-names-for-enum-cases/proposals/NNNN-Compound-Names-For-Enum-Cases.md
>>>>  
>>>> <https://github.com/dduan/swift-evolution/blob/compound-names-for-enum-cases/proposals/NNNN-Compound-Names-For-Enum-Cases.md>)
>>>> 
>>>> 
>>>> ## Introduction
>>>> 
>>>> Argument labels are part of its function's declaration name. An enum case
>>>> declares a function that can be used to construct enum values. For cases 
>>>> with
>>>> associated values, their labels should be part of the constructor name, 
>>>> similar
>>>> to "normal" function and methods. In Swift 3, however, this is not true. 
>>>> This
>>>> proposal aim to change that.
>>>> 
>>>> ## Motivation
>>>> 
>>>> After SE-0111, Swift function's fully qualified name consists of its base 
>>>> name
>>>> and all argument labels. As a example, one can invoke a function with its
>>>> fully name:
>>>> 
>>>> ```swift
>>>> func f(x: Int, y: Int) {}
>>>> 
>>>> f(x: y:)(0, 0) // Okay, this is equivalent to f(x: 0, y: 0)
>>>> ```
>>>> 
>>>> This, however, is not true when enum cases with associated value were
>>>> constructed:
>>>> 
>>>> ```swift
>>>> enum Foo {
>>>>    case bar(x: Int, y: Int)
>>>> }
>>>> 
>>>> Foo.bar(x: y:)(0, 0) // Does not compile as of Swift 3
>>>> ```
>>>> 
>>>> Here, the declared name for the case is `foo`; it has a tuple with two 
>>>> labeled
>>>> fields as its associated value. `x` and `y` aren't part of the case name. 
>>>> This
>>>> inconsistency may surprise some users.
>>>> 
>>>> Using tuple to implement associated value also limits us from certain 
>>>> layout
>>>> optimizations as each payload need to be a tuple first, as opposed to 
>>>> simply be
>>>> unique to the enum.
>>>> 
>>>> ## Proposed solution
>>>> 
>>>> Include labels in enum case's declaration name. In the last example, 
>>>> `bar`'s
>>>> full name would become `bar(x:y:)`, `x` and `y` will no longer be labels 
>>>> in a
>>>> tuple. The compiler may also stop using tuple to represent associated 
>>>> values.
>>>> 
>>>> ## Detailed design
>>>> 
>>>> When labels are present in enum cases, they are now part of case's 
>>>> declared name
>>>> instead of being labels for fields in a tuple. In details, when 
>>>> constructing an
>>>> enum value with the case name, label names must either be supplied in the
>>>> argument list it self, or as part of the full name.
>>>> 
>>>> ```swift
>>>> Foo.bar(x: 0, y: 0) // Okay, the Swift 3 way.
>>>> Foo.bar(x: y:)(0, 0) // Equivalent to the previous line.
>>>> Foo.bar(x: y:)(x: 0, y: 0) // This would be an error, however.
>>>> ```
>>>> 
>>>> Note that since the labels aren't part of a tuple, they no longer 
>>>> participate in
>>>> type checking, similar to functions:
>>>> 
>>>> ```swift
>>>> let f = Foo.bar // f has type (Int, Int) -> Foo
>>>> f(0, 0) // Okay!
>>>> f(x: 0, y: 0) // Won't compile.
>>>> ```
>>>> 
>>>> ## Source compatibility
>>>> 
>>>> Since type-checking rules on labeled tuple is stricter than that on 
>>>> function
>>>> argument labels, existing enum value construction by case name remain 
>>>> valid.
>>>> This change is source compatible with Swift 3.
>>>> 
>>>> ## Effect on ABI stability and resilience
>>>> 
>>>> This change introduces compound names for enum cases, which affects their
>>>> declaration's name mangling.
>>>> 
>>>> The compiler may also choose to change enum payload's representation from 
>>>> tuple.
>>>> This may open up more space for improving enum's memory layout.
>>>> 
>>>> ## Alternatives considered
>>>> 
>>>> Keep current behaviors, which means we live with the inconsistency.
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> [email protected] <mailto:[email protected]>
>>>> 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

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to