[Review] SE-0155: Normalize Enum Case Representation

I'm on vacation and don't have time for a full review right now, but I am concerned that wild this proposal would make enums more general and uniform with the rest of the language , they also would become much more awkward for common use cases. I have recently been very pleased that I didn't have to supply labels in switch statements where the label name would simply have matched the name of the variable to be bound. This looks needlessly verbose:

  case .valid(value: let value, resumptionPoint: let resumptionPoint):

I cannot imagine a real life use case where one would have labels in the case and desire to bind associated values to variables having different names than the labels.

Dave has a good point here. (Which I'm reading *after* sending feedback to John.) If
the problem with labels is that using them for conditional binding is awkward, maybe
it's not the labels that's the problem.

Pattern matching with conditional binding is a mess.

* It's hard to read.
* It uses inconsistent `let` and `var` both inside and outside the `case` syntax.
* It uses inconsistent syntax for switch/case, if/case-guard/case, and regular pattern matching.
* Conditional binding is coequal with pattern matching and can be mixed-and-matched,
  for example, `case .foo(var x, 0 ... .max) where x % 2 == 1`
* It involves inconsistent operators (`=` and `~=`) and awkward syntax.
* It is hard to teach, to learn, and is one of the overall sore points of the language.

Some problems go away if you bind the existing value to a specific case instead of
conditionally binding new values. There are some significant issues here, but let me
demonstrate to give a sense of what I'm talking about. An approach something like
the following would support this proposal and avoids DRY violations. (I'm not
sure if this is even possible to accomplish):

enum Result<T> {
    case success(value: T)
    case failure(error: Error)
}

if case let returnedResult ~= .success {
    // returnedResult is the `success` case.
    print(returnedResult.value) // member access
}

guard case var returnedResult ~= .success  else { ...discard error and leave scope ... }
// returnedResult is the `success` case for the remainder of this scope
print(returnedResult.value)

switch returnedResult {
   // Something like this
    case .success:  // use $0.value
}

switch aDifferentEnum {
    case foo(x: _, y: 0 ...max) where $0.x %2 == 1: // use $0.x, $0.y
    case foo: // use $0.x, $0.y here
}

Can we support labels and re-architect interpretation/binding?

-- E

···

On Feb 19, 2017, at 12:49 PM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 18, 2017, at 10:49 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I agree with this, but I think it’s an issue we can solve (perhaps as an amendment to this proposal).

First, I think Brent’s idea of introducing an argument label that can be distinct from the “property” name of the case is a good one. I think we should do this. It takes the parallel with function signatures even further.

Second, we should allow the “property” name to be `_`. This would mean no label can be used when matching:

case valid(value _: ValueType, resumptionPoint _: PointType)

Third, I think we should also allow suers to elide the label if they either discard the value with `_` or bind a name that is identical to the label, so we might have:

// declaration:
case valid(externalCasConstructorLabel value: ValueType, externalCaseConstructorLabel resumptionPoint: PointType)

// match ok:
case .valid(let value, let resumptionPoint):

// error, names do not match:
case .valid(let foo, let bar):

// ok, label is used:
case .valid(value: let foo, resumptionPoint: let bar):

This follows the behavior of function signatures very closely. The external label is used to provide context for the argument at the call site (of the case constructor). The internal name is used to bind a name to the value that is used by code that works with the value.

The only exception here is that because the usage site is distant from the case declaration it may wish to use a different name. We allow that, but only if the “internal name” is also used in the pattern. This preserves the ability of a reader of the code to see the name / meaning of the associated value as it was declared by the enum in addition to the name that might make more sense for use in the local context.

Secondly, I can't imagine a case where one would want to use the same case basename and different labels. The very common use case where the types of associated values completely distinguish the case and one would rather not have to supply a case name at all is completely unaddressed. If my quick read is not mistaken, this proposal makes it legal for cases to have different complete names (including base name and labels), but doesn't make it legal to have the same full name (which I would love to be "_" or missing in some cases) with different associated value types. If we were truly following the precedent set by function signatures, wouldn't that be possible too?

+1. I think this makes a lot of sense. It completes the parallel of cases with overloaded functions.

I think anonymous cases are a really good idea. I discuss those quite a bit in the value subtyping manifesto I shared last week (I’d love to hear your thoughts on it if / when you have time to take a look).

How would you propose that values of anonymous cases be constructed and matched? My solution is to allow them to be constructed by implicit conversion from the associated value type to the enum type and matched by a cast pattern. Is that what you have in mind? I would *really* love to see this someday...

Sent from my moss-covered three-handled family gradunza

On Feb 17, 2017, at 5:26 PM, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org <mailto:swift-evolution-announce@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

I'm on vacation and don't have time for a full review right now, but I am concerned that wild this proposal would make enums more general and uniform with the rest of the language , they also would become much more awkward for common use cases. I have recently been very pleased that I didn't have to supply labels in switch statements where the label name would simply have matched the name of the variable to be bound. This looks needlessly verbose:

  case .valid(value: let value, resumptionPoint: let resumptionPoint):

I cannot imagine a real life use case where one would have labels in the case and desire to bind associated values to variables having different names than the labels.

I agree with this, but I think it’s an issue we can solve (perhaps as an amendment to this proposal).

First, I think Brent’s idea of introducing an argument label that can be distinct from the “property” name of the case is a good one. I think we should do this. It takes the parallel with function signatures even further.

Second, we should allow the “property” name to be `_`. This would mean no label can be used when matching:

case valid(value _: ValueType, resumptionPoint _: PointType)

Third, I think we should also allow suers to elide the label if they either discard the value with `_` or bind a name that is identical to the label, so we might have:

// declaration:
case valid(externalCasConstructorLabel value: ValueType, externalCaseConstructorLabel resumptionPoint: PointType)

// match ok:
case .valid(let value, let resumptionPoint):

// error, names do not match:
case .valid(let foo, let bar):

// ok, label is used:
case .valid(value: let foo, resumptionPoint: let bar):

This follows the behavior of function signatures very closely. The external label is used to provide context for the argument at the call site (of the case constructor). The internal name is used to bind a name to the value that is used by code that works with the value.

The only exception here is that because the usage site is distant from the case declaration it may wish to use a different name. We allow that, but only if the “internal name” is also used in the pattern. This preserves the ability of a reader of the code to see the name / meaning of the associated value as it was declared by the enum in addition to the name that might make more sense for use in the local context.

Secondly, I can't imagine a case where one would want to use the same case basename and different labels. The very common use case where the types of associated values completely distinguish the case and one would rather not have to supply a case name at all is completely unaddressed. If my quick read is not mistaken, this proposal makes it legal for cases to have different complete names (including base name and labels), but doesn't make it legal to have the same full name (which I would love to be "_" or missing in some cases) with different associated value types. If we were truly following the precedent set by function signatures, wouldn't that be possible too?

+1. I think this makes a lot of sense. It completes the parallel of cases with overloaded functions.

I think anonymous cases are a really good idea. I discuss those quite a bit in the value subtyping manifesto I shared last week (I’d love to hear your thoughts on it if / when you have time to take a look).

How would you propose that values of anonymous cases be constructed and matched? My solution is to allow them to be constructed by implicit conversion from the associated value type to the enum type and matched by a cast pattern. Is that what you have in mind? I would *really* love to see this someday...

I can’t speak for Dave obviously. But I think he was merely proposing “overloaded” form of enum options, in which multiple options may share the compound name but with differently associated types. The name “_” would just be a normal identifier in such scenario. So it would also be the contractor’s function name.

···

On Feb 19, 2017, at 11:49 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 18, 2017, at 10:49 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sent from my moss-covered three-handled family gradunza

On Feb 17, 2017, at 5:26 PM, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org <mailto:swift-evolution-announce@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

+1, two small questions:

- If two cases have the same base name but different full names, will matching on the base name match both cases, or will it be an error?

I feel that it would be safer if it was an error. If the developer intends to match both cases, requiring both explicitly is a (slight) inconvenience but it's also very clear about what's going to match.

I disagree. It is simple enough to use different base names if you don’t want the cases to match. An example of why it should not be an error: I intend to for errors with same base names to be handled in the same way and I don’t want to enumerate all the similar cases and change code every time I add a new way to construct an error. I understand that other people want the equivalent of function overloading. Code that needs to access values must deal with unique cases, so type safety is assured in any case.

Java enums have arguments and match on “base names” (they are quite different, but the precedent exists) and I don’t think that matching on the base name would be confusing. I also do not believe that it is worth adding this feature if all cases are completely unique.The pain of forcing a (probably small) subset of developers to use unique names is preferable to complicating the language for no functional benefit, in my opinion.

···

On Feb 18, 2017, at 6:16 AM, David Rönnqvist via swift-evolution <swift-evolution@swift.org> wrote:
On 18 Feb 2017, at 09:30, Slava Pestov via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

- What are the memory layout optimizations described here? From a first glance this looks purely syntactic.

Slava

On Feb 17, 2017, at 7:26 PM, John McCall via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I'm on vacation and don't have time for a full review right now, but I am concerned that wild this proposal would make enums more general and uniform with the rest of the language , they also would become much more awkward for common use cases. I have recently been very pleased that I didn't have to supply labels in switch statements where the label name would simply have matched the name of the variable to be bound. This looks needlessly verbose:

  case .valid(value: let value, resumptionPoint: let resumptionPoint):

I cannot imagine a real life use case where one would have labels in the case and desire to bind associated values to variables having different names than the labels.

I agree with this, but I think it’s an issue we can solve (perhaps as an amendment to this proposal).

First, I think Brent’s idea of introducing an argument label that can be distinct from the “property” name of the case is a good one. I think we should do this. It takes the parallel with function signatures even further.

Second, we should allow the “property” name to be `_`. This would mean no label can be used when matching:

case valid(value _: ValueType, resumptionPoint _: PointType)

Third, I think we should also allow suers to elide the label if they either discard the value with `_` or bind a name that is identical to the label, so we might have:

// declaration:
case valid(externalCasConstructorLabel value: ValueType, externalCaseConstructorLabel resumptionPoint: PointType)

// match ok:
case .valid(let value, let resumptionPoint):

// error, names do not match:
case .valid(let foo, let bar):

// ok, label is used:
case .valid(value: let foo, resumptionPoint: let bar):

This follows the behavior of function signatures very closely. The external label is used to provide context for the argument at the call site (of the case constructor). The internal name is used to bind a name to the value that is used by code that works with the value.

The only exception here is that because the usage site is distant from the case declaration it may wish to use a different name. We allow that, but only if the “internal name” is also used in the pattern. This preserves the ability of a reader of the code to see the name / meaning of the associated value as it was declared by the enum in addition to the name that might make more sense for use in the local context.

Secondly, I can't imagine a case where one would want to use the same case basename and different labels. The very common use case where the types of associated values completely distinguish the case and one would rather not have to supply a case name at all is completely unaddressed. If my quick read is not mistaken, this proposal makes it legal for cases to have different complete names (including base name and labels), but doesn't make it legal to have the same full name (which I would love to be "_" or missing in some cases) with different associated value types. If we were truly following the precedent set by function signatures, wouldn't that be possible too?

+1. I think this makes a lot of sense. It completes the parallel of cases with overloaded functions.

I think anonymous cases are a really good idea. I discuss those quite a bit in the value subtyping manifesto I shared last week (I’d love to hear your thoughts on it if / when you have time to take a look).

How would you propose that values of anonymous cases be constructed and matched? My solution is to allow them to be constructed by implicit conversion from the associated value type to the enum type and matched by a cast pattern. Is that what you have in mind? I would *really* love to see this someday...

I can’t speak for Dave obviously. But I think he was merely proposing “overloaded” form of enum options, in which multiple options may share the compound name but with differently associated types. The name “_” would just be a normal identifier in such scenario. So it would also be the contractor’s function name.

So values would be constructed like MyEnum._(42) and matched like ._(let i as Int). Is that what you're thinking? I suppose that would be a reasonable step to take for now. Making MyEnum a subtype of the case types still seems like a more elegant long term goal.

···

Sent from my iPad

On Feb 19, 2017, at 6:52 PM, Daniel Duan <daniel@duan.org> wrote:

On Feb 19, 2017, at 11:49 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:
On Feb 18, 2017, at 10:49 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

Sent from my moss-covered three-handled family gradunza

On Feb 17, 2017, at 5:26 PM, John McCall <rjmccall@apple.com> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

+1, two small questions:

- If two cases have the same base name but different full names, will matching on the base name match both cases, or will it be an error?

I feel that it would be safer if it was an error. If the developer intends to match both cases, requiring both explicitly is a (slight) inconvenience but it's also very clear about what's going to match.

I disagree. It is simple enough to use different base names if you don’t want the cases to match. An example of why it should not be an error: I intend to for errors with same base names to be handled in the same way and I don’t want to enumerate all the similar cases and change code every time I add a new way to construct an error. I understand that other people want the equivalent of function overloading. Code that needs to access values must deal with unique cases, so type safety is assured in any case.

Java enums have arguments and match on “base names” (they are quite different, but the precedent exists) and I don’t think that matching on the base name would be confusing. I also do not believe that it is worth adding this feature if all cases are completely unique.The pain of forcing a (probably small) subset of developers to use unique names is preferable to complicating the language for no functional benefit, in my opinion.

A possible compromise: specify that all base names should be matched with a new keyword (or?) Here the keyword ```all``` is used to match all base names.

enum MyError : Error
{
    case e( a: String )
    case e( a: Int )
}

func handleError( error: MyError )
{
    switch error {
    case all .e :
        break
    }
}
···

On Feb 20, 2017, at 12:31 PM, Christopher Kornher via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 18, 2017, at 6:16 AM, David Rönnqvist via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
On 18 Feb 2017, at 09:30, Slava Pestov via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

- What are the memory layout optimizations described here? From a first glance this looks purely syntactic.

Slava

On Feb 17, 2017, at 7:26 PM, John McCall via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

I had not intended for _ to be an ordinary identifier, but as a way of spelling the empty case name. Ambiguous cases, not distinguished by either full name or payload type, would be errors. How to construct anonymous cases? I guess it would be MyEnum(expression)

···

Sent from my moss-covered three-handled family gradunza

On Feb 19, 2017, at 2:52 PM, Daniel Duan <daniel@duan.org> wrote:

On Feb 19, 2017, at 11:49 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 18, 2017, at 10:49 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

I'm on vacation and don't have time for a full review right now, but I am concerned that wild this proposal would make enums more general and uniform with the rest of the language , they also would become much more awkward for common use cases. I have recently been very pleased that I didn't have to supply labels in switch statements where the label name would simply have matched the name of the variable to be bound. This looks needlessly verbose:

  case .valid(value: let value, resumptionPoint: let resumptionPoint):

I cannot imagine a real life use case where one would have labels in the case and desire to bind associated values to variables having different names than the labels.

I agree with this, but I think it’s an issue we can solve (perhaps as an amendment to this proposal).

First, I think Brent’s idea of introducing an argument label that can be distinct from the “property” name of the case is a good one. I think we should do this. It takes the parallel with function signatures even further.

Second, we should allow the “property” name to be `_`. This would mean no label can be used when matching:

case valid(value _: ValueType, resumptionPoint _: PointType)

Third, I think we should also allow suers to elide the label if they either discard the value with `_` or bind a name that is identical to the label, so we might have:

// declaration:
case valid(externalCasConstructorLabel value: ValueType, externalCaseConstructorLabel resumptionPoint: PointType)

// match ok:
case .valid(let value, let resumptionPoint):

// error, names do not match:
case .valid(let foo, let bar):

// ok, label is used:
case .valid(value: let foo, resumptionPoint: let bar):

This follows the behavior of function signatures very closely. The external label is used to provide context for the argument at the call site (of the case constructor). The internal name is used to bind a name to the value that is used by code that works with the value.

The only exception here is that because the usage site is distant from the case declaration it may wish to use a different name. We allow that, but only if the “internal name” is also used in the pattern. This preserves the ability of a reader of the code to see the name / meaning of the associated value as it was declared by the enum in addition to the name that might make more sense for use in the local context.

Secondly, I can't imagine a case where one would want to use the same case basename and different labels. The very common use case where the types of associated values completely distinguish the case and one would rather not have to supply a case name at all is completely unaddressed. If my quick read is not mistaken, this proposal makes it legal for cases to have different complete names (including base name and labels), but doesn't make it legal to have the same full name (which I would love to be "_" or missing in some cases) with different associated value types. If we were truly following the precedent set by function signatures, wouldn't that be possible too?

+1. I think this makes a lot of sense. It completes the parallel of cases with overloaded functions.

I think anonymous cases are a really good idea. I discuss those quite a bit in the value subtyping manifesto I shared last week (I’d love to hear your thoughts on it if / when you have time to take a look).

How would you propose that values of anonymous cases be constructed and matched? My solution is to allow them to be constructed by implicit conversion from the associated value type to the enum type and matched by a cast pattern. Is that what you have in mind? I would *really* love to see this someday...

I can’t speak for Dave obviously. But I think he was merely proposing “overloaded” form of enum options, in which multiple options may share the compound name but with differently associated types. The name “_” would just be a normal identifier in such scenario. So it would also be the contractor’s function name.

Sent from my moss-covered three-handled family gradunza

On Feb 17, 2017, at 5:26 PM, John McCall <rjmccall@apple.com> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

That is certainly a pragmatic solution. However, it would seem to me that
it defeats the raison d'etre for the proposal. As I understand it, the
whole idea here is that enum associated values work like argument lists,
but the syntax is subtly different. Therefore, let's make the rules the
same.

If we have to introduce new keywords to make that workable, then instead of
simplifying and streamlining the language we've just added more rules to
it. In some ways, that's taking us to a very different end result. Given
recent discussion on this list over concerns that too much syntactic sugar
is being proposed that weigh down the language, we should be wary of this.

···

On Mon, Feb 20, 2017 at 1:53 PM, Christopher Kornher via swift-evolution < swift-evolution@swift.org> wrote:

On Feb 20, 2017, at 12:31 PM, Christopher Kornher via swift-evolution < > swift-evolution@swift.org> wrote:

On Feb 18, 2017, at 6:16 AM, David Rönnqvist via swift-evolution < > swift-evolution@swift.org> wrote:

On 18 Feb 2017, at 09:30, Slava Pestov via swift-evolution < > swift-evolution@swift.org> wrote:

+1, two small questions:

- If two cases have the same base name but different full names, will
matching on the base name match both cases, or will it be an error?

I feel that it would be safer if it was an error. If the developer intends
to match both cases, requiring both explicitly is a (slight) inconvenience
but it's also very clear about what's going to match.

I disagree. It is simple enough to use different base names if you don’t
want the cases to match. An example of why it should not be an error: I
intend to for errors with same base names to be handled in the same way and
I don’t want to enumerate all the similar cases and change code every time
I add a new way to construct an error. I understand that other people want
the equivalent of function overloading. Code that needs to access values
must deal with unique cases, so type safety is assured in any case.

Java enums have arguments and match on “base names” (they are quite
different, but the precedent exists) and I don’t think that matching on the
base name would be confusing. I also do not believe that it is worth adding
this feature if all cases are completely unique.The pain of forcing a
(probably small) subset of developers to use unique names is preferable to
complicating the language for no functional benefit, in my opinion.

A possible compromise: specify that all base names should be matched with
a new keyword (or?) Here the keyword ```all``` is used to match all base
names.

enum MyError : Error
{
    case e( a: String )
    case e( a: Int )
}

func handleError( error: MyError )
{
    switch error {
    case all .e :
        break
    }
}

- What are the memory layout optimizations described here? From a first
glance this looks purely syntactic.

Slava

On Feb 17, 2017, at 7:26 PM, John McCall via swift-evolution < > swift-evolution@swift.org> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and
runs through next Friday, February 26th. The proposal is available here:
GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews
should be sent to the swift-evolution mailing list at
https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the
review manager. When replying, please try to keep the proposal link at the
top of the message:

Proposal link: https://github.com/apple/swift-evolution/blob/
master/proposals/0155-normalize-enum-case-representation.md

Reply text

Other replies

*What goes into a review?*

The goal of the review process is to improve the proposal under review
through constructive criticism and, eventually, determine the direction of
Swift. When writing your review, here are some questions you might want to
answer in your review:

• What is your evaluation of the proposal?
• Is the problem being addressed significant enough to warrant a change to
Swift?
• Does this proposal fit well with the feel and direction of Swift?
• If you have used other languages or libraries with a similar feature,
how do you feel that this proposal compares to those?
• How much effort did you put into your review? A glance, a quick reading,
or an in-depth study?

More information about the Swift evolution process is available at
https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

My apologies for misunderstanding.

Would it be better to add the anonymous case feature in a separate proposal? It stands alone as a new addition to enum. The intent for this proposal is bringing enum's syntax closure to other part of Swift.

Daniel Duan

···

Sent from my iPhone

On Feb 21, 2017, at 1:15 AM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

I had not intended for _ to be an ordinary identifier, but as a way of spelling the empty case name. Ambiguous cases, not distinguished by either full name or payload type, would be errors. How to construct anonymous cases? I guess it would be MyEnum(expression)

Sent from my moss-covered three-handled family gradunza

On Feb 19, 2017, at 2:52 PM, Daniel Duan <daniel@duan.org> wrote:

On Feb 19, 2017, at 11:49 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 18, 2017, at 10:49 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

I'm on vacation and don't have time for a full review right now, but I am concerned that wild this proposal would make enums more general and uniform with the rest of the language , they also would become much more awkward for common use cases. I have recently been very pleased that I didn't have to supply labels in switch statements where the label name would simply have matched the name of the variable to be bound. This looks needlessly verbose:

  case .valid(value: let value, resumptionPoint: let resumptionPoint):

I cannot imagine a real life use case where one would have labels in the case and desire to bind associated values to variables having different names than the labels.

I agree with this, but I think it’s an issue we can solve (perhaps as an amendment to this proposal).

First, I think Brent’s idea of introducing an argument label that can be distinct from the “property” name of the case is a good one. I think we should do this. It takes the parallel with function signatures even further.

Second, we should allow the “property” name to be `_`. This would mean no label can be used when matching:

case valid(value _: ValueType, resumptionPoint _: PointType)

Third, I think we should also allow suers to elide the label if they either discard the value with `_` or bind a name that is identical to the label, so we might have:

// declaration:
case valid(externalCasConstructorLabel value: ValueType, externalCaseConstructorLabel resumptionPoint: PointType)

// match ok:
case .valid(let value, let resumptionPoint):

// error, names do not match:
case .valid(let foo, let bar):

// ok, label is used:
case .valid(value: let foo, resumptionPoint: let bar):

This follows the behavior of function signatures very closely. The external label is used to provide context for the argument at the call site (of the case constructor). The internal name is used to bind a name to the value that is used by code that works with the value.

The only exception here is that because the usage site is distant from the case declaration it may wish to use a different name. We allow that, but only if the “internal name” is also used in the pattern. This preserves the ability of a reader of the code to see the name / meaning of the associated value as it was declared by the enum in addition to the name that might make more sense for use in the local context.

Secondly, I can't imagine a case where one would want to use the same case basename and different labels. The very common use case where the types of associated values completely distinguish the case and one would rather not have to supply a case name at all is completely unaddressed. If my quick read is not mistaken, this proposal makes it legal for cases to have different complete names (including base name and labels), but doesn't make it legal to have the same full name (which I would love to be "_" or missing in some cases) with different associated value types. If we were truly following the precedent set by function signatures, wouldn't that be possible too?

+1. I think this makes a lot of sense. It completes the parallel of cases with overloaded functions.

I think anonymous cases are a really good idea. I discuss those quite a bit in the value subtyping manifesto I shared last week (I’d love to hear your thoughts on it if / when you have time to take a look).

How would you propose that values of anonymous cases be constructed and matched? My solution is to allow them to be constructed by implicit conversion from the associated value type to the enum type and matched by a cast pattern. Is that what you have in mind? I would *really* love to see this someday...

I can’t speak for Dave obviously. But I think he was merely proposing “overloaded” form of enum options, in which multiple options may share the compound name but with differently associated types. The name “_” would just be a normal identifier in such scenario. So it would also be the contractor’s function name.

Sent from my moss-covered three-handled family gradunza

On Feb 17, 2017, at 5:26 PM, John McCall <rjmccall@apple.com> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

My apologies for misunderstanding.

Would it be better to add the anonymous case feature in a separate proposal? It stands alone as a new addition to enum. The intent for this proposal is bringing enum's syntax closure to other part of Swift.

The core team met and talked about SE-0155 today, even though we're not quite done with the review period, and here's where we stand.

SE-0155 is being returned for revision. Consensus appears to be strongly in favor of requiring argument labels (if provided) to be enforced on "call" sites. However, the core team feels that the proposal needs revision in the following ways:
  - Are internal argument names syntactically allowed in a case declaration?
  - Can cases with the same base name be overloaded by argument label? If so, is a pattern match using just the bare name ambiguous or does it match both cases?
  - Can cases with the same name (using the same rule as above) be overloaded by argument type? If so, how are they disambiguated in pattern matches?
  - Do pattern matches require argument labels to be given along with value patterns, e.g. "case .valid(value: let value)", or is there some way to shorten this? If the latter, what are the rules for that?
  - Are you proposing anonymous cases, and if so, what are the language rules for them?
  - The proposal makes a claim about layout efficiency; please either discuss this claim or remove it.

John.

···

On Feb 21, 2017, at 4:43 AM, Daniel Duan via swift-evolution <swift-evolution@swift.org> wrote:

Daniel Duan
Sent from my iPhone

On Feb 21, 2017, at 1:15 AM, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I had not intended for _ to be an ordinary identifier, but as a way of spelling the empty case name. Ambiguous cases, not distinguished by either full name or payload type, would be errors. How to construct anonymous cases? I guess it would be MyEnum(expression)

Sent from my moss-covered three-handled family gradunza

On Feb 19, 2017, at 2:52 PM, Daniel Duan <daniel@duan.org <mailto:daniel@duan.org>> wrote:

On Feb 19, 2017, at 11:49 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Feb 18, 2017, at 10:49 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I'm on vacation and don't have time for a full review right now, but I am concerned that wild this proposal would make enums more general and uniform with the rest of the language , they also would become much more awkward for common use cases. I have recently been very pleased that I didn't have to supply labels in switch statements where the label name would simply have matched the name of the variable to be bound. This looks needlessly verbose:

  case .valid(value: let value, resumptionPoint: let resumptionPoint):

I cannot imagine a real life use case where one would have labels in the case and desire to bind associated values to variables having different names than the labels.

I agree with this, but I think it’s an issue we can solve (perhaps as an amendment to this proposal).

First, I think Brent’s idea of introducing an argument label that can be distinct from the “property” name of the case is a good one. I think we should do this. It takes the parallel with function signatures even further.

Second, we should allow the “property” name to be `_`. This would mean no label can be used when matching:

case valid(value _: ValueType, resumptionPoint _: PointType)

Third, I think we should also allow suers to elide the label if they either discard the value with `_` or bind a name that is identical to the label, so we might have:

// declaration:
case valid(externalCasConstructorLabel value: ValueType, externalCaseConstructorLabel resumptionPoint: PointType)

// match ok:
case .valid(let value, let resumptionPoint):

// error, names do not match:
case .valid(let foo, let bar):

// ok, label is used:
case .valid(value: let foo, resumptionPoint: let bar):

This follows the behavior of function signatures very closely. The external label is used to provide context for the argument at the call site (of the case constructor). The internal name is used to bind a name to the value that is used by code that works with the value.

The only exception here is that because the usage site is distant from the case declaration it may wish to use a different name. We allow that, but only if the “internal name” is also used in the pattern. This preserves the ability of a reader of the code to see the name / meaning of the associated value as it was declared by the enum in addition to the name that might make more sense for use in the local context.

Secondly, I can't imagine a case where one would want to use the same case basename and different labels. The very common use case where the types of associated values completely distinguish the case and one would rather not have to supply a case name at all is completely unaddressed. If my quick read is not mistaken, this proposal makes it legal for cases to have different complete names (including base name and labels), but doesn't make it legal to have the same full name (which I would love to be "_" or missing in some cases) with different associated value types. If we were truly following the precedent set by function signatures, wouldn't that be possible too?

+1. I think this makes a lot of sense. It completes the parallel of cases with overloaded functions.

I think anonymous cases are a really good idea. I discuss those quite a bit in the value subtyping manifesto I shared last week (I’d love to hear your thoughts on it if / when you have time to take a look).

How would you propose that values of anonymous cases be constructed and matched? My solution is to allow them to be constructed by implicit conversion from the associated value type to the enum type and matched by a cast pattern. Is that what you have in mind? I would *really* love to see this someday...

I can’t speak for Dave obviously. But I think he was merely proposing “overloaded” form of enum options, in which multiple options may share the compound name but with differently associated types. The name “_” would just be a normal identifier in such scenario. So it would also be the contractor’s function name.

Sent from my moss-covered three-handled family gradunza

On Feb 17, 2017, at 5:26 PM, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org <mailto:swift-evolution-announce@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Thanks. I already planned to do a revision to address these questions, which all came up during the review.

···

On Feb 22, 2017, at 11:27 AM, John McCall <rjmccall@apple.com> wrote:

On Feb 21, 2017, at 4:43 AM, Daniel Duan via swift-evolution <swift-evolution@swift.org> wrote:
My apologies for misunderstanding.

Would it be better to add the anonymous case feature in a separate proposal? It stands alone as a new addition to enum. The intent for this proposal is bringing enum's syntax closure to other part of Swift.

The core team met and talked about SE-0155 today, even though we're not quite done with the review period, and here's where we stand.

SE-0155 is being returned for revision. Consensus appears to be strongly in favor of requiring argument labels (if provided) to be enforced on "call" sites. However, the core team feels that the proposal needs revision in the following ways:
  - Are internal argument names syntactically allowed in a case declaration?
  - Can cases with the same base name be overloaded by argument label? If so, is a pattern match using just the bare name ambiguous or does it match both cases?
  - Can cases with the same name (using the same rule as above) be overloaded by argument type? If so, how are they disambiguated in pattern matches?
  - Do pattern matches require argument labels to be given along with value patterns, e.g. "case .valid(value: let value)", or is there some way to shorten this? If the latter, what are the rules for that?
  - Are you proposing anonymous cases, and if so, what are the language rules for them?
  - The proposal makes a claim about layout efficiency; please either discuss this claim or remove it.

John.

Daniel Duan
Sent from my iPhone

On Feb 21, 2017, at 1:15 AM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

I had not intended for _ to be an ordinary identifier, but as a way of spelling the empty case name. Ambiguous cases, not distinguished by either full name or payload type, would be errors. How to construct anonymous cases? I guess it would be MyEnum(expression)

Sent from my moss-covered three-handled family gradunza

On Feb 19, 2017, at 2:52 PM, Daniel Duan <daniel@duan.org> wrote:

On Feb 19, 2017, at 11:49 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 18, 2017, at 10:49 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

I'm on vacation and don't have time for a full review right now, but I am concerned that wild this proposal would make enums more general and uniform with the rest of the language , they also would become much more awkward for common use cases. I have recently been very pleased that I didn't have to supply labels in switch statements where the label name would simply have matched the name of the variable to be bound. This looks needlessly verbose:

  case .valid(value: let value, resumptionPoint: let resumptionPoint):

I cannot imagine a real life use case where one would have labels in the case and desire to bind associated values to variables having different names than the labels.

I agree with this, but I think it’s an issue we can solve (perhaps as an amendment to this proposal).

First, I think Brent’s idea of introducing an argument label that can be distinct from the “property” name of the case is a good one. I think we should do this. It takes the parallel with function signatures even further.

Second, we should allow the “property” name to be `_`. This would mean no label can be used when matching:

case valid(value _: ValueType, resumptionPoint _: PointType)

Third, I think we should also allow suers to elide the label if they either discard the value with `_` or bind a name that is identical to the label, so we might have:

// declaration:
case valid(externalCasConstructorLabel value: ValueType, externalCaseConstructorLabel resumptionPoint: PointType)

// match ok:
case .valid(let value, let resumptionPoint):

// error, names do not match:
case .valid(let foo, let bar):

// ok, label is used:
case .valid(value: let foo, resumptionPoint: let bar):

This follows the behavior of function signatures very closely. The external label is used to provide context for the argument at the call site (of the case constructor). The internal name is used to bind a name to the value that is used by code that works with the value.

The only exception here is that because the usage site is distant from the case declaration it may wish to use a different name. We allow that, but only if the “internal name” is also used in the pattern. This preserves the ability of a reader of the code to see the name / meaning of the associated value as it was declared by the enum in addition to the name that might make more sense for use in the local context.

Secondly, I can't imagine a case where one would want to use the same case basename and different labels. The very common use case where the types of associated values completely distinguish the case and one would rather not have to supply a case name at all is completely unaddressed. If my quick read is not mistaken, this proposal makes it legal for cases to have different complete names (including base name and labels), but doesn't make it legal to have the same full name (which I would love to be "_" or missing in some cases) with different associated value types. If we were truly following the precedent set by function signatures, wouldn't that be possible too?

+1. I think this makes a lot of sense. It completes the parallel of cases with overloaded functions.

I think anonymous cases are a really good idea. I discuss those quite a bit in the value subtyping manifesto I shared last week (I’d love to hear your thoughts on it if / when you have time to take a look).

How would you propose that values of anonymous cases be constructed and matched? My solution is to allow them to be constructed by implicit conversion from the associated value type to the enum type and matched by a cast pattern. Is that what you have in mind? I would *really* love to see this someday...

I can’t speak for Dave obviously. But I think he was merely proposing “overloaded” form of enum options, in which multiple options may share the compound name but with differently associated types. The name “_” would just be a normal identifier in such scenario. So it would also be the contractor’s function name.

Sent from my moss-covered three-handled family gradunza

On Feb 17, 2017, at 5:26 PM, John McCall <rjmccall@apple.com> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

My apologies for misunderstanding.

Would it be better to add the anonymous case feature in a separate proposal? It stands alone as a new addition to enum. The intent for this proposal is bringing enum's syntax closure to other part of Swift.

The core team met and talked about SE-0155 today, even though we're not quite done with the review period, and here's where we stand.

SE-0155 is being returned for revision. Consensus appears to be strongly in favor of requiring argument labels (if provided) to be enforced on "call" sites.

Does this mean pattern matches as well? That adds a lot of verbosity for no gain.

Russ

···

On Feb 22, 2017, at 11:27 AM, John McCall via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 21, 2017, at 4:43 AM, Daniel Duan via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

However, the core team feels that the proposal needs revision in the following ways:
  - Are internal argument names syntactically allowed in a case declaration?
  - Can cases with the same base name be overloaded by argument label? If so, is a pattern match using just the bare name ambiguous or does it match both cases?
  - Can cases with the same name (using the same rule as above) be overloaded by argument type? If so, how are they disambiguated in pattern matches?
  - Do pattern matches require argument labels to be given along with value patterns, e.g. "case .valid(value: let value)", or is there some way to shorten this? If the latter, what are the rules for that?
  - Are you proposing anonymous cases, and if so, what are the language rules for them?
  - The proposal makes a claim about layout efficiency; please either discuss this claim or remove it.

John.

Daniel Duan
Sent from my iPhone

On Feb 21, 2017, at 1:15 AM, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I had not intended for _ to be an ordinary identifier, but as a way of spelling the empty case name. Ambiguous cases, not distinguished by either full name or payload type, would be errors. How to construct anonymous cases? I guess it would be MyEnum(expression)

Sent from my moss-covered three-handled family gradunza

On Feb 19, 2017, at 2:52 PM, Daniel Duan <daniel@duan.org <mailto:daniel@duan.org>> wrote:

On Feb 19, 2017, at 11:49 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Feb 18, 2017, at 10:49 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I'm on vacation and don't have time for a full review right now, but I am concerned that wild this proposal would make enums more general and uniform with the rest of the language , they also would become much more awkward for common use cases. I have recently been very pleased that I didn't have to supply labels in switch statements where the label name would simply have matched the name of the variable to be bound. This looks needlessly verbose:

  case .valid(value: let value, resumptionPoint: let resumptionPoint):

I cannot imagine a real life use case where one would have labels in the case and desire to bind associated values to variables having different names than the labels.

I agree with this, but I think it’s an issue we can solve (perhaps as an amendment to this proposal).

First, I think Brent’s idea of introducing an argument label that can be distinct from the “property” name of the case is a good one. I think we should do this. It takes the parallel with function signatures even further.

Second, we should allow the “property” name to be `_`. This would mean no label can be used when matching:

case valid(value _: ValueType, resumptionPoint _: PointType)

Third, I think we should also allow suers to elide the label if they either discard the value with `_` or bind a name that is identical to the label, so we might have:

// declaration:
case valid(externalCasConstructorLabel value: ValueType, externalCaseConstructorLabel resumptionPoint: PointType)

// match ok:
case .valid(let value, let resumptionPoint):

// error, names do not match:
case .valid(let foo, let bar):

// ok, label is used:
case .valid(value: let foo, resumptionPoint: let bar):

This follows the behavior of function signatures very closely. The external label is used to provide context for the argument at the call site (of the case constructor). The internal name is used to bind a name to the value that is used by code that works with the value.

The only exception here is that because the usage site is distant from the case declaration it may wish to use a different name. We allow that, but only if the “internal name” is also used in the pattern. This preserves the ability of a reader of the code to see the name / meaning of the associated value as it was declared by the enum in addition to the name that might make more sense for use in the local context.

Secondly, I can't imagine a case where one would want to use the same case basename and different labels. The very common use case where the types of associated values completely distinguish the case and one would rather not have to supply a case name at all is completely unaddressed. If my quick read is not mistaken, this proposal makes it legal for cases to have different complete names (including base name and labels), but doesn't make it legal to have the same full name (which I would love to be "_" or missing in some cases) with different associated value types. If we were truly following the precedent set by function signatures, wouldn't that be possible too?

+1. I think this makes a lot of sense. It completes the parallel of cases with overloaded functions.

I think anonymous cases are a really good idea. I discuss those quite a bit in the value subtyping manifesto I shared last week (I’d love to hear your thoughts on it if / when you have time to take a look).

How would you propose that values of anonymous cases be constructed and matched? My solution is to allow them to be constructed by implicit conversion from the associated value type to the enum type and matched by a cast pattern. Is that what you have in mind? I would *really* love to see this someday...

I can’t speak for Dave obviously. But I think he was merely proposing “overloaded” form of enum options, in which multiple options may share the compound name but with differently associated types. The name “_” would just be a normal identifier in such scenario. So it would also be the contractor’s function name.

Sent from my moss-covered three-handled family gradunza

On Feb 17, 2017, at 5:26 PM, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org <mailto:swift-evolution-announce@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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?

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)

