[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