<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="">Proposal Link: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-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 March 31st through April 10th, 2017. The proposal is <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. However, there was substantial disagreement about the right direction for pattern matching. 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. 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. 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. 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=""> - This information can usefully contribute to the clarity of the code following the pattern.</div><div class=""><br class=""></div><div class=""> - Hiding this information can lead to bugs that would be self-evident if the case labels were always included. 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=""> - 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=""> - 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. This binding name can convey at least as much information as a label would.</div><div class=""><br class=""></div><div class=""> - The risk of mis-labelling an associated value grows as the number of associated values grows. However, very few cases carry a large number of associated values. 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. 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. 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=""> - It is likely that cases will continue to be predominantly distinguished by their base name alone. Methods are often distinguished by argument labels because the base name identifies an entire class of operation with many possible variants. 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. Even when cases <i class="">are</i> 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 <b class="">possible</b> to include associated value labels in a case-pattern, and in some situations it may be <b class="">wise</b> to include them, the core team believes that requiring associated value labels would be unduly onerous. 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. 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. For example:</div><div class=""><br class=""></div><div class=""><font face="Menlo" class=""> enum E {</font></div><div class=""><font face="Menlo" class=""> case often(first: Int, second: Int)</font></div><div class=""><font face="Menlo" class=""> case lots(first: Int, second: Int)</font></div><div class=""><font face="Menlo" class=""> case many(value: Int)</font></div><div class=""><font face="Menlo" class=""> case many(first: Int, second: Int)</font></div><div class=""><font face="Menlo" class=""> case many(alpha: Int, beta: Int)</font></div><div class=""><font face="Menlo" class=""> case sometimes(value: Int)</font></div><div class=""><font face="Menlo" class=""> case sometimes(Int)</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> switch e {</font></div><div class=""><font face="Menlo" class=""> // Valid: the sequence of labels exactly matches a case name.</font></div><div class=""><font face="Menlo" class=""> case .often(first: let a, second: let b):</font></div><div class=""><font face="Menlo" class=""> ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> // Valid: there is only one case with this base name.</font></div><div class=""><font face="Menlo" class=""> case .lots(let a, let b):</font></div><div class=""><font face="Menlo" class=""> ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> // Valid: there is only one case with this base name and payload count.</font></div><div class=""><font face="Menlo" class=""> case .many(let a):</font></div><div class=""><font face="Menlo" class=""> ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> // Invalid: there are multiple cases with this base name and payload count.</font></div><div class=""><font face="Menlo" class=""> case .many(let a, let b):</font></div><div class=""><font face="Menlo" class=""> ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> // Valid: the sequence of labels exactly matches a case name.</font></div><div class=""><font face="Menlo" class=""> case .many(first: let a, second: let b):</font></div><div class=""><font face="Menlo" class=""> ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> // Invalid: includes a label, but not on all of the labelled arguments.</font></div><div class=""><font face="Menlo" class=""> case .same(alpha: let a, let b):</font></div><div class=""><font face="Menlo" class=""> ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> // Valid: the sequence of labels exactly matches a case name (that happens to not provide any labels).</font></div><div class=""><span class="" style="font-family: Menlo;"> case .sometimes(let x):</span></div><div class=""><font face="Menlo" class=""> ...</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> // Invalid: includes a label, but there is no matching case.</font></div><div class=""><span class="" style="font-family: Menlo;"> case .sometimes(badlabel: let x):</span></div><div class=""><font face="Menlo" class=""> ...</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><br class=""></div><div class="">This only affects case patterns. 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. 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 class=""><br class=""></div><div class="">The proposal includes a rule inferring labels in case patterns from binding names. The core team feels that imparting local variable names with this kind of significance would be unprecedented, surprising, and rather "pushy". The goal of this rule is also largely achieved by the new rule allowing labels to be omitted regardless of binding. Accordingly, this rule is struck from the proposal. 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></body></html>