Even in this design, there are the choice of forcing name0/name1 to match the “internal” name in declaration and letting users choose whatever they want. There maybe way elegant syntax that I haven’t thought of. Since my experience with languages with pattern matching syntax is pretty much limited to SML and Haskell, I must admit my inadequacy here. Any help is appreciated here!

···

On Feb 22, 2017, at 11:27 AM, John McCall via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 21, 2017, at 4:43 AM, Daniel Duan via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
My apologies for misunderstanding.

Would it be better to add the anonymous case feature in a separate proposal? It stands alone as a new addition to enum. The intent for this proposal is bringing enum's syntax closure to other part of Swift.

The core team met and talked about SE-0155 today, even though we're not quite done with the review period, and here's where we stand.

SE-0155 is being returned for revision. Consensus appears to be strongly in favor of requiring argument labels (if provided) to be enforced on "call" sites. However, the core team feels that the proposal needs revision in the following ways:
  - Are internal argument names syntactically allowed in a case declaration?
  - Can cases with the same base name be overloaded by argument label? If so, is a pattern match using just the bare name ambiguous or does it match both cases?
  - Can cases with the same name (using the same rule as above) be overloaded by argument type? If so, how are they disambiguated in pattern matches?
  - Do pattern matches require argument labels to be given along with value patterns, e.g. "case .valid(value: let value)", or is there some way to shorten this? If the latter, what are the rules for that?
  - Are you proposing anonymous cases, and if so, what are the language rules for them?
  - The proposal makes a claim about layout efficiency; please either discuss this claim or remove it.

