[swift-evolution] [swift-evolution-announce] [Review] SE-0155: Normalize Enum Case Representation

Daniel Duan daniel at duan.org
Tue Feb 28 00:20:10 CST 2017


My observations of this discussion so far:

First of all, I think there’s no inherent conflict in "making enum constructors look like function" and “making patterns look like tuple”. These can and should be considered orthogonal aspects of enum in the language.

At the risk of over simplifying, I’d like to pick a few conflicting design choices that came up and put them in two columns.

Column A argues for simplicity of the language, better teachability and perhaps more consistency. In this column we have:

1. Enum constructors: Be like functions, have parameter names as well as argument labels.
2. Argument labels in patterns: Require argument label, making patterns look more like the declaration
3. Binding name in patterns: Require matching with argument labels (or maybe parameter names)

Column B argues for better ergonomics and authoring experience, even improved readability in same cases:

1. Enum constructors: Do not introduce parameter names (until we have concrete uses for them in the future)
2. Argument labels in patterns: Allow skipping of all argument labels, matching by position.
3. Binding name in patterns: Allow arbitrary names (or only allow such bindings when labels are supplied)

Here’s they are again for those with GUI/Web email clients:



There are things that doesn’t fit (overloading cases by type, for example, makes the constructors more consistent with functions, but it’s unclear whether it makes the language simpler or more complex).

Both the first revision of this proposal and the next are “a little from column A and a little from column B”. But neither column is *wrong* really. I’m confident that we are *not* doomed!

> On Feb 27, 2017, at 7:17 PM, Xiaodi Wu via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Having watched this conversation from the sidelines, I just wanted to chime in from a more distant view:
> 
> Originally, I thought this proposal was very nice because it made a good argument as to why enum cases would benefit from being function-like. It follows naturally that form should follow function, and therefore it's hard to argue that the syntax shouldn't be "rectified."
> 
> But, given the latest discussions, it seems that there's a bunch of round-peg-square-hole efforts going on precisely because enum cases *aren't* very function-like in some key respects:
> 
> - John McCall gives a cogent reason why parameter names and argument labels would be inconsistently used if they are put to the purpose that some have proposed here for enum cases.
> 
> - There's a lot of bikeshedding as to pattern matching with argument labels, as it seems that people generally agree that always requiring them in that scenario would make the experience of using enums worse rather than better. In fact, it seems that what's cited as a shortcoming in the original proposal ("labels in patterns aren't enforced") is precisely what we're trying to invent new sugar to duplicate.
> 
> Now, since we clearly want enum cases to be tuple-like in some respects (pattern matching) but function-like in other respects, is swinging from one extreme ("cases are tuples!") to the other ("cases are functions!") the right thing to do? Does it really make the language more "consistent"?
> 
> 
> On Mon, Feb 27, 2017 at 4:10 PM, Matthew Johnson via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 
> > On Feb 27, 2017, at 4:07 PM, Dave Abrahams via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> >
> >
> > on Mon Feb 27 2017, Joe Groff <jgroff-AT-apple.com> wrote:
> >
> >>> On Feb 24, 2017, at 9:26 PM, Daniel Duan <daniel at duan.org <mailto:daniel at duan.org>> wrote:
> >>>
> >>> Before I start revising this proposal, there are a couple of open questions I’d like to discuss
> >> with the community and the core team.
> >>>
> >>> The first question relates to the purpose of having a “internal”
> >>> argument name. There are applications of such names in GADT (if we
> >>> ever get there) and perhaps the case-as-subtype-of-the-enum stories
> >>> on the list right now. Out side of these scenarios, however, such
> >>> names has few chances to be used. The one I can come up with, which
> >>> is also the “open” part of the question, is this: we can use the
> >>> internal names in pattern matching, as opposed to using the
> >>> labels. This seems to align with the subtyping/GADT use cases. Is
> >>> this a desirable outcome?
> >>
> >> Why would GADTs make internal argument names useful?
> >
> > I'll probably never win this fight, but I'm trying to get people to use
> > “parameter name” and “argument label” as the preferred terms.
> 
> I like this terminology.  I’ll start using it.  Thanks for making an attempt to get everyone on the same page!  :)
> 
> >
> >> They seem completely useless to me. Their "internal"-ness is
> >> compromised if you try to hang semantics off of them—they shouldn't
> >> have any impact on use sites.
> >>
> >>> The second open question is the syntax for “overloaded” cases. If we
> >>> decide to allow them, what should the patterns matching them look
> >>> like? I can think of one obvious-ish design where we make the
> >>> pattern look like the declaration and require types for
> >>> disambiguation. So the most verbose form of pattern would look
> >>> something like
> >>>
> >>> ```
> >>> case let .baseName(label0 name0: Type0, label1 name1: Type1)
> >>> ```
> >>
> >> By "overloaded", do you mean "same name different types", or "same
> >> base name, different argument names"?
> >
> > When you write "argument name," do you mean parameter name or argument
> > label?  This is an example of why I'd like us to settle on the other
> > terminology.
> >
> >> I think we should have a consistent naming model where the latter is
> >> never considered overloading. As an affordance to make pattern
> >> matching more concise, it seems reasonable to me to maybe say that a
> >> binding pattern matches a label with the same name, so that `case
> >> .foo(let bar, let bas)` can match `.foo(bar:bas:)`.
> >
> > SGTM
> >
> > --
> > -Dave
> > _______________________________________________
> > swift-evolution mailing list
> > swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> > https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170227/fe966c1b/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: associated-value-discussion.png
Type: image/png
Size: 272490 bytes
Desc: not available
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170227/fe966c1b/attachment-0001.png>


More information about the swift-evolution mailing list