<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 19, 2017, at 4:58 PM, Daniel Duan via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 19, 2017, at 2:29 PM, Joe Groff &lt;<a href="mailto:jgroff@apple.com" class="">jgroff@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class=""><br class="Apple-interchange-newline">On Jan 19, 2017, at 1:47 PM, Douglas Gregor via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class="">This looks totally reasonable to me. A couple of comments:<br class=""><br class="">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.<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">I was about to bring up the same. Right now, an enum pattern works like .&lt;identifier&gt; &lt;tuple-pattern&gt;, where the &lt;tuple-pattern&gt; then recursively matches the payload tuple. In this model, it seems like we'd want to treat it more like .&lt;identifier&gt;(&lt;pattern&gt;, &lt;pattern&gt;, ...). 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.</span></div></blockquote><br class=""><div class="">I’m leaning towards “no” for simplicity of the language (and implementation). That means this would be source-breaking 😞. &nbsp;Will update the proposal and see how the rest of the feedback goes.</div></div></div></div></blockquote><div><br class=""></div><div>I lean towards “no” as well. &nbsp;I like the general direction of departing from treating associated values as tuples. &nbsp;This opens the door to some additional features related to associated values that have been discussed from time to time. &nbsp;</div><div><br class=""></div><div>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). &nbsp;When all cases define an associated value with the same name and type it really can be viewed very much like a property. &nbsp;In other cases, it is possible to view them as read-only, optional properties. &nbsp;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.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class=""> 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.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">-Joe</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">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<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>- Doug<br class=""><br class=""><blockquote type="cite" class="">On Jan 19, 2017, at 10:37 AM, Daniel Duan via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class="">Hi all,<br class=""><br class="">Here’s a short proposal for fixing an inconsistency in Swift’s enum. Please share you feedback :)<br class=""><br class="">(Updating/rendered version: <a href="https://github.com/dduan/swift-evolution/blob/compound-names-for-enum-cases/proposals/NNNN-Compound-Names-For-Enum-Cases.md" class="">https://github.com/dduan/swift-evolution/blob/compound-names-for-enum-cases/proposals/NNNN-Compound-Names-For-Enum-Cases.md</a>)<br class=""><br class=""><br class="">## Introduction<br class=""><br class="">Argument labels are part of its function's declaration name. An enum case<br class="">declares a function that can be used to construct enum values. For cases with<br class="">associated values, their labels should be part of the constructor name, similar<br class="">to "normal" function and methods. In Swift 3, however, this is not true. This<br class="">proposal aim to change that.<br class=""><br class="">## Motivation<br class=""><br class="">After SE-0111, Swift function's fully qualified name consists of its base name<br class="">and all argument labels. As a example, one can invoke a function with its<br class="">fully name:<br class=""><br class="">```swift<br class="">func f(x: Int, y: Int) {}<br class=""><br class="">f(x: y:)(0, 0) // Okay, this is equivalent to f(x: 0, y: 0)<br class="">```<br class=""><br class="">This, however, is not true when enum cases with associated value were<br class="">constructed:<br class=""><br class="">```swift<br class="">enum Foo {<br class="">&nbsp;&nbsp;&nbsp;case bar(x: Int, y: Int)<br class="">}<br class=""><br class="">Foo.bar(x: y:)(0, 0) // Does not compile as of Swift 3<br class="">```<br class=""><br class="">Here, the declared name for the case is `foo`; it has a tuple with two labeled<br class="">fields as its associated value. `x` and `y` aren't part of the case name. This<br class="">inconsistency may surprise some users.<br class=""><br class="">Using tuple to implement associated value also limits us from certain layout<br class="">optimizations as each payload need to be a tuple first, as opposed to simply be<br class="">unique to the enum.<br class=""><br class="">## Proposed solution<br class=""><br class="">Include labels in enum case's declaration name. In the last example, `bar`'s<br class="">full name would become `bar(x:y:)`, `x` and `y` will no longer be labels in a<br class="">tuple. The compiler may also stop using tuple to represent associated values.<br class=""><br class="">## Detailed design<br class=""><br class="">When labels are present in enum cases, they are now part of case's declared name<br class="">instead of being labels for fields in a tuple. In details, when constructing an<br class="">enum value with the case name, label names must either be supplied in the<br class="">argument list it self, or as part of the full name.<br class=""><br class="">```swift<br class="">Foo.bar(x: 0, y: 0) // Okay, the Swift 3 way.<br class="">Foo.bar(x: y:)(0, 0) // Equivalent to the previous line.<br class="">Foo.bar(x: y:)(x: 0, y: 0) // This would be an error, however.<br class="">```<br class=""><br class="">Note that since the labels aren't part of a tuple, they no longer participate in<br class="">type checking, similar to functions:<br class=""><br class="">```swift<br class="">let f = Foo.bar // f has type (Int, Int) -&gt; Foo<br class="">f(0, 0) // Okay!<br class="">f(x: 0, y: 0) // Won't compile.<br class="">```<br class=""><br class="">## Source compatibility<br class=""><br class="">Since type-checking rules on labeled tuple is stricter than that on function<br class="">argument labels, existing enum value construction by case name remain valid.<br class="">This change is source compatible with Swift 3.<br class=""><br class="">## Effect on ABI stability and resilience<br class=""><br class="">This change introduces compound names for enum cases, which affects their<br class="">declaration's name mangling.<br class=""><br class="">The compiler may also choose to change enum payload's representation from tuple.<br class="">This may open up more space for improving enum's memory layout.<br class=""><br class="">## Alternatives considered<br class=""><br class="">Keep current behaviors, which means we live with the inconsistency.<br class=""><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></blockquote><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></blockquote></div></blockquote></div><br class=""></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>