John.

Daniel Duan
Sent from my iPhone

On Feb 21, 2017, at 1:15 AM, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I had not intended for _ to be an ordinary identifier, but as a way of spelling the empty case name. Ambiguous cases, not distinguished by either full name or payload type, would be errors. How to construct anonymous cases? I guess it would be MyEnum(expression)

Sent from my moss-covered three-handled family gradunza

On Feb 19, 2017, at 2:52 PM, Daniel Duan <daniel@duan.org <mailto:daniel@duan.org>> wrote:

On Feb 19, 2017, at 11:49 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Feb 18, 2017, at 10:49 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I'm on vacation and don't have time for a full review right now, but I am concerned that wild this proposal would make enums more general and uniform with the rest of the language , they also would become much more awkward for common use cases. I have recently been very pleased that I didn't have to supply labels in switch statements where the label name would simply have matched the name of the variable to be bound. This looks needlessly verbose:

  case .valid(value: let value, resumptionPoint: let resumptionPoint):

I cannot imagine a real life use case where one would have labels in the case and desire to bind associated values to variables having different names than the labels.

I agree with this, but I think it’s an issue we can solve (perhaps as an amendment to this proposal).

First, I think Brent’s idea of introducing an argument label that can be distinct from the “property” name of the case is a good one. I think we should do this. It takes the parallel with function signatures even further.

