<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>One thing I wanted to point out and that was a non trivial issue last year and that the core team did discuss and agreed to revisit (if I remember the thread update by Chris Lattner last year):</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature"><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;"></p><blockquote type="cite"><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;"><span style="background-color: rgba(255, 255, 255, 0);">Note that since the labels aren't part of a tuple, they no longer participate in type checking, behaving consistently with functions.</span></p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px;"><pre style="box-sizing: border-box; word-wrap: normal; margin-top: 0px; margin-bottom: 0px; padding: 16px; overflow: auto; line-height: 1.45; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal;"><font face="UICTFontTextStyleBody"><span style="white-space: normal; background-color: rgba(255, 255, 255, 0);"><span class="pl-k" style="box-sizing: border-box;">let</span> f <span class="pl-k" style="box-sizing: border-box;">=</span> Expr.<span class="pl-smi" style="box-sizing: border-box;">elet</span> <span class="pl-c" style="box-sizing: border-box;"><span class="pl-c" style="box-sizing: border-box;">//</span> f has type ([(String, Expr)], Expr) -&gt; Expr</span>
<span class="pl-c" style="box-sizing: border-box;"></span><span class="pl-c1" style="box-sizing: border-box;">f</span>([], anExpr) <span class="pl-c" style="box-sizing: border-box;"><span class="pl-c" style="box-sizing: border-box;">//</span> Okay!</span>
<span class="pl-c" style="box-sizing: border-box;"></span><span class="pl-c1" style="box-sizing: border-box;">f</span>(<span class="pl-c1" style="box-sizing: border-box;">locals</span>: [], <span class="pl-c1" style="box-sizing: border-box;">body</span>: anExpr) <span class="pl-c" style="box-sizing: border-box;"><span class="pl-c" style="box-sizing: border-box;">//</span> Won't compile.</span></span></font></pre></div></blockquote>I appreciate effort for consistency, but I hope this is not going to be used against the effort to bring labels in functions/stored closures/callbacks.</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">Swift, as we discussed last year, made a conscious, intentional effort to double down on the self documentation and call site readability of argument labels in general and the status quo after Swift 3/3.1 is not reflecting that whenever functions are stored in variables and/or passed to other functions as arguments.</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">I would like not to miss the Swift 4.0 deadline for this and we should discuss it sooner rather than later. I brought this up here because, for consistency, we are doubling down on something we should really be discussing to improve in my opinion.</div><div id="AppleMailSignature"><br></div><div id="AppleMailSignature">Sent from my iPhone</div><div><br>On 20 Apr 2017, at 21:39, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><div dir="ltr">On Thu, Apr 20, 2017 at 3:20 PM, John McCall via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word">Proposal Link:&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md" target="_blank">https://github.com/<wbr>apple/swift-evolution/blob/<wbr>master/proposals/0155-<wbr>normalize-enum-case-<wbr>representation.md</a><div><div><div><br></div><div>Hello Swift Community,</div><div><br></div><div>The review of SE-0155 "Normalize Enum Case Representation” ran from&nbsp;March 31st through April 10th, 2017. The proposal is&nbsp;<b>accepted with revisions</b>.</div><div><br></div><div>Feedback from the community was positive about most aspects of the proposal.&nbsp; However, there was substantial disagreement about the right direction for pattern matching.&nbsp; The core team discussed this issue in depth.</div><div><br></div><div>Pattern matching is central to the use of enum types.&nbsp; It's the only way you can use an enum value, besides general operations like passing it to a function or the special affordances for Optionals.&nbsp; Pattern matching is as central to enums as stored property access is to structs, and it's fair to be worried about anything that would make it substantially more onerous.&nbsp; Unconditionally requiring associated-value labels in case patterns would certainly do that, and several members of the core team expressed concern that it would be bad enough to discourage the use of associated-value labels completely — in effect, subverting the entire language feature being proposed.</div><div><br></div><div>It is true that including associated-value labels in case patterns does preserve a great deal of information in the source code:</div><div><br></div><div>&nbsp; - This information can usefully contribute to the clarity of the code following the pattern.</div><div><br></div><div>&nbsp; - Hiding this information can lead to bugs that would be self-evident if the case labels were always included.&nbsp; For example, if a case payload included a number of different boolean flags, it would be easy for a pattern to accidentally label them in the wrong order.</div><div><br></div><div>&nbsp; - Finally, this information may be necessary in order to determine which case is being matched, since the proposal adds the ability to distinguish cases purely by the labels on associated values.</div><div><br></div><div>However, the core team feels that there are counter-arguments which weaken the force of these considerations:</div><div><br></div><div>&nbsp; - While an associated-value label can indeed contribute to the readability of the pattern, the programmer can also choose a meaningful name to bind to the associated value.&nbsp; This binding name can convey at least as much information as a label would.</div><div><br></div><div>&nbsp; - The risk of mis-labelling an associated value grows as the number of associated values grows.&nbsp; However, very few cases carry a large number of associated values.&nbsp; As the amount of information which the case should carry grows, it becomes more and more interesting to encapsulate that information in its own struct — among other reasons, to avoid the need to revise every matching case-pattern in the program.&nbsp; Furthermore, when a case does carry a significant number of associated values, there is often a positional conventional between them that lowers the risk of re-ordering: for example, the conventional left-then-right ordering of a binary search tree.&nbsp; Therefore this risk is somewhat over-stated, and of course the programmer should remain free to include labels for cases where they feel the risk is significant.</div><div><br></div><div>&nbsp; - It is likely that cases will continue to be predominantly distinguished by their base name alone.&nbsp; Methods are often distinguished by argument labels because the base name identifies an entire class of operation with many possible variants.&nbsp; In contrast, each case of an enum is a kind of data, and its name is conventionally more like the name of a property than the name of a method, and thus likely to be unique among all the cases.&nbsp; Even when cases&nbsp;<i>are</i>&nbsp;distinguished using only associated value labels, it simply means that the corresponding case-patterns must include those labels; we should not feel required to force that burden on all other case-patterns purely to achieve consistency with this presumably-unusual style.</div><div><br></div><div>Accordingly, while it needs to be&nbsp;<b>possible</b>&nbsp;to include associated value labels in a case-pattern, and in some situations it may be&nbsp;<b>wise</b>&nbsp;to include them, the core team believes that requiring associated value labels would be unduly onerous.&nbsp; Therefore, the core teams revises the proposal as follows:</div><div><br></div><div>A case pattern may omit labels for the associated values of a case if there is only one case with the same base name and arity.&nbsp; A pattern must omit all labels if it omits any of them; thus, a case pattern either exactly matches the full name of a case or has no labels at all.&nbsp; For example:</div><div><br></div><div><font face="Menlo">&nbsp; enum E {</font></div><div><font face="Menlo">&nbsp; &nbsp; case often(first: Int, second: Int)</font></div><div><font face="Menlo">&nbsp; &nbsp; case lots(first: Int, second: Int)</font></div><div><font face="Menlo">&nbsp; &nbsp; case many(value: Int)</font></div><div><font face="Menlo">&nbsp; &nbsp; case many(first: Int, second: Int)</font></div><div><font face="Menlo">&nbsp; &nbsp; case many(alpha: Int, beta: Int)</font></div><div><font face="Menlo">&nbsp; &nbsp; case sometimes(value: Int)</font></div><div><font face="Menlo">&nbsp; &nbsp; case sometimes(Int)</font></div><div><font face="Menlo">&nbsp; }</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo">&nbsp; switch e {</font></div><div><font face="Menlo">&nbsp; // Valid: the sequence of labels exactly matches a case name.</font></div><div><font face="Menlo">&nbsp; case .often(first: let a, second: let b):</font></div><div><font face="Menlo">&nbsp; &nbsp; ...</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo">&nbsp; // Valid: there is only one case with this base name.</font></div><div><font face="Menlo">&nbsp; case .lots(let a, let b):</font></div><div><font face="Menlo">&nbsp; &nbsp; ...</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo">&nbsp; // Valid: there is only one case with this base name and payload count.</font></div><div><font face="Menlo">&nbsp; case .many(let a):</font></div><div><font face="Menlo">&nbsp; &nbsp; ...</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo">&nbsp; // Invalid: there are multiple cases with this base name and payload count.</font></div><div><font face="Menlo">&nbsp; case .many(let a, let b):</font></div><div><font face="Menlo">&nbsp; &nbsp; ...</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo">&nbsp; // Valid: the sequence of labels exactly matches a case name.</font></div><div><font face="Menlo">&nbsp; case .many(first: let a, second: let b):</font></div><div><font face="Menlo">&nbsp; &nbsp; ...</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo">&nbsp; // Invalid: includes a label, but not on all of the labelled arguments.</font></div><div><font face="Menlo">&nbsp; case .same(alpha: let a, let b):</font></div><div><font face="Menlo">&nbsp; &nbsp; ...</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo">&nbsp; // Valid: the sequence of labels exactly matches a case name (that happens to not provide any labels).</font></div><div><span style="font-family:menlo">&nbsp; case .sometimes(let x):</span></div><div><font face="Menlo">&nbsp; &nbsp; ...</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo">&nbsp; // Invalid: includes a label, but there is no matching case.</font></div><div><span style="font-family:menlo">&nbsp; case .sometimes(badlabel: let x):</span></div><div><font face="Menlo">&nbsp; &nbsp; ...</font></div><div><font face="Menlo">&nbsp; }</font></div><div><br></div><div>This only affects case patterns.&nbsp; Constructing a case always requires that any associated value labels in the case name be provided.</div><div><br></div><div>A case pattern must include patterns for all associated values of the case, even if the associated value has a default value.&nbsp; We may choose to relax this rule in a future release, or generally provide some sort of "..." syntax for indicating that there are associated values being ignored.</div></div></div></div></blockquote><div><br></div><div>I assume that the following is obvious and the core team's intention, but it bears confirmation and being documented:</div><div><br></div><div>```</div><div>enum F {</div><div>&nbsp; case many(first: Int, second: Int)</div><div>&nbsp; case many(Int, Int)</div><div>&nbsp; case withDefaultValue(Int, Int, Int=42)</div><div>&nbsp; case withDefaultValue(first: Int, second: Int, third: Int=42)</div><div>&nbsp; case withDefaultValue(first: Int, second: Int, notThirdToMakeAPoint: Int=43)</div><div>}<br></div><div><br></div><div>switch f {</div><div>// Valid, even though multiple cases have this base name and arity,</div><div>// because it is an exact match for a case that provides no labels.</div><div>case .many(let a, let b):</div><div>&nbsp; break</div><div><br></div><div>// Invalid, as case pattern must include even values with default.</div><div>case .withDefaultValue(let a, let b):</div><div>&nbsp; break</div><div><br></div><div>// Valid, as inclusion doesn't mean binding.</div><div>case .withDefaultValue(let a, let b, _):</div><div>&nbsp; break</div><div><br></div><div>// Valid, for the same reason as above.</div><div>case .withDefaultValue(first: let a, second: let b, third: _):</div><div>&nbsp; break</div><div><br></div><div>// Invalid, because the label is part of what's required, even if using `_`,</div><div>// since otherwise it could be ambiguous as to which case is being matched.</div><div>case .withDefaultValue(first: let a, second: let b, _):</div><div>&nbsp; break</div><div>}</div><div>```</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><div><div></div><div>The proposal includes a rule inferring labels in case patterns from binding names.&nbsp; The core team feels that imparting local variable names with this kind of significance would be unprecedented, surprising, and rather "pushy".&nbsp; The goal of this rule is also largely achieved by the new rule allowing labels to be omitted regardless of binding.&nbsp; Accordingly, this rule is struck from the proposal.&nbsp; That said, it would be a good idea for the implementation to warn when a binding name matches the label for a different associated value.</div><div><br></div><div>John McCall</div><div>Review Manager</div></div></div></div><br>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
<br></blockquote></div><br></div></div>
</div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>