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
