> On Feb 27, 2017, at 9:17 PM, Xiaodi Wu <[email protected]> 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.

I didn’t write the proposal so I won’t comment directly on the motivation 
section.  The reason I think not enforcing labels is a problem in the current 
rules is because allowing this does not convey the meaning of the associated 
value to a reader of the pattern.  The suggestions for syntactic sugar to allow 
eliding a label avoids this problem altogether.  I don’t think label elision is 
that complicated rule to teach and it could improve clarity of code 
nontrivially.  

I have personally found a tension between using labels and having patterns that 
are quite unfortunately verbose.  One can avoid this today by leaving off the 
label and being responsible with the name you assign.  I would like to keep the 
concise nature of leaving off the labels while being assured that a reasonable 
name is used.

> 
> 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”?

My view is that it is a mistake to try to pidgeonhole enum cases into *one* of 
the roles they play.  They actually play a couple of roles and we should 
acknowledge and consider each of these in designing the language.  

The way I view enum cases is as a static factory method that produces a value 
which may be structurally matched using a pattern accessible via the base name 
of the case.  I don’t see any reason why we should have to adopt one view or 
the other.  Both are true and should be embraced.  

enum Foo {
   case bar(argumentLabel propertyName: Int)
}

Is a lot like this in a hypothetical Swift with value subtyping and structural 
decomposition / matching of structs:

struct Foo {
   struct Bar: Foo { let propertyName: Int }
   static func bar(argumentLabel parameterName: Int) -> Bar {
      return Bar(propertyName: parameterName)
   }
}

switch Foo.bar(argumentLabel: 42) as Foo {
   case let (propertyName: let propertyValue): print(“value is 
\(propertyValue)”) as Bar
}

The only important differences are that this *requires* subtyping, and it does 
not allow the pattern to be accessed on Foo.  One can even imaging syntax 
allowing the pattern to be accessible on `Foo` using a name `bar`:

extension Foo {
   pattern bar = // syntax which sets up a structural match of Bar values 
inside the parens when users type `.bar(structural match of Bar value here)`
}


> 
> 
> On Mon, Feb 27, 2017 at 4:10 PM, Matthew Johnson via swift-evolution 
> <[email protected] <mailto:[email protected]>> wrote:
> 
> > On Feb 27, 2017, at 4:07 PM, Dave Abrahams via swift-evolution 
> > <[email protected] <mailto:[email protected]>> wrote:
> >
> >
> > on Mon Feb 27 2017, Joe Groff <jgroff-AT-apple.com> wrote:
> >
> >>> On Feb 24, 2017, at 9:26 PM, Daniel Duan <[email protected] 
> >>> <mailto:[email protected]>> 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
> > [email protected] <mailto:[email protected]>
> > https://lists.swift.org/mailman/listinfo/swift-evolution 
> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected] <mailto:[email protected]>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <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