> On Jan 19, 2017, at 2:29 PM, Joe Groff <jgr...@apple.com> wrote:
> 
>> 
>> On Jan 19, 2017, at 1:47 PM, Douglas Gregor via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> 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 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 
>>> <swift-evolution@swift.org> 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)
>>> 
>>> 
>>> ## 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
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> _______________________________________________
>> 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>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to