[swift-evolution] [draft] Compound Names For Enum Cases

Xiaodi Wu xiaodi.wu at gmail.com
Tue Jan 24 17:55:12 CST 2017


Yes, but *this* proposal is precisely to make the label part of the name.


On Tue, Jan 24, 2017 at 17:51 Christopher Kornher <ckornher at me.com> wrote:

> On Jan 24, 2017, at 4:24 PM, Xiaodi Wu via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> I'm now confused who is arguing for what. Enums cases cannot have the same
> name. As far as I'm aware, this proposal does not seek to change that. Each
> case must still be unique. It only changes whether labels are regarded as
> part of the name or part of the associated type.
>
>
> Labels are currently neither part of the name nor part of the associated
> type. See my example (it runs in the playground in Xcode 8.2.1).
>
> Forgive any lack of precise terminology:  Labels for enums with associated
> values are currently only used to create a "function signature" for
> constructing values for the enum. They are ignored in all other uses of the
> enum AFAIK.
>
> My proposal is a way to allow multiple cases with the same name without
> breaking existing code. It has the benefit of giving enums a richer
> meaning, in simple English:
>
> Here is an example of a way to handle this currently and what it would
> become:
>
> // Runs now
> enum MultipleTypes {
>     case anInt( value: Int )
>     case aString( value: String )
> }
>
> enum E {
>     case a( a: MultipleTypes )
> }
>
> let theCurrentWay = E.a( a: .aString( value: "str") )
>
> switch theCurrentWay {
> case .a( let x ) :
>     switch x {
>     case .anInt( let x ) :
>         break
>
>     case .aString( let x ) :
>         break
>     }
> }
>
> // Proposed:
>
> /*
> enum theNewWay {
>      case a( value: Int ) :
>      case a( value: String ) :
> }
>
> switch theCurrentWay {
> case .a( let x: Int ) :
>     break
>
> case .a( let x: String ) :
>     break
> }
> */
>
>
>
>
> On Tue, Jan 24, 2017 at 17:16 Christopher Kornher via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> On Jan 24, 2017, at 4:02 PM, Daniel Duan <daniel at duan.org> wrote:
>
>
>
> Daniel Duan
> Sent from my iPhone
>
> On Jan 24, 2017, at 2:53 PM, Daniel Duan via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>
>
> Daniel Duan
> Sent from my iPhone
>
> On Jan 24, 2017, at 2:18 PM, Christopher Kornher via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> I agree that  this rule would be consistent with the handing of Swift
> function signatures, but my proposal is self-consistent and:
>
> 1) It is more powerful, matching on the case name or not as required.
> 2) Is consistent with existing switches that ignore associated values
> 3) Is constant with ignored labels in other Swift constructs (proposed and
> in past versions of Swift, at least)
> 4) Avoids a possible API change for current enums. This is currently legal
> but would not be if the enum case “name” is the entire signature for
> constructing it:
>
> ```
> enum E {
>     case a( a: Int )
>     case b( a: Int )
> }
>
> let anEmum = E.a( a: 4 )
>
>
> switch anEmum {
> case .a( let x ) :
>     break
> case .b( let x ) :
>     break
> }
>
> switch anEmum {
> case .a( let y ) :
>     break
>
> case .b( let y ) :
>     break
> }
> ```
> So is this proposal worth creating a breaking change? I don’t think so.
>  it would be possible to ignore the associated parameter name, but not the
> type, but that would further confuse case matching, I believe.
>
> I personally don’t see much purpose in having two enum cases with the same
> name if they are always treated as distinct and there is no way to reason
> on the case name.
>
>
> Would you say the same for functions? Our opinions differ in what
> constitute a "name". In Swift, function names include parameters. Each enum
> case declares a function that creates a enum value. That's why it's *more*
> consistent for enum to have a similar definition of "name".
>
> As for pattern matching, number of patterns the number of cases being
> matched have a many-to-one relationships. This is true in Swift and many
>
>
> (Ah, accidentally sent it on my iPhone. My apologies.)
>
> … other languages. What you are proposing complicates the rules by making
> this untrue. We'd have to special-case this feature in our pattern matching
> algorithm.
>
>
> I am not proposing a breaking change. I believe that it is the best way to
> handle “overloading” enum names without breaking existing code. I don’t
> believe that this proposal changes any existing logic or rules.
>
> The use of the terms "name” and "signature" is well established in many
> languages. e.g.: https://en.wikipedia.org/wiki/Type_signature I am trying
> to use the terms in this context.
>
> Sharing a function name (with different signatures)  is an aid to
> understanding the purpose of functions and is part of many languages. I do
> not believe that extending the concept to enums is worth the cost,
> especially since it will break existing Swift code.
>
> You are proposing a source breaking change and I do not agree that is is
> an improvement. What is the benefit of this change?
>
>
>
> If they are always distinct, then requiring different names eliminates
> unnecessary cognitive load. There is a good reason for functions to have
> the same “name” and different signatures, and there are precedents in many
> languages.
>
> You may disagree, but I believe that enums exist to support reasoning on
> distinct cases and that muddying that by treating the associated value as
> part of the “signature" increases the language “surface area” while adding
> no tangible benefit.
>
>
> On Jan 24, 2017, at 2:23 PM, Matthew Johnson via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>
> On Jan 24, 2017, at 3:10 PM, Christopher Kornher via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> Your example is only has only one case, which is not typical. Perhaps I am
> missing something, but the only reason that I can imagine for having a case
> with multiple ways to “construct” it is to have all variants of the case to
> match. If you don’t want them to match, use a different case name.
>
>
> It sounds like you are missing something.  The `bar(a:)` and `bar(b:)` are
> the full case names.  These are *not* the same case.  The `bar` shorthand
> is allowed when there is no ambiguity, however for an enum with both
> `bar(a:)` and `bar(b:)` there *is* ambiguity and therefore the `bar`
> shorthand is not allowed.  The programmer is required to spell out the full
> name of the case they wish to match.
>
>
>
> It would still be possible to match on the different types of bar when
> needed:
>
> ```
> enum Foo {
>     case bar(a: Int)
>     case bar(b: String)
>     case notAbar
> }
>
>
>  switch aFoo {
>     case .bar( let a: Int) : // matches Ints only
> ...
>
>     case .bar( let b: String) : // matches Strings only
>        ...
> }
>
> switch aFoo {
>     case .bar :  // Matches both  cases and that is a good thing
>>
>     case notAbar:
> ….
> }
>
> ```
>
> On Jan 24, 2017, at 5:27 AM, Xiaodi Wu via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> I would imagine it would be logical to have it work just like it does now
> with functions. If case bar is distinct, then that should still work, but
> if bar is "overloaded," then case bar should be invalid for ambiguity.
> Seems fine to me, shouldn't break any existing code and therefore we don't
> lose anything.
>
>
> On Tue, Jan 24, 2017 at 01:13 David Hart via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>
>
> On 24 Jan 2017, at 00:52, Joe Groff via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> We're not terribly principled about this right now with non-pattern
> declaration references. You can still reference an unapplied function by
> its base name alone without its labels, if it's unambiguous:
>
> func foo(x: Int, y: Int) {}
>
> let foo_x_y: (Int, Int) -> () = foo
>
>
> so it'd be consistent to continue to allow the same in pattern references.
>
>
> WRT ambiguity, do we loose the ability to pattern match on the naked case
> name when two cases share the same base name?
>
> enum Foo {
>     case bar(a: Int)
>     case bar(b: String)
> }
>
> switch aFoo {
>     case .bar: // matches both cases
>         break
> }
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170124/79741441/attachment.html>


More information about the swift-evolution mailing list