> On Feb 27, 2017, at 12:46 PM, Joe Groff <jgr...@apple.com> wrote: > > >> On Feb 27, 2017, at 10:39 AM, Matthew Johnson <matt...@anandabits.com> wrote: >> >> >> >> Sent from my iPad >> >>> On Feb 27, 2017, at 12:00 PM, Joe Groff via swift-evolution >>> <swift-evolution@swift.org> wrote: >>> >>> >>>> On Feb 24, 2017, at 9:26 PM, Daniel Duan <dan...@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? 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. >> >> Internal is probably a bad name. Imagine if the case is a subtype of the >> enum and thus a struct or struct-like type. We would usually want the >> property to be named similarly to the name we would use for an argument in a >> function implementation, not the label used when calling the function. >> >> Here is an example of the kind of thing I have in mind: >> >> enum PlayerState { >> case stopped >> sub case playing(with track: Track) >> >> // type of the playing case looks something like this: >> struct Playing { let track: Track } >> >> // the case value constructor looks something like this >> static func playing(with track: Track) -> Playing { >> return Playing(track: track) >> } >> } >> >> let foo = Foo.playing(with: makeTrack()) >> let track = foo.track >> >> switch foo { >> case .stopped: break >> // we get to match with the name that is argument / property-like >> // `with` would be a terrible variable name >> case .playing(let track): // do something with the track >> >> // this label would be used when the user wants to use a *different* name >> // case .playing(with: let someOtherName) >> } > > That still feels like it's going against the behavior of the binding name in > other declarations. Personally, `case .playing(with: let x)` doesn't bother > me that much, especially since the IDE ought to be able to splat that out for > you.
It depends on how verbose the label is. :) What did you think of the subtype example using the “internal” name as the property name? Does that make sense? I definitely don’t think we would want to allow eliding the *external* label by binding a name: `case .playing(let with)` is a bit absurd! :) Personally, I think eliding would be a useful shorthand and if we allow it along with internal names (which I also think is a good idea) then we would want eliding to use the internal / property name. The primary goal should be clarity at the site of the pattern. Sometimes a label adds clarity, but other times it will just add clutter. Allowing label elision ensures a reader sees a name that lines up with the meaning of the associated value with less clutter. I think this would often increase clarity. That said, it is a rather minor piece of syntactic sugar. > > -Joe _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution