> On Apr 20, 2017, at 5:50 PM, Goffredo Marocchi <pana...@gmail.com> wrote:
> 
> 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):
> 
> 
>> Note that since the labels aren't part of a tuple, they no longer 
>> participate in type checking, behaving consistently with functions.
>> 
>> let f = Expr.elet // f has type ([(String, Expr)], Expr) -> Expr f([], 
>> anExpr) // Okay! f(locals: [], body: anExpr) // Won't compile.
> 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.

It will not.  The issues are unrelated.  Whatever rules we use for supporting 
argument labels on indirect calls to functions will also apply to indirect 
calls to enum case constructors.

John.

> 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.
> 
> 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.

> 
> Sent from my iPhone
> 
> On 20 Apr 2017, at 21:39, Xiaodi Wu via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> On Thu, Apr 20, 2017 at 3:20 PM, John McCall via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> Proposal Link: 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md
>>  
>> <https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md>
>> 
>> Hello Swift Community,
>> 
>> The review of SE-0155 "Normalize Enum Case Representation” ran from March 
>> 31st through April 10th, 2017. The proposal is accepted with revisions.
>> 
>> 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.
>> 
>> 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.
>> 
>> It is true that including associated-value labels in case patterns does 
>> preserve a great deal of information in the source code:
>> 
>>   - This information can usefully contribute to the clarity of the code 
>> following the pattern.
>> 
>>   - 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.
>> 
>>   - 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.
>> 
>> However, the core team feels that there are counter-arguments which weaken 
>> the force of these considerations:
>> 
>>   - 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.
>> 
>>   - 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.
>> 
>>   - 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 are 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.
>> 
>> Accordingly, while it needs to be possible to include associated value 
>> labels in a case-pattern, and in some situations it may be wise 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:
>> 
>> 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:
>> 
>>   enum E {
>>     case often(first: Int, second: Int)
>>     case lots(first: Int, second: Int)
>>     case many(value: Int)
>>     case many(first: Int, second: Int)
>>     case many(alpha: Int, beta: Int)
>>     case sometimes(value: Int)
>>     case sometimes(Int)
>>   }
>> 
>>   switch e {
>>   // Valid: the sequence of labels exactly matches a case name.
>>   case .often(first: let a, second: let b):
>>     ...
>> 
>>   // Valid: there is only one case with this base name.
>>   case .lots(let a, let b):
>>     ...
>> 
>>   // Valid: there is only one case with this base name and payload count.
>>   case .many(let a):
>>     ...
>> 
>>   // Invalid: there are multiple cases with this base name and payload count.
>>   case .many(let a, let b):
>>     ...
>> 
>>   // Valid: the sequence of labels exactly matches a case name.
>>   case .many(first: let a, second: let b):
>>     ...
>> 
>>   // Invalid: includes a label, but not on all of the labelled arguments.
>>   case .same(alpha: let a, let b):
>>     ...
>> 
>>   // Valid: the sequence of labels exactly matches a case name (that happens 
>> to not provide any labels).
>>   case .sometimes(let x):
>>     ...
>> 
>>   // Invalid: includes a label, but there is no matching case.
>>   case .sometimes(badlabel: let x):
>>     ...
>>   }
>> 
>> This only affects case patterns.  Constructing a case always requires that 
>> any associated value labels in the case name be provided.
>> 
>> 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.
>> 
>> I assume that the following is obvious and the core team's intention, but it 
>> bears confirmation and being documented:
>> 
>> ```
>> enum F {
>>   case many(first: Int, second: Int)
>>   case many(Int, Int)
>>   case withDefaultValue(Int, Int, Int=42)
>>   case withDefaultValue(first: Int, second: Int, third: Int=42)
>>   case withDefaultValue(first: Int, second: Int, notThirdToMakeAPoint: 
>> Int=43)
>> }
>> 
>> switch f {
>> // Valid, even though multiple cases have this base name and arity,
>> // because it is an exact match for a case that provides no labels.
>> case .many(let a, let b):
>>   break
>> 
>> // Invalid, as case pattern must include even values with default.
>> case .withDefaultValue(let a, let b):
>>   break
>> 
>> // Valid, as inclusion doesn't mean binding.
>> case .withDefaultValue(let a, let b, _):
>>   break
>> 
>> // Valid, for the same reason as above.
>> case .withDefaultValue(first: let a, second: let b, third: _):
>>   break
>> 
>> // Invalid, because the label is part of what's required, even if using `_`,
>> // since otherwise it could be ambiguous as to which case is being matched.
>> case .withDefaultValue(first: let a, second: let b, _):
>>   break
>> }
>> ```
>> 
>> 
>> 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.
>> 
>> John McCall
>> Review Manager
>> 
>> _______________________________________________
>> 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 <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

Reply via email to