Second, we should allow the “property” name to be `_`. This would mean no label can be used when matching:

case valid(value _: ValueType, resumptionPoint _: PointType)

Third, I think we should also allow suers to elide the label if they either discard the value with `_` or bind a name that is identical to the label, so we might have:

// declaration:
case valid(externalCasConstructorLabel value: ValueType, externalCaseConstructorLabel resumptionPoint: PointType)

// match ok:
case .valid(let value, let resumptionPoint):

// error, names do not match:
case .valid(let foo, let bar):

// ok, label is used:
case .valid(value: let foo, resumptionPoint: let bar):

This follows the behavior of function signatures very closely. The external label is used to provide context for the argument at the call site (of the case constructor). The internal name is used to bind a name to the value that is used by code that works with the value.

The only exception here is that because the usage site is distant from the case declaration it may wish to use a different name. We allow that, but only if the “internal name” is also used in the pattern. This preserves the ability of a reader of the code to see the name / meaning of the associated value as it was declared by the enum in addition to the name that might make more sense for use in the local context.

Secondly, I can't imagine a case where one would want to use the same case basename and different labels. The very common use case where the types of associated values completely distinguish the case and one would rather not have to supply a case name at all is completely unaddressed. If my quick read is not mistaken, this proposal makes it legal for cases to have different complete names (including base name and labels), but doesn't make it legal to have the same full name (which I would love to be "_" or missing in some cases) with different associated value types. If we were truly following the precedent set by function signatures, wouldn't that be possible too?

