> 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