<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 Apr 20, 2017, at 5:50 PM, Goffredo Marocchi &lt;<a href="mailto:panajev@gmail.com" class="">panajev@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class="">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 class=""><br class=""></div><div class=""><div style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;" class=""><br class="webkit-block-placeholder"></div><blockquote type="cite" class=""><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;" class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">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;" class=""><font face="UICTFontTextStyleBody" class=""><span style="white-space: normal; background-color: rgba(255, 255, 255, 0);" class=""><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></div></blockquote><div><br class=""></div>It will not. &nbsp;The issues are unrelated. &nbsp;Whatever rules we use for supporting argument labels on indirect calls to functions will also apply to indirect calls to enum case constructors.</div><div><br class=""></div><div>John.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class="">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 class=""><br class=""></div><div class="">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></div></blockquote></div><div><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class=""><br class=""></div><div class="">Sent from my iPhone</div><div class=""><br class="">On 20 Apr 2017, at 21:39, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">On Thu, Apr 20, 2017 at 3:20 PM, John McCall via swift-evolution <span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span> wrote:<br class=""><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" class="">Proposal Link:&nbsp;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md" target="_blank" class="">https://github.com/<wbr class="">apple/swift-evolution/blob/<wbr class="">master/proposals/0155-<wbr class="">normalize-enum-case-<wbr class="">representation.md</a><div class=""><div class=""><div class=""><br class=""></div><div class="">Hello Swift Community,</div><div class=""><br class=""></div><div class="">The review of SE-0155 "Normalize Enum Case Representation” ran from&nbsp;March 31st through April 10th, 2017. The proposal is&nbsp;<b class="">accepted with revisions</b>.</div><div class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">It is true that including associated-value labels in case patterns does preserve a great deal of information in the source code:</div><div class=""><br class=""></div><div class="">&nbsp; - This information can usefully contribute to the clarity of the code following the pattern.</div><div class=""><br class=""></div><div class="">&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 class=""><br class=""></div><div class="">&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 class=""><br class=""></div><div class="">However, the core team feels that there are counter-arguments which weaken the force of these considerations:</div><div class=""><br class=""></div><div class="">&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 class=""><br class=""></div><div class="">&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 class=""><br class=""></div><div class="">&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 class="">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 class=""><br class=""></div><div class="">Accordingly, while it needs to be&nbsp;<b class="">possible</b>&nbsp;to include associated value labels in a case-pattern, and in some situations it may be&nbsp;<b class="">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 class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class=""><font face="Menlo" class="">&nbsp; enum E {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; case often(first: Int, second: Int)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; case lots(first: Int, second: Int)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; case many(value: Int)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; case many(first: Int, second: Int)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; case many(alpha: Int, beta: Int)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; case sometimes(value: Int)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; case sometimes(Int)</font></div><div class=""><font face="Menlo" class="">&nbsp; }</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; switch e {</font></div><div class=""><font face="Menlo" class="">&nbsp; // Valid: the sequence of labels exactly matches a case name.</font></div><div class=""><font face="Menlo" class="">&nbsp; case .often(first: let a, second: let b):</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; // Valid: there is only one case with this base name.</font></div><div class=""><font face="Menlo" class="">&nbsp; case .lots(let a, let b):</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; // Valid: there is only one case with this base name and payload count.</font></div><div class=""><font face="Menlo" class="">&nbsp; case .many(let a):</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; // Invalid: there are multiple cases with this base name and payload count.</font></div><div class=""><font face="Menlo" class="">&nbsp; case .many(let a, let b):</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; // Valid: the sequence of labels exactly matches a case name.</font></div><div class=""><font face="Menlo" class="">&nbsp; case .many(first: let a, second: let b):</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; // Invalid: includes a label, but not on all of the labelled arguments.</font></div><div class=""><font face="Menlo" class="">&nbsp; case .same(alpha: let a, let b):</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; // Valid: the sequence of labels exactly matches a case name (that happens to not provide any labels).</font></div><div class=""><span style="font-family:menlo" class="">&nbsp; case .sometimes(let x):</span></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; // Invalid: includes a label, but there is no matching case.</font></div><div class=""><span style="font-family:menlo" class="">&nbsp; case .sometimes(badlabel: let x):</span></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; ...</font></div><div class=""><font face="Menlo" class="">&nbsp; }</font></div><div class=""><br class=""></div><div class="">This only affects case patterns.&nbsp; Constructing a case always requires that any associated value labels in the case name be provided.</div><div class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">I assume that the following is obvious and the core team's intention, but it bears confirmation and being documented:</div><div class=""><br class=""></div><div class="">```</div><div class="">enum F {</div><div class="">&nbsp; case many(first: Int, second: Int)</div><div class="">&nbsp; case many(Int, Int)</div><div class="">&nbsp; case withDefaultValue(Int, Int, Int=42)</div><div class="">&nbsp; case withDefaultValue(first: Int, second: Int, third: Int=42)</div><div class="">&nbsp; case withDefaultValue(first: Int, second: Int, notThirdToMakeAPoint: Int=43)</div><div class="">}<br class=""></div><div class=""><br class=""></div><div class="">switch f {</div><div class="">// Valid, even though multiple cases have this base name and arity,</div><div class="">// because it is an exact match for a case that provides no labels.</div><div class="">case .many(let a, let b):</div><div class="">&nbsp; break</div><div class=""><br class=""></div><div class="">// Invalid, as case pattern must include even values with default.</div><div class="">case .withDefaultValue(let a, let b):</div><div class="">&nbsp; break</div><div class=""><br class=""></div><div class="">// Valid, as inclusion doesn't mean binding.</div><div class="">case .withDefaultValue(let a, let b, _):</div><div class="">&nbsp; break</div><div class=""><br class=""></div><div class="">// Valid, for the same reason as above.</div><div class="">case .withDefaultValue(first: let a, second: let b, third: _):</div><div class="">&nbsp; break</div><div class=""><br class=""></div><div class="">// Invalid, because the label is part of what's required, even if using `_`,</div><div class="">// since otherwise it could be ambiguous as to which case is being matched.</div><div class="">case .withDefaultValue(first: let a, second: let b, _):</div><div class="">&nbsp; break</div><div class="">}</div><div class="">```</div><div class=""><br class=""></div><div class=""><br class=""></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" class=""><div class=""><div class=""><div class=""></div><div class="">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 class=""><br class=""></div><div class="">John McCall</div><div class="">Review Manager</div></div></div></div><br class="">______________________________<wbr 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" rel="noreferrer" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a><br class="">
<br class=""></blockquote></div><br class=""></div></div>
</div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></div></blockquote></div><br class=""></body></html>