+1. I think this makes a lot of sense. It completes the parallel of cases with overloaded functions.

I think anonymous cases are a really good idea. I discuss those quite a bit in the value subtyping manifesto I shared last week (I’d love to hear your thoughts on it if / when you have time to take a look).

How would you propose that values of anonymous cases be constructed and matched? My solution is to allow them to be constructed by implicit conversion from the associated value type to the enum type and matched by a cast pattern. Is that what you have in mind? I would *really* love to see this someday...

I can’t speak for Dave obviously. But I think he was merely proposing “overloaded” form of enum options, in which multiple options may share the compound name but with differently associated types. The name “_” would just be a normal identifier in such scenario. So it would also be the contractor’s function name.

Sent from my moss-covered three-handled family gradunza

On Feb 17, 2017, at 5:26 PM, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org <mailto:swift-evolution-announce@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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?

This is what I suggested. I think of it like this: the case includes a static factory method that produces values. We obviously want the external label here. The pattern is like matching a labeled tuple. When we think of the cases as a labeled tuple (or synthesized struct in the case-as-subtype world) it is clear (to me at least) that we want to use the internal name. To avoid the noise, I suggest allowing patterns to elide the label if they bind to an identical name, which is often what they will do.

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)

We don't need new syntax for this. Cast patterns in the associated value slots should work just fine:

