[swift-evolution] [swift-evolution-announce] [Review] SE-0155: Normalize Enum Case Representation
Joe Groff
jgroff at apple.com
Mon Feb 27 12:46:16 CST 2017
> On Feb 27, 2017, at 10:39 AM, Matthew Johnson <matthew at anandabits.com> wrote:
>
>
>
> Sent from my iPad
>
>> On Feb 27, 2017, at 12:00 PM, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:
>>
>>
>>> On Feb 24, 2017, at 9:26 PM, Daniel Duan <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? 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.
-Joe
More information about the swift-evolution
mailing list