I wasn't arguing for a strictly parallel syntax. I was arguing against
being able to omit labels. I don't view those as strictly tied together.
How are they?

On Mon, Sep 4, 2017 at 12:38 PM, Matthew Johnson <[email protected]>
wrote:

>
> On Sep 4, 2017, at 10:52 AM, T.J. Usiyan via swift-evolution <
> [email protected]> wrote:
>
> While re-litigating has it's issues, I am for simplifying the rule and
> always requiring the labels if they exist. This is similar to the change
> around external labels. Yes, it is slightly less convenient, but it removes
> a difficult to motivate caveat for beginners.
>
>
> I disagree.  Creating a value and destructuring it are two very different
> operations and I believe it is a mistake to require them to have parallel
> syntax.
>
> Imagine a future enhancement to the language that supports destructuring a
> struct.  A struct might not have a strictly memberwise initializer.  It
> might not even be possible to reconstruct initializer arguments for the
> sake of parallel destructuring syntax.  There might even be more than one
> projection that is reasonable to use when destructuring the value in a
> pattern (such as cartesian and polar coordinates).
>
> FWIW, I made this case in more detail during the discussion and review of
> this proposal.
>
>
> On Sun, Sep 3, 2017 at 4:35 PM, Xiaodi Wu via swift-evolution <
> [email protected]> wrote:
>
>> The desired behavior was the major topic of controversy during review;
>> I’m wary of revisiting this topic as we are essentially relitigating the
>> proposal.
>>
>> To start off, the premise, if I recall, going into review was that the
>> author **rejected** the notion that pattern matching should mirror
>> creation. I happen to agree with you on this point, but it was not the
>> prevailing argument. Fortunately, we do not need to settle this to arrive
>> at some clarity for the issues at hand.
>>
>> From a practical standpoint, a requirement for labels in all cases would
>> be much more source-breaking, whereas the proposal as it stands would allow
>> currently omitted labels to continue being valid. Moreover, and I think
>> this is a worthy consideration, one argument for permitting the omission of
>> labels during pattern matching is to encourage API designers to use labels
>> to clarify initialization without forcing its use by API consumers during
>> every pattern matching operation.
>>
>> In any case, the conclusion reached is precedented in the world of
>> functions:
>>
>> func g(a: Int, b: Int) { ... }
>> let f = g
>> f(1, 2)
>>
>> On Sun, Sep 3, 2017 at 15:13 Robert Widmann via swift-evolution <
>> [email protected]> wrote:
>>
>>> Hello Swift Evolution,
>>>
>>> I took up the cause of implementing SE-0155
>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md>,
>>> and am most of the way through the larger points of the proposal.  One
>>> thing struck me when I got to the part about normalizing the behavior
>>> of pattern matching
>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md#pattern-consistency>.
>>> The Core Team indicated in their rationale
>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170417/035972.html>
>>>  that
>>> the proposal’s suggestion that a variable binding sub in for a label was a
>>> little much as in this example:
>>>
>>> enum Foo {
>>>   case foo(x: Int, y: Int)
>>> }
>>> if case let .foo(x: x, y: y) {} // Fine!  Labels match and are in order
>>> if case let .foo(x, y: y) {} // Bad!  Missing label 'x'
>>> if case let .foo(x, y) {} // Fine?  Missing labels, but variable names
>>> match labels
>>>
>>> They instead suggested the following behavior:
>>>
>>> enum Foo {
>>>   case foo(x: Int, y: Int)
>>> }
>>> if case let .foo(x: x, y: y) {} // Fine!  Labels match and are in order
>>> if case let .foo(x, y: y) {} // Bad!  Missing label 'x'
>>> if case let .foo(x, y) {} // Fine?  Missing labels, and full name of
>>> case is unambiguous
>>>
>>> Which, for example, would reject this:
>>>
>>> enum Foo {
>>>   case foo(x: Int, y: Int) // Note: foo(x:y:)
>>>   case foo(x: Int, z: Int) // Note: foo(x:z:)
>>> }
>>> if case let .foo(x, y) {} // Bad!  Are we matching foo(x:y:) or
>>> foo(x:z:)?
>>>
>>> With this reasoning:
>>>
>>>  - 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.
>>>
>>>
>>> This sounds fine in principle, but I believe it is inconsistent with the
>>> goals of the proposal and doesn’t actually normalize much about the
>>> existing pattern matching process.  As it stands, labels may be omitted
>>> from patterns because Swift’s philosophy before this proposal is that
>>> associated values in enum cases were conceptually tuples.  With the
>>> addition of default arguments, the ability to overload case names with
>>> differing associated value labels, and making the labels part of the API
>>> name, there is no reason we should allow tuple-like behavior in just this
>>> one case.
>>>
>>> While an associated-value label...
>>>
>>>
>>> While it is true that a user often has a domain-specific intention for
>>> variables created during the destructuring process, the labels do not
>>> distract from the original purpose of the API and the user is still free to
>>> provide whatever name they see fit.
>>>
>>> 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...
>>>
>>>
>>> This is phrased as a matter of choice, in practice this is perplexing.
>>> Recall an earlier rejected pattern:
>>>
>>> enum Foo {
>>>   case foo(x: Int, y: Int)
>>> }
>>> if case let .foo(x, y: y) {} // Bad!  Missing label ‘x'
>>>
>>> From the user’s perspective, it is obvious what should happen: Either
>>> they did, or did not, intend to match labels.  From the compiler’s
>>> perspective this is a proper ambiguity.  Did the user intend to provide a
>>> “more meaningful name” and hence meant to elide the label, or did the user
>>> intend to match all the labels but forgot or deleted one?  It is not
>>> obvious why, if we’re making the distinction, we should assume one way or
>>> the other.   This case only gets worse when we must diagnose intent if the
>>> case is also overloaded by base name.
>>>
>>> I don’t see how it is "unduly onerous” to teach code completion to
>>> suggest the full name of an enum case everywhere or to create diagnostics
>>> that always insert missing labels in patterns to correct the user’s
>>> mistake.  Freedom of choice is, in this case, only making a hard problem
>>> harder.
>>>
>>> It is likely that cases will continue to be predominantly distinguished by 
>>> their base name alone...
>>>
>>>
>>> This makes sense given the current state of the world, but under this
>>> proposal we fully expect users to be overloading that base name and writing
>>> more and more ambiguous patterns.  We should encourage disambiguating these
>>> cases with labels as a matter of both principle and QoI.
>>>
>>> A pattern is meant to mirror the way a value was constructed with
>>> destructuring acting as a dual to creation.  By maintaining the structure
>>> of the value in the pattern, labels included, users can properly convey
>>> that they intend the label to be a real part of the API of an enum case
>>> with associated values instead of just an ancillary storage area.  Further,
>>> we can actually simplify pattern matching by making enum cases consistent
>>> with something function-like instead of tuple-like.
>>>
>>> To that end, I'd like the rationale and the proposal to be amended to
>>> require labels in patterns in all cases.
>>>
>>> Thoughts?
>>>
>>> ~Robert Widmann
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected]
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected]
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to