case let .baseName(name0 as Type0, name1 as Type1)

Here, `name0` and `name1` are the internal names of the pattern. If the pattern had different internal names the label must be used:

case let .baseName(internalName1: name0 as Type0, internalName2: name1 as Type1)

Note: the syntactic sugar of eliding the label should also be allowed in cases that don't don't distinguish the internal and external names.

···

Sent from my iPad

On Feb 24, 2017, at 11:26 PM, Daniel Duan via swift-evolution <swift-evolution@swift.org> wrote:

Even in this design, there are the choice of forcing name0/name1 to match the “internal” name in declaration and letting users choose whatever they want. There maybe way elegant syntax that I haven’t thought of. Since my experience with languages with pattern matching syntax is pretty much limited to SML and Haskell, I must admit my inadequacy here. Any help is appreciated here!

On Feb 22, 2017, at 11:27 AM, John McCall via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 21, 2017, at 4:43 AM, Daniel Duan via swift-evolution <swift-evolution@swift.org> wrote:
My apologies for misunderstanding.

Would it be better to add the anonymous case feature in a separate proposal? It stands alone as a new addition to enum. The intent for this proposal is bringing enum's syntax closure to other part of Swift.

The core team met and talked about SE-0155 today, even though we're not quite done with the review period, and here's where we stand.

SE-0155 is being returned for revision. Consensus appears to be strongly in favor of requiring argument labels (if provided) to be enforced on "call" sites. However, the core team feels that the proposal needs revision in the following ways:
  - Are internal argument names syntactically allowed in a case declaration?
  - Can cases with the same base name be overloaded by argument label? If so, is a pattern match using just the bare name ambiguous or does it match both cases?
  - Can cases with the same name (using the same rule as above) be overloaded by argument type? If so, how are they disambiguated in pattern matches?
  - Do pattern matches require argument labels to be given along with value patterns, e.g. "case .valid(value: let value)", or is there some way to shorten this? If the latter, what are the rules for that?
  - Are you proposing anonymous cases, and if so, what are the language rules for them?
  - The proposal makes a claim about layout efficiency; please either discuss this claim or remove it.

John.

Daniel Duan
Sent from my iPhone

On Feb 21, 2017, at 1:15 AM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

I had not intended for _ to be an ordinary identifier, but as a way of spelling the empty case name. Ambiguous cases, not distinguished by either full name or payload type, would be errors. How to construct anonymous cases? I guess it would be MyEnum(expression)

Sent from my moss-covered three-handled family gradunza

On Feb 19, 2017, at 2:52 PM, Daniel Duan <daniel@duan.org> wrote:

On Feb 19, 2017, at 11:49 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 18, 2017, at 10:49 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

I'm on vacation and don't have time for a full review right now, but I am concerned that wild this proposal would make enums more general and uniform with the rest of the language , they also would become much more awkward for common use cases. I have recently been very pleased that I didn't have to supply labels in switch statements where the label name would simply have matched the name of the variable to be bound. This looks needlessly verbose:

  case .valid(value: let value, resumptionPoint: let resumptionPoint):

I cannot imagine a real life use case where one would have labels in the case and desire to bind associated values to variables having different names than the labels.

I agree with this, but I think it’s an issue we can solve (perhaps as an amendment to this proposal).

First, I think Brent’s idea of introducing an argument label that can be distinct from the “property” name of the case is a good one. I think we should do this. It takes the parallel with function signatures even further.

Second, we should allow the “property” name to be `_`. This would mean no label can be used when matching:

case valid(value _: ValueType, resumptionPoint _: PointType)

Third, I think we should also allow suers to elide the label if they either discard the value with `_` or bind a name that is identical to the label, so we might have:

// declaration:
case valid(externalCasConstructorLabel value: ValueType, externalCaseConstructorLabel resumptionPoint: PointType)

// match ok:
case .valid(let value, let resumptionPoint):

// error, names do not match:
case .valid(let foo, let bar):

// ok, label is used:
case .valid(value: let foo, resumptionPoint: let bar):

This follows the behavior of function signatures very closely. The external label is used to provide context for the argument at the call site (of the case constructor). The internal name is used to bind a name to the value that is used by code that works with the value.

The only exception here is that because the usage site is distant from the case declaration it may wish to use a different name. We allow that, but only if the “internal name” is also used in the pattern. This preserves the ability of a reader of the code to see the name / meaning of the associated value as it was declared by the enum in addition to the name that might make more sense for use in the local context.

Secondly, I can't imagine a case where one would want to use the same case basename and different labels. The very common use case where the types of associated values completely distinguish the case and one would rather not have to supply a case name at all is completely unaddressed. If my quick read is not mistaken, this proposal makes it legal for cases to have different complete names (including base name and labels), but doesn't make it legal to have the same full name (which I would love to be "_" or missing in some cases) with different associated value types. If we were truly following the precedent set by function signatures, wouldn't that be possible too?

+1. I think this makes a lot of sense. It completes the parallel of cases with overloaded functions.

I think anonymous cases are a really good idea. I discuss those quite a bit in the value subtyping manifesto I shared last week (I’d love to hear your thoughts on it if / when you have time to take a look).

How would you propose that values of anonymous cases be constructed and matched? My solution is to allow them to be constructed by implicit conversion from the associated value type to the enum type and matched by a cast pattern. Is that what you have in mind? I would *really* love to see this someday...

I can’t speak for Dave obviously. But I think he was merely proposing “overloaded” form of enum options, in which multiple options may share the compound name but with differently associated types. The name “_” would just be a normal identifier in such scenario. So it would also be the contractor’s function name.

Sent from my moss-covered three-handled family gradunza

On Feb 17, 2017, at 5:26 PM, John McCall <rjmccall@apple.com> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

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"? 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:)`.

-Joe

···

On Feb 24, 2017, at 9:26 PM, Daniel Duan <daniel@duan.org> wrote:

Sent from my iPad

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?

This is what I suggested. I think of it like this: the case includes a static factory method that produces values. We obviously want the external label here. The pattern is like matching a labeled tuple. When we think of the cases as a labeled tuple (or synthesized struct in the case-as-subtype world) it is clear (to me at least) that we want to use the internal name. To avoid the noise, I suggest allowing patterns to elide the label if they bind to an identical name, which is often what they will do.

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)

We don't need new syntax for this. Cast patterns in the associated value slots should work just fine:

case let .baseName(name0 as Type0, name1 as Type1)

Here, `name0` and `name1` are the internal names of the pattern. If the pattern had different internal names the label must be used:

case let .baseName(internalName1: name0 as Type0, internalName2: name1 as Type1)

Note: the syntactic sugar of eliding the label should also be allowed in cases that don't don't distinguish the internal and external names.

Nice!

···

On Feb 25, 2017, at 6:13 AM, Matthew Johnson <matthew@anandabits.com> wrote:
On Feb 24, 2017, at 11:26 PM, Daniel Duan via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Even in this design, there are the choice of forcing name0/name1 to match the “internal” name in declaration and letting users choose whatever they want. There maybe way elegant syntax that I haven’t thought of. Since my experience with languages with pattern matching syntax is pretty much limited to SML and Haskell, I must admit my inadequacy here. Any help is appreciated here!

On Feb 22, 2017, at 11:27 AM, John McCall via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Feb 21, 2017, at 4:43 AM, Daniel Duan via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
My apologies for misunderstanding.

Would it be better to add the anonymous case feature in a separate proposal? It stands alone as a new addition to enum. The intent for this proposal is bringing enum's syntax closure to other part of Swift.

The core team met and talked about SE-0155 today, even though we're not quite done with the review period, and here's where we stand.

SE-0155 is being returned for revision. Consensus appears to be strongly in favor of requiring argument labels (if provided) to be enforced on "call" sites. However, the core team feels that the proposal needs revision in the following ways:
  - Are internal argument names syntactically allowed in a case declaration?
  - Can cases with the same base name be overloaded by argument label? If so, is a pattern match using just the bare name ambiguous or does it match both cases?
  - Can cases with the same name (using the same rule as above) be overloaded by argument type? If so, how are they disambiguated in pattern matches?
  - Do pattern matches require argument labels to be given along with value patterns, e.g. "case .valid(value: let value)", or is there some way to shorten this? If the latter, what are the rules for that?
  - Are you proposing anonymous cases, and if so, what are the language rules for them?
  - The proposal makes a claim about layout efficiency; please either discuss this claim or remove it.

John.

Daniel Duan
Sent from my iPhone

On Feb 21, 2017, at 1:15 AM, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I had not intended for _ to be an ordinary identifier, but as a way of spelling the empty case name. Ambiguous cases, not distinguished by either full name or payload type, would be errors. How to construct anonymous cases? I guess it would be MyEnum(expression)

Sent from my moss-covered three-handled family gradunza

On Feb 19, 2017, at 2:52 PM, Daniel Duan <daniel@duan.org <mailto:daniel@duan.org>> wrote:

On Feb 19, 2017, at 11:49 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Feb 18, 2017, at 10:49 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I'm on vacation and don't have time for a full review right now, but I am concerned that wild this proposal would make enums more general and uniform with the rest of the language , they also would become much more awkward for common use cases. I have recently been very pleased that I didn't have to supply labels in switch statements where the label name would simply have matched the name of the variable to be bound. This looks needlessly verbose:

  case .valid(value: let value, resumptionPoint: let resumptionPoint):

I cannot imagine a real life use case where one would have labels in the case and desire to bind associated values to variables having different names than the labels.

I agree with this, but I think it’s an issue we can solve (perhaps as an amendment to this proposal).

First, I think Brent’s idea of introducing an argument label that can be distinct from the “property” name of the case is a good one. I think we should do this. It takes the parallel with function signatures even further.

Second, we should allow the “property” name to be `_`. This would mean no label can be used when matching:

case valid(value _: ValueType, resumptionPoint _: PointType)

Third, I think we should also allow suers to elide the label if they either discard the value with `_` or bind a name that is identical to the label, so we might have:

// declaration:
case valid(externalCasConstructorLabel value: ValueType, externalCaseConstructorLabel resumptionPoint: PointType)

// match ok:
case .valid(let value, let resumptionPoint):

// error, names do not match:
case .valid(let foo, let bar):

// ok, label is used:
case .valid(value: let foo, resumptionPoint: let bar):

This follows the behavior of function signatures very closely. The external label is used to provide context for the argument at the call site (of the case constructor). The internal name is used to bind a name to the value that is used by code that works with the value.

The only exception here is that because the usage site is distant from the case declaration it may wish to use a different name. We allow that, but only if the “internal name” is also used in the pattern. This preserves the ability of a reader of the code to see the name / meaning of the associated value as it was declared by the enum in addition to the name that might make more sense for use in the local context.

Secondly, I can't imagine a case where one would want to use the same case basename and different labels. The very common use case where the types of associated values completely distinguish the case and one would rather not have to supply a case name at all is completely unaddressed. If my quick read is not mistaken, this proposal makes it legal for cases to have different complete names (including base name and labels), but doesn't make it legal to have the same full name (which I would love to be "_" or missing in some cases) with different associated value types. If we were truly following the precedent set by function signatures, wouldn't that be possible too?

+1. I think this makes a lot of sense. It completes the parallel of cases with overloaded functions.

I think anonymous cases are a really good idea. I discuss those quite a bit in the value subtyping manifesto I shared last week (I’d love to hear your thoughts on it if / when you have time to take a look).

How would you propose that values of anonymous cases be constructed and matched? My solution is to allow them to be constructed by implicit conversion from the associated value type to the enum type and matched by a cast pattern. Is that what you have in mind? I would *really* love to see this someday...

I can’t speak for Dave obviously. But I think he was merely proposing “overloaded” form of enum options, in which multiple options may share the compound name but with differently associated types. The name “_” would just be a normal identifier in such scenario. So it would also be the contractor’s function name.

Sent from my moss-covered three-handled family gradunza

On Feb 17, 2017, at 5:26 PM, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

Hello Swift community,

The review of "SE-0155: Normalize Enum Case Representation" begins now and runs through next Friday, February 26th. The proposal is available here:
  https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at
  https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md

  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

John McCall
Review Manager
_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org <mailto:swift-evolution-announce@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

Daniel Duan

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.

Interesting.

I was reaching for any possible use cases there. The theory is these names would be how one refers to a "property" of the case in, say, extension methods for the case.

But yeah, I considered this internal name thing during first draft and decided that they weren't necessary :woman_shrugging:

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"? I think we should have a consistent naming model where the latter is never considered overloading.

Same name different type is what "overloading" was meant here. "Same base name" is already in the first revision and wouldn't fit in this "open question" discussion.

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:)`.

Good idea.

···

Sent from my iPhone

On Feb 27, 2017, at 10:00 AM, Joe Groff <jgroff@apple.com> wrote:

On Feb 24, 2017, at 9:26 PM, Daniel Duan <daniel@duan.org> wrote:

-Joe

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)
}

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"? 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:)`.

I agree as far as names go, but I think this was talking about same name different types. I believe the overloading sub-topic began with Dave A's comments about anonymous cases for enums where the associated value is all that matters.

My suggestion was to allow overloading on types and use cast patterns to disambiguate when matching. This increases consistency with functions and enables that important use case.

···

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 <daniel@duan.org> wrote:

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

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

···

on Mon Feb 27 2017, Joe Groff <jgroff-AT-apple.com> wrote:

On Feb 24, 2017, at 9:26 PM, Daniel Duan <daniel@duan.org> wrote:

--
-Dave

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

···

On Feb 27, 2017, at 10:39 AM, Matthew Johnson <matthew@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 <daniel@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)
}

Sent from my iPad

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.

···

On Feb 27, 2017, at 12:46 PM, Joe Groff <jgroff@apple.com> wrote:

On Feb 27, 2017, at 10:39 AM, Matthew Johnson <matthew@anandabits.com> wrote:

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 <daniel@duan.org> wrote:

-Joe