# Allowing non-binding pattern matching as a Bool expression?

**URL:** <https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294>\
**Category:** Discussion\
**Created:** [December 8, 2015, 4:05am UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294 "2015-12-08T04:05:51Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alex\_Lew](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@Alex\_Lew](https://forums.swift.org/u/Alex_Lew)\
**Post date:** [December 8, 2015, 4:05am UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/1 "2015-12-08T04:05:51Z")

</div>

Hi all,

Curious to hear thoughts on allowing non-binding pattern matches to be used  
as boolean values outside of an if, guard, for...in, while, switch, etc.  
Something like:

enum List\<T\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Empty  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indirect case Link(T, List\<T\>)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func isEmpty() -\> Bool {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return case .Empty = self  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
}

It gets rid of some boilerplate (explicit return true and return false),  
and seems intuitive that it would work given that you can already do

if case .Empty = self {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
} else {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
}

I haven't really thought through all the implications here, so there's  
probably something I'm missing. It also may be useful only in such limited  
situations that it's not worth the trouble to add.

-Alex

---

<div class="post-metadata">

**Author:** ![Andrew](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/andrew/32/949_2.png) [@Andrew](https://forums.swift.org/u/Andrew)\
**Post date:** [December 8, 2015, 10:31am UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/2 "2015-12-08T10:31:33Z")

</div>

I've wanted similar too. Although it may be better, instead of Bool, to  
have it as an optional tuple, the reason I suggest this is so that you can  
get the associated type. For example:

case let .Link(value,link) = self

So your example could be written:

func isEmpty() -\> Bool {  
&nbsp;&nbsp;&nbsp;&nbsp;return (case .Empty = self) != nil  
}

However I'm not sure about this syntax, perhaps something like this:

func isEmpty() -\> Bool {  
&nbsp;&nbsp;&nbsp;&nbsp;return self is case .Empty  
}

Alternatively if you want the value you could do:

let (value, link) = self as? case .Link

> **···**
>
> On Tue, Dec 8, 2015 at 3:05 PM, Alex Lew via swift-evolution \< swift-evolution@swift.org\> wrote:
> 
> > Hi all,
> > 
> > Curious to hear thoughts on allowing non-binding pattern matches to be  
> > used as boolean values outside of an if, guard, for...in, while, switch,  
> > etc. Something like:
> > 
> > enum List\<T\> {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Empty  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indirect case Link(T, List\<T\>)
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func isEmpty() -\> Bool {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return case .Empty = self  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > }
> > 
> > It gets rid of some boilerplate (explicit return true and return false),  
> > and seems intuitive that it would work given that you can already do
> > 
> > if case .Empty = self {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
> > } else {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > }
> > 
> > I haven't really thought through all the implications here, so there's  
> > probably something I'm missing. It also may be useful only in such limited  
> > situations that it's not worth the trouble to add.
> > 
> > -Alex
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner](https://avatars.discourse-cdn.com/v4/letter/c/bc8723/32.png) [@Chris\_Lattner](https://forums.swift.org/u/Chris_Lattner)\
**Post date:** [December 9, 2015, 5:45am UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/3 "2015-12-09T05:45:18Z")

</div>

I agree with you that this is a problem that we should solve, but I think it could be solved in a different way. Imagine if:

enum Foo {  
&nbsp;&nbsp;case X(a : Float), Y, Z(a : Int)  
}

automatically synthesized these members (the exact names are just a strawman proposal, not serious :-)

extension Foo {  
&nbsp;&nbsp;func isX() -\> Float? {…}  
&nbsp;&nbsp;func isY() -\> Bool {…}  
&nbsp;&nbsp;func isZ() -\> Int? {…}  
}

This would tie into all of the mechanics we have for dealing with optionals, e.g. if/let and ??

-Chris

> **···**
>
> > On Dec 7, 2015, at 8:05 PM, Alex Lew via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > Hi all,
> > 
> > Curious to hear thoughts on allowing non-binding pattern matches to be used as boolean values outside of an if, guard, for...in, while, switch, etc. Something like:
> > 
> > enum List\<T\> {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Empty  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indirect case Link(T, List\<T\>)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func isEmpty() -\> Bool {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return case .Empty = self  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > }

---

<div class="post-metadata">

**Author:** ![Kevin\_Lundberg](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kevin_lundberg/32/353_2.png) [@Kevin\_Lundberg](https://forums.swift.org/u/Kevin_Lundberg)\
**Post date:** [December 8, 2015, 2:17pm UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/4 "2015-12-08T14:17:54Z")

</div>

Adding additional behavior to is/as that doesn't deal directly with types seems confusing to me. Those operators I feel would be best left for checking and casting types, despite how much nicer this reads.

> **···**
>
> --  
> Kevin Lundberg
> 
> > On Dec 8, 2015, at 5:31 AM, Andrew Bennett via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > I've wanted similar too. Although it may be better, instead of Bool, to have it as an optional tuple, the reason I suggest this is so that you can get the associated type. For example:
> > 
> > case let .Link(value,link) = self
> > 
> > So your example could be written:
> > 
> > func isEmpty() -\> Bool {  
> > &nbsp;&nbsp;&nbsp;&nbsp;return (case .Empty = self) != nil  
> > }
> > 
> > However I'm not sure about this syntax, perhaps something like this:
> > 
> > func isEmpty() -\> Bool {  
> > &nbsp;&nbsp;&nbsp;&nbsp;return self is case .Empty  
> > }
> > 
> > Alternatively if you want the value you could do:
> > 
> > let (value, link) = self as? case .Link
> > 
> > > On Tue, Dec 8, 2015 at 3:05 PM, Alex Lew via swift-evolution \<swift-evolution@swift.org\> wrote:  
> > > Hi all,
> > > 
> > > Curious to hear thoughts on allowing non-binding pattern matches to be used as boolean values outside of an if, guard, for...in, while, switch, etc. Something like:
> > > 
> > > enum List\<T\> {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Empty  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indirect case Link(T, List\<T\>)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func isEmpty() -\> Bool {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return case .Empty = self  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > > }
> > > 
> > > It gets rid of some boilerplate (explicit return true and return false), and seems intuitive that it would work given that you can already do
> > > 
> > > if case .Empty = self {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
> > > } else {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > > }
> > > 
> > > I haven't really thought through all the implications here, so there's probably something I'm missing. It also may be useful only in such limited situations that it's not worth the trouble to add.
> > > 
> > > -Alex
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Alex\_Lew](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@Alex\_Lew](https://forums.swift.org/u/Alex_Lew)\
**Post date:** [December 9, 2015, 6:29am UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/5 "2015-12-09T06:29:56Z")

</div>

Thanks, Chris, for all the time you're putting into responding to these  
proposals (and the kindness with which you're responding!). I really like  
that solution.

Brainstorming some names for the auto-generated functions:

1. If a case has no associated values, isX() -\> Bool is generated, where X  
is the case name.  
&nbsp;&nbsp;&nbsp;&nbsp;If a case has an associated value of type T, asX() -\> T? is generated,  
where X is the case name.  
&nbsp;&nbsp;&nbsp;&nbsp;This mirrors is/as? operators, which return Bool / Optional  
respectively.  
2. projectX() -\> Bool / projectX() -\> T?  
3. isX() -\> Bool / xValue() -\> T?

Another option (probably the wrong option, but it's worth putting out  
there) is that instead of returning Bool in the no-associated-value case,  
we return ()?. This would make me feel better about using the same naming  
convention (asX(), projectX(), xValue(), etc.) for each case, and would  
allow for != nil checks on all cases. But it would probably be a little  
confusing for newcomers to the language.

One (potentially misguided) question. I noticed in proposal 0002 (on  
removing function currying) that there are "plans to move away from the  
arguments-are-a-single-tuple model" in the near future. Would this also  
affect associated values of enums? That is, might

case Dog(name: String, age: Int, breed: String)

one day not have the semantics of a single associated value of type (name:  
String, age: Int, breed: String)? Or is the de-ML-ification planned only  
for function arguments?

-Alex

> **···**
>
> On Wed, Dec 9, 2015 at 12:45 AM, Chris Lattner \<clattner@apple.com\> wrote:
> 
> > \> On Dec 7, 2015, at 8:05 PM, Alex Lew via swift-evolution \< \> swift-evolution@swift.org\> wrote:  
> > \>  
> > \> Hi all,  
> > \>  
> > \> Curious to hear thoughts on allowing non-binding pattern matches to be  
> > used as boolean values outside of an if, guard, for...in, while, switch,  
> > etc. Something like:  
> > \>  
> > \> enum List\<T\> {  
> > \> case Empty  
> > \> indirect case Link(T, List\<T\>)  
> > \>  
> > \> func isEmpty() -\> Bool {  
> > \> return case .Empty = self  
> > \> }  
> > \> }
> > 
> > I agree with you that this is a problem that we should solve, but I think  
> > it could be solved in a different way. Imagine if:
> > 
> > enum Foo {  
> > &nbsp;&nbsp;case X(a : Float), Y, Z(a : Int)  
> > }
> > 
> > automatically synthesized these members (the exact names are just a  
> > strawman proposal, not serious :-)
> > 
> > extension Foo {  
> > &nbsp;&nbsp;func isX() -\> Float? {…}  
> > &nbsp;&nbsp;func isY() -\> Bool {…}  
> > &nbsp;&nbsp;func isZ() -\> Int? {…}  
> > }
> > 
> > This would tie into all of the mechanics we have for dealing with  
> > optionals, e.g. if/let and ??
> > 
> > -Chris

---

<div class="post-metadata">

**Author:** ![thorsten](https://avatars.discourse-cdn.com/v4/letter/t/d2c977/32.png) [@thorsten](https://forums.swift.org/u/thorsten)\
**Post date:** [December 9, 2015, 4:49pm UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/6 "2015-12-09T16:49:49Z")

</div>

I would prefer if no "magic" methods would be generated automatically, but only when marked with @derivestandardmethods (fill in better name here).

As to naming I like the proposal #1 by Alex.

What about enums with more than one associated value?

-Thorsten

> **···**
>
> > Am 09.12.2015 um 07:29 schrieb Alex Lew via swift-evolution \<swift-evolution@swift.org\>:
> > 
> > Thanks, Chris, for all the time you're putting into responding to these proposals (and the kindness with which you're responding!). I really like that solution.
> > 
> > Brainstorming some names for the auto-generated functions:
> > 
> > 1. If a case has no associated values, isX() -\> Bool is generated, where X is the case name.  
> > &nbsp;&nbsp;&nbsp;&nbsp;If a case has an associated value of type T, asX() -\> T? is generated, where X is the case name.  
> > &nbsp;&nbsp;&nbsp;&nbsp;This mirrors is/as? operators, which return Bool / Optional respectively.  
> > 2. projectX() -\> Bool / projectX() -\> T?  
> > 3. isX() -\> Bool / xValue() -\> T?
> > 
> > Another option (probably the wrong option, but it's worth putting out there) is that instead of returning Bool in the no-associated-value case, we return ()?. This would make me feel better about using the same naming convention (asX(), projectX(), xValue(), etc.) for each case, and would allow for != nil checks on all cases. But it would probably be a little confusing for newcomers to the language.
> > 
> > One (potentially misguided) question. I noticed in proposal 0002 (on removing function currying) that there are "plans to move away from the arguments-are-a-single-tuple model" in the near future. Would this also affect associated values of enums? That is, might
> > 
> > case Dog(name: String, age: Int, breed: String)
> > 
> > one day not have the semantics of a single associated value of type (name: String, age: Int, breed: String)? Or is the de-ML-ification planned only for function arguments?
> > 
> > -Alex
> > 
> > > On Wed, Dec 9, 2015 at 12:45 AM, Chris Lattner \<clattner@apple.com\> wrote:
> > > 
> > > \> On Dec 7, 2015, at 8:05 PM, Alex Lew via swift-evolution \<swift-evolution@swift.org\> wrote:  
> > > \>  
> > > \> Hi all,  
> > > \>  
> > > \> Curious to hear thoughts on allowing non-binding pattern matches to be used as boolean values outside of an if, guard, for...in, while, switch, etc. Something like:  
> > > \>  
> > > \> enum List\<T\> {  
> > > \> case Empty  
> > > \> indirect case Link(T, List\<T\>)  
> > > \>  
> > > \> func isEmpty() -\> Bool {  
> > > \> return case .Empty = self  
> > > \> }  
> > > \> }
> > > 
> > > I agree with you that this is a problem that we should solve, but I think it could be solved in a different way. Imagine if:
> > > 
> > > enum Foo {  
> > > &nbsp;&nbsp;case X(a : Float), Y, Z(a : Int)  
> > > }
> > > 
> > > automatically synthesized these members (the exact names are just a strawman proposal, not serious :-)
> > > 
> > > extension Foo {  
> > > &nbsp;&nbsp;func isX() -\> Float? {…}  
> > > &nbsp;&nbsp;func isY() -\> Bool {…}  
> > > &nbsp;&nbsp;func isZ() -\> Int? {…}  
> > > }
> > > 
> > > This would tie into all of the mechanics we have for dealing with optionals, e.g. if/let and ??
> > > 
> > > -Chris
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner](https://avatars.discourse-cdn.com/v4/letter/c/bc8723/32.png) [@Chris\_Lattner](https://forums.swift.org/u/Chris_Lattner)\
**Post date:** [December 11, 2015, 5:36am UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/7 "2015-12-11T05:36:35Z")

</div>

> Thanks, Chris, for all the time you're putting into responding to these proposals (and the kindness with which you're responding!). I really like that solution.

Happy to help.

> Brainstorming some names for the auto-generated functions:
> 
> 1. If a case has no associated values, isX() -\> Bool is generated, where X is the case name.  
> &nbsp;&nbsp;&nbsp;&nbsp;If a case has an associated value of type T, asX() -\> T? is generated, where X is the case name.  
> &nbsp;&nbsp;&nbsp;&nbsp;This mirrors is/as? operators, which return Bool / Optional respectively.  
> 2. projectX() -\> Bool / projectX() -\> T?  
> 3. isX() -\> Bool / xValue() -\> T?

MHO, I like #1 with isX/asX - good idea.

> Another option (probably the wrong option, but it's worth putting out there) is that instead of returning Bool in the no-associated-value case, we return ()?. This would make me feel better about using the same naming convention (asX(), projectX(), xValue(), etc.) for each case, and would allow for != nil checks on all cases. But it would probably be a little confusing for newcomers to the language.

I can see that argument, but I think it would both be surprising/weird but would also be less useful. You’d have to do things like:  
&nbsp;&nbsp;if myEnum.asX() != nil {  
instead of:  
&nbsp;&nbsp;if myEnum.isX() {

Similarly, the ??, if let, and other mechanics that work with optionals wouldn’t be helpful here, since you’d never want to bind the void value.

> One (potentially misguided) question. I noticed in proposal 0002 (on removing function currying) that there are "plans to move away from the arguments-are-a-single-tuple model" in the near future. Would this also affect associated values of enums? That is, might
> 
> case Dog(name: String, age: Int, breed: String)
> 
> one day not have the semantics of a single associated value of type (name: String, age: Int, breed: String)? Or is the de-ML-ification planned only for function arguments?

No, enum cases should retain their argument lists. It is not related.

-Chris

> **···**
>
> On Dec 8, 2015, at 10:29 PM, Alex Lew \<alexl.mail+swift@gmail.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Alex\_Lew](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@Alex\_Lew](https://forums.swift.org/u/Alex_Lew)\
**Post date:** [December 9, 2015, 6:56pm UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/8 "2015-12-09T18:56:16Z")

</div>

Semantically, I believe enums with more than one associated value are  
actually just enums with one associated value, of tuple type.

I'm not convinced it would be bad to do magic function generation, but it's  
worth considering explicit syntax. If we were to use @ compile-time  
attributes, maybe it could be a word before the case -- like @projectable  
or @selectable (or some better name)?

enum List\<T\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@projectable case Empty  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indirect case FirstAndRest(T, List\<T\>)  
}

generates:  
myList.isEmpty() -\> Bool

Another option: some sort of @reflectable attribute on the enum itself.

@reflectable enum Pet {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Cat(name: String, color: String)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Dog(name: String, breed: String)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Bear(name: String, isHibernating: Bool)  
}

And one other option, in a very different direction, that seems weird but  
maybe has its benefits:

What if we exposed an associatedValue computed property of type Any? (It  
would be unit type for cases with no associated value.)

You could then do something like this:

enum Contact {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Person(String) // name  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Business(String) // org name  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case FamilyMember(String) // relation name  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case RecentCall(Int) // a contact from caller id, only store the phone  
number

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func name() -\> String {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return associatedValue as? String ?? "Unknown (\(associatedValue  
as! Int))"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
}

Essentially, it allows you to project out a relatively common associated  
value (in this case a string) without much boilerplate. It's also just one  
thing for the compiler to generate, instead of \*n\*. Not crazy about any of  
these... just brainstorming. It may also be that a concise switch-like  
control flow expression eliminates the need for this.

-Alex

> **···**
>
> On Wed, Dec 9, 2015 at 11:49 AM, thorsten@portableinnovations.de \< thorsten@portableinnovations.de\> wrote:
> 
> > I would prefer if no "magic" methods would be generated automatically, but  
> > only when marked with @derivestandardmethods (fill in better name here).
> > 
> > As to naming I like the proposal #1 by Alex.
> > 
> > What about enums with more than one associated value?
> > 
> > -Thorsten
> > 
> > Am 09.12.2015 um 07:29 schrieb Alex Lew via swift-evolution \< \> swift-evolution@swift.org\>:
> > 
> > Thanks, Chris, for all the time you're putting into responding to these  
> > proposals (and the kindness with which you're responding!). I really like  
> > that solution.
> > 
> > Brainstorming some names for the auto-generated functions:
> > 
> > 1. If a case has no associated values, isX() -\> Bool is generated, where X  
> > is the case name.  
> > &nbsp;&nbsp;&nbsp;&nbsp;If a case has an associated value of type T, asX() -\> T? is generated,  
> > where X is the case name.  
> > &nbsp;&nbsp;&nbsp;&nbsp;This mirrors is/as? operators, which return Bool / Optional  
> > respectively.  
> > 2. projectX() -\> Bool / projectX() -\> T?  
> > 3. isX() -\> Bool / xValue() -\> T?
> > 
> > Another option (probably the wrong option, but it's worth putting out  
> > there) is that instead of returning Bool in the no-associated-value case,  
> > we return ()?. This would make me feel better about using the same naming  
> > convention (asX(), projectX(), xValue(), etc.) for each case, and would  
> > allow for != nil checks on all cases. But it would probably be a little  
> > confusing for newcomers to the language.
> > 
> > One (potentially misguided) question. I noticed in proposal 0002 (on  
> > removing function currying) that there are "plans to move away from the  
> > arguments-are-a-single-tuple model" in the near future. Would this also  
> > affect associated values of enums? That is, might
> > 
> > case Dog(name: String, age: Int, breed: String)
> > 
> > one day not have the semantics of a single associated value of type (name:  
> > String, age: Int, breed: String)? Or is the de-ML-ification planned only  
> > for function arguments?
> > 
> > -Alex
> > 
> > On Wed, Dec 9, 2015 at 12:45 AM, Chris Lattner \<clattner@apple.com\> \> wrote:
> > 
> > > \> On Dec 7, 2015, at 8:05 PM, Alex Lew via swift-evolution \< \>\> swift-evolution@swift.org\> wrote:  
> > > \>  
> > > \> Hi all,  
> > > \>  
> > > \> Curious to hear thoughts on allowing non-binding pattern matches to be  
> > > used as boolean values outside of an if, guard, for...in, while, switch,  
> > > etc. Something like:  
> > > \>  
> > > \> enum List\<T\> {  
> > > \> case Empty  
> > > \> indirect case Link(T, List\<T\>)  
> > > \>  
> > > \> func isEmpty() -\> Bool {  
> > > \> return case .Empty = self  
> > > \> }  
> > > \> }
> > > 
> > > I agree with you that this is a problem that we should solve, but I think  
> > > it could be solved in a different way. Imagine if:
> > > 
> > > enum Foo {  
> > > &nbsp;&nbsp;case X(a : Float), Y, Z(a : Int)  
> > > }
> > > 
> > > automatically synthesized these members (the exact names are just a  
> > > strawman proposal, not serious :-)
> > > 
> > > extension Foo {  
> > > &nbsp;&nbsp;func isX() -\> Float? {…}  
> > > &nbsp;&nbsp;func isY() -\> Bool {…}  
> > > &nbsp;&nbsp;func isZ() -\> Int? {…}  
> > > }
> > > 
> > > This would tie into all of the mechanics we have for dealing with  
> > > optionals, e.g. if/let and ??
> > > 
> > > -Chris
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > Untracked with Trackbuster \<[Your contacts automatically up to date | evercontact](https://trackbuster.com/?sig&gt);

---

<div class="post-metadata">

**Author:** ![Andrew](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/andrew/32/949_2.png) [@Andrew](https://forums.swift.org/u/Andrew)\
**Post date:** [December 9, 2015, 9:00pm UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/9 "2015-12-09T21:00:18Z")

</div>

I really like this solution and perhaps you can also go  
@projectable("empyValue") if the default name is a bad choice. See @obc for  
similar usage.

> **···**
>
> On Thursday, 10 December 2015, Alex Lew via swift-evolution \< swift-evolution@swift.org\> wrote:
> 
> > Semantically, I believe enums with more than one associated value are  
> > actually just enums with one associated value, of tuple type.
> > 
> > I'm not convinced it would be bad to do magic function generation, but  
> > it's worth considering explicit syntax. If we were to use @ compile-time  
> > attributes, maybe it could be a word before the case -- like @projectable  
> > or @selectable (or some better name)?
> > 
> > enum List\<T\> {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@projectable case Empty  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indirect case FirstAndRest(T, List\<T\>)  
> > }
> > 
> > generates:  
> > myList.isEmpty() -\> Bool
> > 
> > Another option: some sort of @reflectable attribute on the enum itself.
> > 
> > @reflectable enum Pet {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Cat(name: String, color: String)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Dog(name: String, breed: String)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Bear(name: String, isHibernating: Bool)  
> > }
> > 
> > And one other option, in a very different direction, that seems weird but  
> > maybe has its benefits:
> > 
> > What if we exposed an associatedValue computed property of type Any? (It  
> > would be unit type for cases with no associated value.)
> > 
> > You could then do something like this:
> > 
> > enum Contact {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Person(String) // name  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Business(String) // org name  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case FamilyMember(String) // relation name  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case RecentCall(Int) // a contact from caller id, only store the  
> > phone number
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func name() -\> String {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return associatedValue as? String ?? "Unknown (\(associatedValue  
> > as! Int))"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > }
> > 
> > Essentially, it allows you to project out a relatively common associated  
> > value (in this case a string) without much boilerplate. It's also just one  
> > thing for the compiler to generate, instead of \*n\*. Not crazy about any  
> > of these... just brainstorming. It may also be that a concise switch-like  
> > control flow expression eliminates the need for this.
> > 
> > -Alex
> > 
> > On Wed, Dec 9, 2015 at 11:49 AM, thorsten@portableinnovations.de \> \<javascript:\_e(%7B%7D,'cvml','thorsten@portableinnovations.de');\> \< \> thorsten@portableinnovations.de \> \<javascript:\_e(%7B%7D,'cvml','thorsten@portableinnovations.de');\>\> wrote:
> > 
> > > I would prefer if no "magic" methods would be generated automatically,  
> > > but only when marked with @derivestandardmethods (fill in better name here).
> > > 
> > > As to naming I like the proposal #1 by Alex.
> > > 
> > > What about enums with more than one associated value?
> > > 
> > > -Thorsten
> > > 
> > > Am 09.12.2015 um 07:29 schrieb Alex Lew via swift-evolution \< \>\> swift-evolution@swift.org  
> > > \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>\>:
> > > 
> > > Thanks, Chris, for all the time you're putting into responding to these  
> > > proposals (and the kindness with which you're responding!). I really like  
> > > that solution.
> > > 
> > > Brainstorming some names for the auto-generated functions:
> > > 
> > > 1. If a case has no associated values, isX() -\> Bool is generated, where  
> > > X is the case name.  
> > > &nbsp;&nbsp;&nbsp;&nbsp;If a case has an associated value of type T, asX() -\> T? is  
> > > generated, where X is the case name.  
> > > &nbsp;&nbsp;&nbsp;&nbsp;This mirrors is/as? operators, which return Bool / Optional  
> > > respectively.  
> > > 2. projectX() -\> Bool / projectX() -\> T?  
> > > 3. isX() -\> Bool / xValue() -\> T?
> > > 
> > > Another option (probably the wrong option, but it's worth putting out  
> > > there) is that instead of returning Bool in the no-associated-value case,  
> > > we return ()?. This would make me feel better about using the same naming  
> > > convention (asX(), projectX(), xValue(), etc.) for each case, and would  
> > > allow for != nil checks on all cases. But it would probably be a little  
> > > confusing for newcomers to the language.
> > > 
> > > One (potentially misguided) question. I noticed in proposal 0002 (on  
> > > removing function currying) that there are "plans to move away from the  
> > > arguments-are-a-single-tuple model" in the near future. Would this also  
> > > affect associated values of enums? That is, might
> > > 
> > > case Dog(name: String, age: Int, breed: String)
> > > 
> > > one day not have the semantics of a single associated value of type  
> > > (name: String, age: Int, breed: String)? Or is the de-ML-ification planned  
> > > only for function arguments?
> > > 
> > > -Alex
> > > 
> > > On Wed, Dec 9, 2015 at 12:45 AM, Chris Lattner \<clattner@apple.com \>\> \<javascript:\_e(%7B%7D,'cvml','clattner@apple.com');\>\> wrote:
> > > 
> > > > \> On Dec 7, 2015, at 8:05 PM, Alex Lew via swift-evolution \< \>\>\> swift-evolution@swift.org \>\>\> \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>\> wrote:  
> > > > \>  
> > > > \> Hi all,  
> > > > \>  
> > > > \> Curious to hear thoughts on allowing non-binding pattern matches to be  
> > > > used as boolean values outside of an if, guard, for...in, while, switch,  
> > > > etc. Something like:  
> > > > \>  
> > > > \> enum List\<T\> {  
> > > > \> case Empty  
> > > > \> indirect case Link(T, List\<T\>)  
> > > > \>  
> > > > \> func isEmpty() -\> Bool {  
> > > > \> return case .Empty = self  
> > > > \> }  
> > > > \> }
> > > > 
> > > > I agree with you that this is a problem that we should solve, but I  
> > > > think it could be solved in a different way. Imagine if:
> > > > 
> > > > enum Foo {  
> > > > &nbsp;&nbsp;case X(a : Float), Y, Z(a : Int)  
> > > > }
> > > > 
> > > > automatically synthesized these members (the exact names are just a  
> > > > strawman proposal, not serious :-)
> > > > 
> > > > extension Foo {  
> > > > &nbsp;&nbsp;func isX() -\> Float? {…}  
> > > > &nbsp;&nbsp;func isY() -\> Bool {…}  
> > > > &nbsp;&nbsp;func isZ() -\> Int? {…}  
> > > > }
> > > > 
> > > > This would tie into all of the mechanics we have for dealing with  
> > > > optionals, e.g. if/let and ??
> > > > 
> > > > -Chris
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org  
> > > \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > 
> > > Untracked with Trackbuster \<[Your contacts automatically up to date | evercontact](https://trackbuster.com/?sig&gt);

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner](https://avatars.discourse-cdn.com/v4/letter/c/bc8723/32.png) [@Chris\_Lattner](https://forums.swift.org/u/Chris_Lattner)\
**Post date:** [December 11, 2015, 5:32am UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/10 "2015-12-11T05:32:10Z")

</div>

> I would prefer if no "magic" methods would be generated automatically, but only when marked with @derivestandardmethods (fill in better name here).

Yes, making it opt-in could make sense.

> What about enums with more than one associated value?

It would return an optional tuple of the associated values, the tuple corresponds to the case parameter list.

-Chris

> **···**
>
> > On Dec 9, 2015, at 8:49 AM, thorsten@portableinnovations.de wrote:
> 
> > -Thorsten
> > 
> > Am 09.12.2015 um 07:29 schrieb Alex Lew via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\>:
> > 
> > > Thanks, Chris, for all the time you're putting into responding to these proposals (and the kindness with which you're responding!). I really like that solution.
> > > 
> > > Brainstorming some names for the auto-generated functions:
> > > 
> > > 1. If a case has no associated values, isX() -\> Bool is generated, where X is the case name.  
> > > &nbsp;&nbsp;&nbsp;&nbsp;If a case has an associated value of type T, asX() -\> T? is generated, where X is the case name.  
> > > &nbsp;&nbsp;&nbsp;&nbsp;This mirrors is/as? operators, which return Bool / Optional respectively.  
> > > 2. projectX() -\> Bool / projectX() -\> T?  
> > > 3. isX() -\> Bool / xValue() -\> T?
> > > 
> > > Another option (probably the wrong option, but it's worth putting out there) is that instead of returning Bool in the no-associated-value case, we return ()?. This would make me feel better about using the same naming convention (asX(), projectX(), xValue(), etc.) for each case, and would allow for != nil checks on all cases. But it would probably be a little confusing for newcomers to the language.
> > > 
> > > One (potentially misguided) question. I noticed in proposal 0002 (on removing function currying) that there are "plans to move away from the arguments-are-a-single-tuple model" in the near future. Would this also affect associated values of enums? That is, might
> > > 
> > > case Dog(name: String, age: Int, breed: String)
> > > 
> > > one day not have the semantics of a single associated value of type (name: String, age: Int, breed: String)? Or is the de-ML-ification planned only for function arguments?
> > > 
> > > -Alex
> > > 
> > > On Wed, Dec 9, 2015 at 12:45 AM, Chris Lattner \<clattner@apple.com \<mailto:clattner@apple.com\>\> wrote:
> > > 
> > > \> On Dec 7, 2015, at 8:05 PM, Alex Lew via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:  
> > > \>  
> > > \> Hi all,  
> > > \>  
> > > \> Curious to hear thoughts on allowing non-binding pattern matches to be used as boolean values outside of an if, guard, for...in, while, switch, etc. Something like:  
> > > \>  
> > > \> enum List\<T\> {  
> > > \> case Empty  
> > > \> indirect case Link(T, List\<T\>)  
> > > \>  
> > > \> func isEmpty() -\> Bool {  
> > > \> return case .Empty = self  
> > > \> }  
> > > \> }
> > > 
> > > I agree with you that this is a problem that we should solve, but I think it could be solved in a different way. Imagine if:
> > > 
> > > enum Foo {  
> > > &nbsp;&nbsp;case X(a : Float), Y, Z(a : Int)  
> > > }
> > > 
> > > automatically synthesized these members (the exact names are just a strawman proposal, not serious :-)
> > > 
> > > extension Foo {  
> > > &nbsp;&nbsp;func isX() -\> Float? {…}  
> > > &nbsp;&nbsp;func isY() -\> Bool {…}  
> > > &nbsp;&nbsp;func isZ() -\> Int? {…}  
> > > }
> > > 
> > > This would tie into all of the mechanics we have for dealing with optionals, e.g. if/let and ??
> > > 
> > > -Chris
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![plx](https://avatars.discourse-cdn.com/v4/letter/p/6f9a4e/32.png) [@plx](https://forums.swift.org/u/plx)\
**Post date:** [December 10, 2015, 3:24pm UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/11 "2015-12-10T15:24:30Z")

</div>

FWIW, as long as we’re asking for some compiler assistance generating useful enumeration-related boilerplate, I’d like to request that something along these lines be possible in some version of Swift:

@synthesize\_case\_enum  
enum Example {

&nbsp;&nbsp;case Foo(X)  
&nbsp;&nbsp;case Bar  
&nbsp;&nbsp;case Baz(Y)

}

…which would then by default expand to something like this:

enum ExampleCase : Int {  
&nbsp;&nbsp;  
&nbsp;&nbsp;case Foo  
&nbsp;&nbsp;case Bar  
&nbsp;&nbsp;case Baz

}

extension Example {

&nbsp;&nbsp;var enumerationCase: ExampleCase {  
&nbsp;&nbsp;&nbsp;&nbsp;get {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch self {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Foo(\_): return .Foo  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Bar(\_): return .Bar  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Baz(\_): return .Baz  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;}

}

…in the default case, but with some customization of the synthesized enumeration-case-enum’s details.

For the remaining proposals:

- `isX()` is nice (and should always `-\> Bool`, IMHO)  
- `projectX()` is nice and should:  
&nbsp;&nbsp;- \*not\* be defined for enums w/out associated values  
&nbsp;&nbsp;- `-\> T?` for enums w/ a single associated value  
&nbsp;&nbsp;- -\> the full tuple, for enums w/ multiple associated values, e.g.:  
&nbsp;&nbsp;&nbsp;&nbsp;- `Foo(A,B)` yields `projectFoo() -\> (A,B)?  
&nbsp;&nbsp;&nbsp;&nbsp;- `Event(place: Place, time: Time)` -\> (place: Place, time: Time)?  
&nbsp;&nbsp;&nbsp;&nbsp;- (which is essentially the same as for the single-value case, just making it explicit)

…which has the benefit of predictability (and if you need more convenience, replace your tuples with actual classes-or-structs).

Finally, as convenient as the `associatedValue` proposal is down below, it seems better-served by some sort of generalized delegation construct; at a minimum, I don’t think it's that uncommon to have N cases all wrapping the same underlying type, and in such cases working with an `Any?` would feel rather clunky.

> **···**
>
> > On Dec 9, 2015, at 3:00 PM, Andrew Bennett via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > I really like this solution and perhaps you can also go @projectable("empyValue") if the default name is a bad choice. See @obc for similar usage.
> > 
> > On Thursday, 10 December 2015, Alex Lew via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:  
> > Semantically, I believe enums with more than one associated value are actually just enums with one associated value, of tuple type.
> > 
> > I'm not convinced it would be bad to do magic function generation, but it's worth considering explicit syntax. If we were to use @ compile-time attributes, maybe it could be a word before the case -- like @projectable or @selectable (or some better name)?
> > 
> > enum List\<T\> {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@projectable case Empty  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indirect case FirstAndRest(T, List\<T\>)  
> > }
> > 
> > generates:  
> > myList.isEmpty() -\> Bool
> > 
> > Another option: some sort of @reflectable attribute on the enum itself.
> > 
> > @reflectable enum Pet {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Cat(name: String, color: String)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Dog(name: String, breed: String)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Bear(name: String, isHibernating: Bool)  
> > }
> > 
> > And one other option, in a very different direction, that seems weird but maybe has its benefits:
> > 
> > What if we exposed an associatedValue computed property of type Any? (It would be unit type for cases with no associated value.)
> > 
> > You could then do something like this:
> > 
> > enum Contact {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Person(String) // name  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Business(String) // org name  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case FamilyMember(String) // relation name  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case RecentCall(Int) // a contact from caller id, only store the phone number
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func name() -\> String {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return associatedValue as? String ?? "Unknown (\(associatedValue as! Int))"  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > }
> > 
> > Essentially, it allows you to project out a relatively common associated value (in this case a string) without much boilerplate. It's also just one thing for the compiler to generate, instead of n. Not crazy about any of these... just brainstorming. It may also be that a concise switch-like control flow expression eliminates the need for this.
> > 
> > -Alex
> > 
> > On Wed, Dec 9, 2015 at 11:49 AM, thorsten@portableinnovations.de \<javascript:\_e(%7B%7D,'cvml','thorsten@portableinnovations.de');\> \<thorsten@portableinnovations.de \<javascript:\_e(%7B%7D,'cvml','thorsten@portableinnovations.de');\>\> wrote:  
> > I would prefer if no "magic" methods would be generated automatically, but only when marked with @derivestandardmethods (fill in better name here).
> > 
> > As to naming I like the proposal #1 by Alex.
> > 
> > What about enums with more than one associated value?
> > 
> > -Thorsten
> > 
> > Am 09.12.2015 um 07:29 schrieb Alex Lew via swift-evolution \< swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>\>:
> > 
> > > Thanks, Chris, for all the time you're putting into responding to these proposals (and the kindness with which you're responding!). I really like that solution.
> > > 
> > > Brainstorming some names for the auto-generated functions:
> > > 
> > > 1. If a case has no associated values, isX() -\> Bool is generated, where X is the case name.  
> > > &nbsp;&nbsp;&nbsp;&nbsp;If a case has an associated value of type T, asX() -\> T? is generated, where X is the case name.  
> > > &nbsp;&nbsp;&nbsp;&nbsp;This mirrors is/as? operators, which return Bool / Optional respectively.  
> > > 2. projectX() -\> Bool / projectX() -\> T?  
> > > 3. isX() -\> Bool / xValue() -\> T?
> > > 
> > > Another option (probably the wrong option, but it's worth putting out there) is that instead of returning Bool in the no-associated-value case, we return ()?. This would make me feel better about using the same naming convention (asX(), projectX(), xValue(), etc.) for each case, and would allow for != nil checks on all cases. But it would probably be a little confusing for newcomers to the language.
> > > 
> > > One (potentially misguided) question. I noticed in proposal 0002 (on removing function currying) that there are "plans to move away from the arguments-are-a-single-tuple model" in the near future. Would this also affect associated values of enums? That is, might
> > > 
> > > case Dog(name: String, age: Int, breed: String)
> > > 
> > > one day not have the semantics of a single associated value of type (name: String, age: Int, breed: String)? Or is the de-ML-ification planned only for function arguments?
> > > 
> > > -Alex
> > > 
> > > On Wed, Dec 9, 2015 at 12:45 AM, Chris Lattner \<clattner@apple.com \<javascript:\_e(%7B%7D,'cvml','clattner@apple.com');\>\> wrote:
> > > 
> > > \> On Dec 7, 2015, at 8:05 PM, Alex Lew via swift-evolution \<swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>\> wrote:  
> > > \>  
> > > \> Hi all,  
> > > \>  
> > > \> Curious to hear thoughts on allowing non-binding pattern matches to be used as boolean values outside of an if, guard, for...in, while, switch, etc. Something like:  
> > > \>  
> > > \> enum List\<T\> {  
> > > \> case Empty  
> > > \> indirect case Link(T, List\<T\>)  
> > > \>  
> > > \> func isEmpty() -\> Bool {  
> > > \> return case .Empty = self  
> > > \> }  
> > > \> }
> > > 
> > > I agree with you that this is a problem that we should solve, but I think it could be solved in a different way. Imagine if:
> > > 
> > > enum Foo {  
> > > &nbsp;&nbsp;case X(a : Float), Y, Z(a : Int)  
> > > }
> > > 
> > > automatically synthesized these members (the exact names are just a strawman proposal, not serious :-)
> > > 
> > > extension Foo {  
> > > &nbsp;&nbsp;func isX() -\> Float? {…}  
> > > &nbsp;&nbsp;func isY() -\> Bool {…}  
> > > &nbsp;&nbsp;func isZ() -\> Int? {…}  
> > > }
> > > 
> > > This would tie into all of the mechanics we have for dealing with optionals, e.g. if/let and ??
> > > 
> > > -Chris
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > Untracked with Trackbuster \<[Your contacts automatically up to date | evercontact](https://trackbuster.com/?sig&gt);
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Kevin\_Wooten](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kevin_wooten/32/980_2.png) [@Kevin\_Wooten](https://forums.swift.org/u/Kevin_Wooten)\
**Post date:** [December 10, 2015, 3:35pm UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/12 "2015-12-10T15:35:25Z")

</div>

I get the gist of what you are requesting and I can see it might me useful but given that

if case .Foo(\_) == ex {  
}

Provides comparison, regardless of the # of associated values in .Foo, I’m not sure generating a second enum just to carry a diminished amount of information is worth it.

> **···**
>
> > On Dec 10, 2015, at 8:24 AM, plx via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > FWIW, as long as we’re asking for some compiler assistance generating useful enumeration-related boilerplate, I’d like to request that something along these lines be possible in some version of Swift:
> > 
> > @synthesize\_case\_enum  
> > enum Example {
> > 
> > &nbsp;&nbsp;case Foo(X)  
> > &nbsp;&nbsp;case Bar  
> > &nbsp;&nbsp;case Baz(Y)
> > 
> > }
> > 
> > …which would then by default expand to something like this:
> > 
> > enum ExampleCase : Int {  
> > &nbsp;&nbsp;  
> > &nbsp;&nbsp;case Foo  
> > &nbsp;&nbsp;case Bar  
> > &nbsp;&nbsp;case Baz
> > 
> > }
> > 
> > extension Example {
> > 
> > &nbsp;&nbsp;var enumerationCase: ExampleCase {  
> > &nbsp;&nbsp;&nbsp;&nbsp;get {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch self {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Foo(\_): return .Foo  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Bar(\_): return .Bar  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Baz(\_): return .Baz  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;}
> > 
> > }
> > 
> > …in the default case, but with some customization of the synthesized enumeration-case-enum’s details.
> > 
> > For the remaining proposals:
> > 
> > - `isX()` is nice (and should always `-\> Bool`, IMHO)  
> > - `projectX()` is nice and should:  
> > &nbsp;&nbsp;- \*not\* be defined for enums w/out associated values  
> > &nbsp;&nbsp;- `-\> T?` for enums w/ a single associated value  
> > &nbsp;&nbsp;- -\> the full tuple, for enums w/ multiple associated values, e.g.:  
> > &nbsp;&nbsp;&nbsp;&nbsp;- `Foo(A,B)` yields `projectFoo() -\> (A,B)?  
> > &nbsp;&nbsp;&nbsp;&nbsp;- `Event(place: Place, time: Time)` -\> (place: Place, time: Time)?  
> > &nbsp;&nbsp;&nbsp;&nbsp;- (which is essentially the same as for the single-value case, just making it explicit)
> > 
> > …which has the benefit of predictability (and if you need more convenience, replace your tuples with actual classes-or-structs).
> > 
> > Finally, as convenient as the `associatedValue` proposal is down below, it seems better-served by some sort of generalized delegation construct; at a minimum, I don’t think it's that uncommon to have N cases all wrapping the same underlying type, and in such cases working with an `Any?` would feel rather clunky.
> > 
> > > On Dec 9, 2015, at 3:00 PM, Andrew Bennett via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > 
> > > I really like this solution and perhaps you can also go @projectable("empyValue") if the default name is a bad choice. See @obc for similar usage.
> > > 
> > > On Thursday, 10 December 2015, Alex Lew via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:  
> > > Semantically, I believe enums with more than one associated value are actually just enums with one associated value, of tuple type.
> > > 
> > > I'm not convinced it would be bad to do magic function generation, but it's worth considering explicit syntax. If we were to use @ compile-time attributes, maybe it could be a word before the case -- like @projectable or @selectable (or some better name)?
> > > 
> > > enum List\<T\> {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@projectable case Empty  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indirect case FirstAndRest(T, List\<T\>)  
> > > }
> > > 
> > > generates:  
> > > myList.isEmpty() -\> Bool
> > > 
> > > Another option: some sort of @reflectable attribute on the enum itself.
> > > 
> > > @reflectable enum Pet {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Cat(name: String, color: String)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Dog(name: String, breed: String)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Bear(name: String, isHibernating: Bool)  
> > > }
> > > 
> > > And one other option, in a very different direction, that seems weird but maybe has its benefits:
> > > 
> > > What if we exposed an associatedValue computed property of type Any? (It would be unit type for cases with no associated value.)
> > > 
> > > You could then do something like this:
> > > 
> > > enum Contact {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Person(String) // name  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Business(String) // org name  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case FamilyMember(String) // relation name  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case RecentCall(Int) // a contact from caller id, only store the phone number
> > > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func name() -\> String {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return associatedValue as? String ?? "Unknown (\(associatedValue as! Int))"  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > > }
> > > 
> > > Essentially, it allows you to project out a relatively common associated value (in this case a string) without much boilerplate. It's also just one thing for the compiler to generate, instead of n. Not crazy about any of these... just brainstorming. It may also be that a concise switch-like control flow expression eliminates the need for this.
> > > 
> > > -Alex
> > > 
> > > On Wed, Dec 9, 2015 at 11:49 AM, thorsten@portableinnovations.de \<javascript:\_e(%7B%7D,'cvml','thorsten@portableinnovations.de');\> \<thorsten@portableinnovations.de \<javascript:\_e(%7B%7D,'cvml','thorsten@portableinnovations.de');\>\> wrote:  
> > > I would prefer if no "magic" methods would be generated automatically, but only when marked with @derivestandardmethods (fill in better name here).
> > > 
> > > As to naming I like the proposal #1 by Alex.
> > > 
> > > What about enums with more than one associated value?
> > > 
> > > -Thorsten
> > > 
> > > Am 09.12.2015 um 07:29 schrieb Alex Lew via swift-evolution \< swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>\>:
> > > 
> > > > Thanks, Chris, for all the time you're putting into responding to these proposals (and the kindness with which you're responding!). I really like that solution.
> > > > 
> > > > Brainstorming some names for the auto-generated functions:
> > > > 
> > > > 1. If a case has no associated values, isX() -\> Bool is generated, where X is the case name.  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;If a case has an associated value of type T, asX() -\> T? is generated, where X is the case name.  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;This mirrors is/as? operators, which return Bool / Optional respectively.  
> > > > 2. projectX() -\> Bool / projectX() -\> T?  
> > > > 3. isX() -\> Bool / xValue() -\> T?
> > > > 
> > > > Another option (probably the wrong option, but it's worth putting out there) is that instead of returning Bool in the no-associated-value case, we return ()?. This would make me feel better about using the same naming convention (asX(), projectX(), xValue(), etc.) for each case, and would allow for != nil checks on all cases. But it would probably be a little confusing for newcomers to the language.
> > > > 
> > > > One (potentially misguided) question. I noticed in proposal 0002 (on removing function currying) that there are "plans to move away from the arguments-are-a-single-tuple model" in the near future. Would this also affect associated values of enums? That is, might
> > > > 
> > > > case Dog(name: String, age: Int, breed: String)
> > > > 
> > > > one day not have the semantics of a single associated value of type (name: String, age: Int, breed: String)? Or is the de-ML-ification planned only for function arguments?
> > > > 
> > > > -Alex
> > > > 
> > > > On Wed, Dec 9, 2015 at 12:45 AM, Chris Lattner \<clattner@apple.com \<javascript:\_e(%7B%7D,'cvml','clattner@apple.com');\>\> wrote:
> > > > 
> > > > \> On Dec 7, 2015, at 8:05 PM, Alex Lew via swift-evolution \<swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>\> wrote:  
> > > > \>  
> > > > \> Hi all,  
> > > > \>  
> > > > \> Curious to hear thoughts on allowing non-binding pattern matches to be used as boolean values outside of an if, guard, for...in, while, switch, etc. Something like:  
> > > > \>  
> > > > \> enum List\<T\> {  
> > > > \> case Empty  
> > > > \> indirect case Link(T, List\<T\>)  
> > > > \>  
> > > > \> func isEmpty() -\> Bool {  
> > > > \> return case .Empty = self  
> > > > \> }  
> > > > \> }
> > > > 
> > > > I agree with you that this is a problem that we should solve, but I think it could be solved in a different way. Imagine if:
> > > > 
> > > > enum Foo {  
> > > > &nbsp;&nbsp;case X(a : Float), Y, Z(a : Int)  
> > > > }
> > > > 
> > > > automatically synthesized these members (the exact names are just a strawman proposal, not serious :-)
> > > > 
> > > > extension Foo {  
> > > > &nbsp;&nbsp;func isX() -\> Float? {…}  
> > > > &nbsp;&nbsp;func isY() -\> Bool {…}  
> > > > &nbsp;&nbsp;func isZ() -\> Int? {…}  
> > > > }
> > > > 
> > > > This would tie into all of the mechanics we have for dealing with optionals, e.g. if/let and ??
> > > > 
> > > > -Chris
> > > > 
> > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > swift-evolution mailing list  
> > > > swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>  
> > > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > 
> > > Untracked with Trackbuster \<[Your contacts automatically up to date | evercontact](https://trackbuster.com/?sig&gt);
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![plx](https://avatars.discourse-cdn.com/v4/letter/p/6f9a4e/32.png) [@plx](https://forums.swift.org/u/plx)\
**Post date:** [December 10, 2015, 3:42pm UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/13 "2015-12-10T15:42:36Z")

</div>

The motivating/most-common case for me is serialization:

coder.encodeInteger(self.enumerationCase.rawValue, forKey: “case")  
switch self {  
&nbsp;&nbsp;case let .Foo(data): coder.encodeX(data, forKey: “data”)  
&nbsp;&nbsp;case let .Bar(data): coder.encodeY(data, forKey: “data”)  
}

…etc., and the obvious use of the above when decoding (decode the case, switch on it, decode data).

Once you have it it’s occasionally handy in other contexts, but that’s by far the main motivation.

> **···**
>
> > On Dec 10, 2015, at 9:35 AM, Kevin Wooten \<kdubb@me.com\> wrote:
> > 
> > I get the gist of what you are requesting and I can see it might me useful but given that
> > 
> > if case .Foo(\_) == ex {  
> > }
> > 
> > Provides comparison, regardless of the # of associated values in .Foo, I’m not sure generating a second enum just to carry a diminished amount of information is worth it.
> > 
> > > On Dec 10, 2015, at 8:24 AM, plx via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > 
> > > FWIW, as long as we’re asking for some compiler assistance generating useful enumeration-related boilerplate, I’d like to request that something along these lines be possible in some version of Swift:
> > > 
> > > @synthesize\_case\_enum  
> > > enum Example {
> > > 
> > > &nbsp;&nbsp;case Foo(X)  
> > > &nbsp;&nbsp;case Bar  
> > > &nbsp;&nbsp;case Baz(Y)
> > > 
> > > }
> > > 
> > > …which would then by default expand to something like this:
> > > 
> > > enum ExampleCase : Int {  
> > > &nbsp;&nbsp;  
> > > &nbsp;&nbsp;case Foo  
> > > &nbsp;&nbsp;case Bar  
> > > &nbsp;&nbsp;case Baz
> > > 
> > > }
> > > 
> > > extension Example {
> > > 
> > > &nbsp;&nbsp;var enumerationCase: ExampleCase {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;get {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch self {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Foo(\_): return .Foo  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Bar(\_): return .Bar  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Baz(\_): return .Baz  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > > &nbsp;&nbsp;}
> > > 
> > > }
> > > 
> > > …in the default case, but with some customization of the synthesized enumeration-case-enum’s details.
> > > 
> > > For the remaining proposals:
> > > 
> > > - `isX()` is nice (and should always `-\> Bool`, IMHO)  
> > > - `projectX()` is nice and should:  
> > > &nbsp;&nbsp;- \*not\* be defined for enums w/out associated values  
> > > &nbsp;&nbsp;- `-\> T?` for enums w/ a single associated value  
> > > &nbsp;&nbsp;- -\> the full tuple, for enums w/ multiple associated values, e.g.:  
> > > &nbsp;&nbsp;&nbsp;&nbsp;- `Foo(A,B)` yields `projectFoo() -\> (A,B)?  
> > > &nbsp;&nbsp;&nbsp;&nbsp;- `Event(place: Place, time: Time)` -\> (place: Place, time: Time)?  
> > > &nbsp;&nbsp;&nbsp;&nbsp;- (which is essentially the same as for the single-value case, just making it explicit)
> > > 
> > > …which has the benefit of predictability (and if you need more convenience, replace your tuples with actual classes-or-structs).
> > > 
> > > Finally, as convenient as the `associatedValue` proposal is down below, it seems better-served by some sort of generalized delegation construct; at a minimum, I don’t think it's that uncommon to have N cases all wrapping the same underlying type, and in such cases working with an `Any?` would feel rather clunky.
> > > 
> > > > On Dec 9, 2015, at 3:00 PM, Andrew Bennett via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > > 
> > > > I really like this solution and perhaps you can also go @projectable("empyValue") if the default name is a bad choice. See @obc for similar usage.
> > > > 
> > > > On Thursday, 10 December 2015, Alex Lew via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:  
> > > > Semantically, I believe enums with more than one associated value are actually just enums with one associated value, of tuple type.
> > > > 
> > > > I'm not convinced it would be bad to do magic function generation, but it's worth considering explicit syntax. If we were to use @ compile-time attributes, maybe it could be a word before the case -- like @projectable or @selectable (or some better name)?
> > > > 
> > > > enum List\<T\> {  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@projectable case Empty  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indirect case FirstAndRest(T, List\<T\>)  
> > > > }
> > > > 
> > > > generates:  
> > > > myList.isEmpty() -\> Bool
> > > > 
> > > > Another option: some sort of @reflectable attribute on the enum itself.
> > > > 
> > > > @reflectable enum Pet {  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Cat(name: String, color: String)  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Dog(name: String, breed: String)  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Bear(name: String, isHibernating: Bool)  
> > > > }
> > > > 
> > > > And one other option, in a very different direction, that seems weird but maybe has its benefits:
> > > > 
> > > > What if we exposed an associatedValue computed property of type Any? (It would be unit type for cases with no associated value.)
> > > > 
> > > > You could then do something like this:
> > > > 
> > > > enum Contact {  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Person(String) // name  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Business(String) // org name  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case FamilyMember(String) // relation name  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case RecentCall(Int) // a contact from caller id, only store the phone number
> > > > 
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func name() -\> String {  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return associatedValue as? String ?? "Unknown (\(associatedValue as! Int))"  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > > > }
> > > > 
> > > > Essentially, it allows you to project out a relatively common associated value (in this case a string) without much boilerplate. It's also just one thing for the compiler to generate, instead of n. Not crazy about any of these... just brainstorming. It may also be that a concise switch-like control flow expression eliminates the need for this.
> > > > 
> > > > -Alex
> > > > 
> > > > On Wed, Dec 9, 2015 at 11:49 AM, thorsten@portableinnovations.de \<javascript:\_e(%7B%7D,'cvml','thorsten@portableinnovations.de');\> \<thorsten@portableinnovations.de \<javascript:\_e(%7B%7D,'cvml','thorsten@portableinnovations.de');\>\> wrote:  
> > > > I would prefer if no "magic" methods would be generated automatically, but only when marked with @derivestandardmethods (fill in better name here).
> > > > 
> > > > As to naming I like the proposal #1 by Alex.
> > > > 
> > > > What about enums with more than one associated value?
> > > > 
> > > > -Thorsten
> > > > 
> > > > Am 09.12.2015 um 07:29 schrieb Alex Lew via swift-evolution \< swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>\>:
> > > > 
> > > > > Thanks, Chris, for all the time you're putting into responding to these proposals (and the kindness with which you're responding!). I really like that solution.
> > > > > 
> > > > > Brainstorming some names for the auto-generated functions:
> > > > > 
> > > > > 1. If a case has no associated values, isX() -\> Bool is generated, where X is the case name.  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;If a case has an associated value of type T, asX() -\> T? is generated, where X is the case name.  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;This mirrors is/as? operators, which return Bool / Optional respectively.  
> > > > > 2. projectX() -\> Bool / projectX() -\> T?  
> > > > > 3. isX() -\> Bool / xValue() -\> T?
> > > > > 
> > > > > Another option (probably the wrong option, but it's worth putting out there) is that instead of returning Bool in the no-associated-value case, we return ()?. This would make me feel better about using the same naming convention (asX(), projectX(), xValue(), etc.) for each case, and would allow for != nil checks on all cases. But it would probably be a little confusing for newcomers to the language.
> > > > > 
> > > > > One (potentially misguided) question. I noticed in proposal 0002 (on removing function currying) that there are "plans to move away from the arguments-are-a-single-tuple model" in the near future. Would this also affect associated values of enums? That is, might
> > > > > 
> > > > > case Dog(name: String, age: Int, breed: String)
> > > > > 
> > > > > one day not have the semantics of a single associated value of type (name: String, age: Int, breed: String)? Or is the de-ML-ification planned only for function arguments?
> > > > > 
> > > > > -Alex
> > > > > 
> > > > > On Wed, Dec 9, 2015 at 12:45 AM, Chris Lattner \<clattner@apple.com \<javascript:\_e(%7B%7D,'cvml','clattner@apple.com');\>\> wrote:
> > > > > 
> > > > > \> On Dec 7, 2015, at 8:05 PM, Alex Lew via swift-evolution \<swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>\> wrote:  
> > > > > \>  
> > > > > \> Hi all,  
> > > > > \>  
> > > > > \> Curious to hear thoughts on allowing non-binding pattern matches to be used as boolean values outside of an if, guard, for...in, while, switch, etc. Something like:  
> > > > > \>  
> > > > > \> enum List\<T\> {  
> > > > > \> case Empty  
> > > > > \> indirect case Link(T, List\<T\>)  
> > > > > \>  
> > > > > \> func isEmpty() -\> Bool {  
> > > > > \> return case .Empty = self  
> > > > > \> }  
> > > > > \> }
> > > > > 
> > > > > I agree with you that this is a problem that we should solve, but I think it could be solved in a different way. Imagine if:
> > > > > 
> > > > > enum Foo {  
> > > > > &nbsp;&nbsp;case X(a : Float), Y, Z(a : Int)  
> > > > > }
> > > > > 
> > > > > automatically synthesized these members (the exact names are just a strawman proposal, not serious :-)
> > > > > 
> > > > > extension Foo {  
> > > > > &nbsp;&nbsp;func isX() -\> Float? {…}  
> > > > > &nbsp;&nbsp;func isY() -\> Bool {…}  
> > > > > &nbsp;&nbsp;func isZ() -\> Int? {…}  
> > > > > }
> > > > > 
> > > > > This would tie into all of the mechanics we have for dealing with optionals, e.g. if/let and ??
> > > > > 
> > > > > -Chris
> > > > > 
> > > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > > swift-evolution mailing list  
> > > > > swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>  
> > > > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > > 
> > > > Untracked with Trackbuster \<[Your contacts automatically up to date | evercontact](https://trackbuster.com/?sig&gt);
> > > > 
> > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > swift-evolution mailing list  
> > > > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > > > [https://lists.swift.org/mailman/listinfo/swift-evolution](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](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Kevin\_Wooten](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kevin_wooten/32/980_2.png) [@Kevin\_Wooten](https://forums.swift.org/u/Kevin_Wooten)\
**Post date:** [December 10, 2015, 3:48pm UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/14 "2015-12-10T15:48:11Z")

</div>

> The motivating/most-common case for me is serialization:
> 
> coder.encodeInteger(self.enumerationCase.rawValue, forKey: “case")  
> switch self {  
> &nbsp;&nbsp;case let .Foo(data): coder.encodeX(data, forKey: “data”)  
> &nbsp;&nbsp;case let .Bar(data): coder.encodeY(data, forKey: “data”)  
> }

Solvable now via…

switch self {  
&nbsp;&nbsp;case let .Foo(data):  
&nbsp;&nbsp;&nbsp;&nbsp;coder.encodeInteger(…)  
&nbsp;&nbsp;&nbsp;&nbsp;coder.encodeX(..)  
&nbsp;&nbsp;case let .Bar(data):  
&nbsp;&nbsp;&nbsp;&nbsp;coder.encodeInteger(…)  
&nbsp;&nbsp;&nbsp;&nbsp;coder.encodeY(…)  
}

It’s only missing an integer raw value assigned by the compiler.

> **···**
>
> > On Dec 10, 2015, at 8:42 AM, plx via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> > …etc., and the obvious use of the above when decoding (decode the case, switch on it, decode data).
> > 
> > Once you have it it’s occasionally handy in other contexts, but that’s by far the main motivation.
> > 
> > > On Dec 10, 2015, at 9:35 AM, Kevin Wooten \<kdubb@me.com \<mailto:kdubb@me.com\>\> wrote:
> > > 
> > > I get the gist of what you are requesting and I can see it might me useful but given that
> > > 
> > > if case .Foo(\_) == ex {  
> > > }
> > > 
> > > Provides comparison, regardless of the # of associated values in .Foo, I’m not sure generating a second enum just to carry a diminished amount of information is worth it.
> > > 
> > > > On Dec 10, 2015, at 8:24 AM, plx via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > > 
> > > > FWIW, as long as we’re asking for some compiler assistance generating useful enumeration-related boilerplate, I’d like to request that something along these lines be possible in some version of Swift:
> > > > 
> > > > @synthesize\_case\_enum  
> > > > enum Example {
> > > > 
> > > > &nbsp;&nbsp;case Foo(X)  
> > > > &nbsp;&nbsp;case Bar  
> > > > &nbsp;&nbsp;case Baz(Y)
> > > > 
> > > > }
> > > > 
> > > > …which would then by default expand to something like this:
> > > > 
> > > > enum ExampleCase : Int {  
> > > > &nbsp;&nbsp;  
> > > > &nbsp;&nbsp;case Foo  
> > > > &nbsp;&nbsp;case Bar  
> > > > &nbsp;&nbsp;case Baz
> > > > 
> > > > }
> > > > 
> > > > extension Example {
> > > > 
> > > > &nbsp;&nbsp;var enumerationCase: ExampleCase {  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;get {  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch self {  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Foo(\_): return .Foo  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Bar(\_): return .Bar  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Baz(\_): return .Baz  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > > > &nbsp;&nbsp;}
> > > > 
> > > > }
> > > > 
> > > > …in the default case, but with some customization of the synthesized enumeration-case-enum’s details.
> > > > 
> > > > For the remaining proposals:
> > > > 
> > > > - `isX()` is nice (and should always `-\> Bool`, IMHO)  
> > > > - `projectX()` is nice and should:  
> > > > &nbsp;&nbsp;- \*not\* be defined for enums w/out associated values  
> > > > &nbsp;&nbsp;- `-\> T?` for enums w/ a single associated value  
> > > > &nbsp;&nbsp;- -\> the full tuple, for enums w/ multiple associated values, e.g.:  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;- `Foo(A,B)` yields `projectFoo() -\> (A,B)?  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;- `Event(place: Place, time: Time)` -\> (place: Place, time: Time)?  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;- (which is essentially the same as for the single-value case, just making it explicit)
> > > > 
> > > > …which has the benefit of predictability (and if you need more convenience, replace your tuples with actual classes-or-structs).
> > > > 
> > > > Finally, as convenient as the `associatedValue` proposal is down below, it seems better-served by some sort of generalized delegation construct; at a minimum, I don’t think it's that uncommon to have N cases all wrapping the same underlying type, and in such cases working with an `Any?` would feel rather clunky.
> > > > 
> > > > > On Dec 9, 2015, at 3:00 PM, Andrew Bennett via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > > > 
> > > > > I really like this solution and perhaps you can also go @projectable("empyValue") if the default name is a bad choice. See @obc for similar usage.
> > > > > 
> > > > > On Thursday, 10 December 2015, Alex Lew via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:  
> > > > > Semantically, I believe enums with more than one associated value are actually just enums with one associated value, of tuple type.
> > > > > 
> > > > > I'm not convinced it would be bad to do magic function generation, but it's worth considering explicit syntax. If we were to use @ compile-time attributes, maybe it could be a word before the case -- like @projectable or @selectable (or some better name)?
> > > > > 
> > > > > enum List\<T\> {  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@projectable case Empty  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indirect case FirstAndRest(T, List\<T\>)  
> > > > > }
> > > > > 
> > > > > generates:  
> > > > > myList.isEmpty() -\> Bool
> > > > > 
> > > > > Another option: some sort of @reflectable attribute on the enum itself.
> > > > > 
> > > > > @reflectable enum Pet {  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Cat(name: String, color: String)  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Dog(name: String, breed: String)  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Bear(name: String, isHibernating: Bool)  
> > > > > }
> > > > > 
> > > > > And one other option, in a very different direction, that seems weird but maybe has its benefits:
> > > > > 
> > > > > What if we exposed an associatedValue computed property of type Any? (It would be unit type for cases with no associated value.)
> > > > > 
> > > > > You could then do something like this:
> > > > > 
> > > > > enum Contact {  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Person(String) // name  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Business(String) // org name  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case FamilyMember(String) // relation name  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case RecentCall(Int) // a contact from caller id, only store the phone number
> > > > > 
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func name() -\> String {  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return associatedValue as? String ?? "Unknown (\(associatedValue as! Int))"  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > > > > }
> > > > > 
> > > > > Essentially, it allows you to project out a relatively common associated value (in this case a string) without much boilerplate. It's also just one thing for the compiler to generate, instead of n. Not crazy about any of these... just brainstorming. It may also be that a concise switch-like control flow expression eliminates the need for this.
> > > > > 
> > > > > -Alex
> > > > > 
> > > > > On Wed, Dec 9, 2015 at 11:49 AM, thorsten@portableinnovations.de \<javascript:\_e(%7B%7D,'cvml','thorsten@portableinnovations.de');\> \<thorsten@portableinnovations.de \<javascript:\_e(%7B%7D,'cvml','thorsten@portableinnovations.de');\>\> wrote:  
> > > > > I would prefer if no "magic" methods would be generated automatically, but only when marked with @derivestandardmethods (fill in better name here).
> > > > > 
> > > > > As to naming I like the proposal #1 by Alex.
> > > > > 
> > > > > What about enums with more than one associated value?
> > > > > 
> > > > > -Thorsten
> > > > > 
> > > > > Am 09.12.2015 um 07:29 schrieb Alex Lew via swift-evolution \< swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>\>:
> > > > > 
> > > > > > Thanks, Chris, for all the time you're putting into responding to these proposals (and the kindness with which you're responding!). I really like that solution.
> > > > > > 
> > > > > > Brainstorming some names for the auto-generated functions:
> > > > > > 
> > > > > > 1. If a case has no associated values, isX() -\> Bool is generated, where X is the case name.  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;If a case has an associated value of type T, asX() -\> T? is generated, where X is the case name.  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;This mirrors is/as? operators, which return Bool / Optional respectively.  
> > > > > > 2. projectX() -\> Bool / projectX() -\> T?  
> > > > > > 3. isX() -\> Bool / xValue() -\> T?
> > > > > > 
> > > > > > Another option (probably the wrong option, but it's worth putting out there) is that instead of returning Bool in the no-associated-value case, we return ()?. This would make me feel better about using the same naming convention (asX(), projectX(), xValue(), etc.) for each case, and would allow for != nil checks on all cases. But it would probably be a little confusing for newcomers to the language.
> > > > > > 
> > > > > > One (potentially misguided) question. I noticed in proposal 0002 (on removing function currying) that there are "plans to move away from the arguments-are-a-single-tuple model" in the near future. Would this also affect associated values of enums? That is, might
> > > > > > 
> > > > > > case Dog(name: String, age: Int, breed: String)
> > > > > > 
> > > > > > one day not have the semantics of a single associated value of type (name: String, age: Int, breed: String)? Or is the de-ML-ification planned only for function arguments?
> > > > > > 
> > > > > > -Alex
> > > > > > 
> > > > > > On Wed, Dec 9, 2015 at 12:45 AM, Chris Lattner \<clattner@apple.com \<javascript:\_e(%7B%7D,'cvml','clattner@apple.com');\>\> wrote:
> > > > > > 
> > > > > > \> On Dec 7, 2015, at 8:05 PM, Alex Lew via swift-evolution \<swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>\> wrote:  
> > > > > > \>  
> > > > > > \> Hi all,  
> > > > > > \>  
> > > > > > \> Curious to hear thoughts on allowing non-binding pattern matches to be used as boolean values outside of an if, guard, for...in, while, switch, etc. Something like:  
> > > > > > \>  
> > > > > > \> enum List\<T\> {  
> > > > > > \> case Empty  
> > > > > > \> indirect case Link(T, List\<T\>)  
> > > > > > \>  
> > > > > > \> func isEmpty() -\> Bool {  
> > > > > > \> return case .Empty = self  
> > > > > > \> }  
> > > > > > \> }
> > > > > > 
> > > > > > I agree with you that this is a problem that we should solve, but I think it could be solved in a different way. Imagine if:
> > > > > > 
> > > > > > enum Foo {  
> > > > > > &nbsp;&nbsp;case X(a : Float), Y, Z(a : Int)  
> > > > > > }
> > > > > > 
> > > > > > automatically synthesized these members (the exact names are just a strawman proposal, not serious :-)
> > > > > > 
> > > > > > extension Foo {  
> > > > > > &nbsp;&nbsp;func isX() -\> Float? {…}  
> > > > > > &nbsp;&nbsp;func isY() -\> Bool {…}  
> > > > > > &nbsp;&nbsp;func isZ() -\> Int? {…}  
> > > > > > }
> > > > > > 
> > > > > > This would tie into all of the mechanics we have for dealing with optionals, e.g. if/let and ??
> > > > > > 
> > > > > > -Chris
> > > > > > 
> > > > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > > > swift-evolution mailing list  
> > > > > > swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>  
> > > > > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > > > 
> > > > > Untracked with Trackbuster \<[Your contacts automatically up to date | evercontact](https://trackbuster.com/?sig&gt);
> > > > > 
> > > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > > swift-evolution mailing list  
> > > > > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > > > > [https://lists.swift.org/mailman/listinfo/swift-evolution](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](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![plx](https://avatars.discourse-cdn.com/v4/letter/p/6f9a4e/32.png) [@plx](https://forums.swift.org/u/plx)\
**Post date:** [December 10, 2015, 4:29pm UTC](https://forums.swift.org/t/allowing-non-binding-pattern-matching-as-a-bool-expression/294/15 "2015-12-10T16:29:44Z")

</div>

> > The motivating/most-common case for me is serialization:
> > 
> > coder.encodeInteger(self.enumerationCase.rawValue, forKey: “case")  
> > switch self {  
> > &nbsp;&nbsp;case let .Foo(data): coder.encodeX(data, forKey: “data”)  
> > &nbsp;&nbsp;case let .Bar(data): coder.encodeY(data, forKey: “data”)  
> > }
> 
> Solvable now via…
> 
> switch self {  
> &nbsp;&nbsp;case let .Foo(data):  
> &nbsp;&nbsp;&nbsp;&nbsp;coder.encodeInteger(…)  
> &nbsp;&nbsp;&nbsp;&nbsp;coder.encodeX(..)  
> &nbsp;&nbsp;case let .Bar(data):  
> &nbsp;&nbsp;&nbsp;&nbsp;coder.encodeInteger(…)  
> &nbsp;&nbsp;&nbsp;&nbsp;coder.encodeY(…)  
> }
> 
> It’s only missing an integer raw value assigned by the compiler.

Well, it’s also missing:

- a compiler-enforced exhaustiveness check here:

guard let enumerationCase = EnumerationCase(rawValue: coder.decodeIntegerForKey(“case”)) else { return nil }  
switch enumerationCase {  
&nbsp;&nbsp;case IntegerForFooCase: …  
&nbsp;&nbsp;case IntegerForBazCase: …  
&nbsp;&nbsp;// forgot about Bar! and Quux!  
}

…along with compiler-enforced “no typo/no-duplicate/no-forget” checks here:

// in encode:  
case let .Foo(data):  
&nbsp;&nbsp;coder.encodeInteger(1, ..)  
&nbsp;&nbsp;coder.encodeX(…)  
case let .Bar(data):  
&nbsp;&nbsp;coder.encodeInteger(1, ..) // oopsie  
&nbsp;&nbsp;coder.encodeY(…)  
case let .Baz(data):  
&nbsp;&nbsp;coder.encodeInteger(3, ..)  
&nbsp;&nbsp;coder.encodeZ(…)  
case let .Quux(data):  
&nbsp;&nbsp;// oopsie! if only i didn’t have to repeat myself!  
&nbsp;&nbsp;coder.encodeW(…)

// in decode:  
switch caseInteger {  
&nbsp;&nbsp;case 1: // try to decode Bar // oopsie  
&nbsp;&nbsp;case 2: // try to decode Foo // oopsie  
&nbsp;&nbsp;case 4: // try to decode Baz (//oopsie!)  
&nbsp;&nbsp;&nbsp;&nbsp;// oopsie, forgot about Quux  
}

…and once I’m doing this:

extension Example {  
&nbsp;&nbsp;static let SerializationIntegerForFoo: Int = 1  
&nbsp;&nbsp;static let SerializationIntegerForBar: Int = 2  
&nbsp;&nbsp;// etc.

&nbsp;&nbsp;var caseSerializationInteger: Int {  
&nbsp;&nbsp;&nbsp;&nbsp;get {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch self {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Foo(\_): return .SerializationIntegerForFoo // etc.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;}  
}

…we’re back to the same boilerplate, just written manually and without, e.g., the benefit of exhaustiveness checks in our switch statements.

Outside serialization, the construct has some miscellaneous handiness, e.g.:

enum SomeStateMachineStateData\<A,B,C\> {  
&nbsp;&nbsp;case Initialized  
&nbsp;&nbsp;case StateA(A)  
&nbsp;&nbsp;case StateB(B)  
&nbsp;&nbsp;case StateC(C)  
&nbsp;&nbsp;case MixedAB(A,B)  
}

// ^ \*not\* obj-c visible

@objc  
enum SomeStateMachineState : Int {  
&nbsp;&nbsp;case Initialized  
&nbsp;&nbsp;case StateA  
&nbsp;&nbsp;case StateB  
&nbsp;&nbsp;case StateC  
&nbsp;&nbsp;case MixedAB  
}

// ^ objc-visible

…(and similar) which makes it easier to, say, have an obj-c delegate protocol `SomeStateMachineDelegate` that can “follow along” with the associated state machine’s transitions.

Anyways, this isn’t a request that would make previously-unsolvable problems solvable, it’s merely a request for some compiler assistance reducing certain types of boilerplate, offered up in a discussion of other possible enumeration-related boilerplate reduction (isX(), projectX(), etc.).

On an importance scale from 1-10 it’s maybe a 3 for me personally, but I’d hate to see e.g. synthesis of `isX()` make it into the language without having at least seen if anyone else is interested on this one as well.

> **···**
>
> > On Dec 10, 2015, at 9:48 AM, Kevin Wooten \<kdubb@me.com\> wrote:
> > 
> > > On Dec 10, 2015, at 8:42 AM, plx via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> 
> > > …etc., and the obvious use of the above when decoding (decode the case, switch on it, decode data).
> > > 
> > > Once you have it it’s occasionally handy in other contexts, but that’s by far the main motivation.
> > > 
> > > > On Dec 10, 2015, at 9:35 AM, Kevin Wooten \<kdubb@me.com \<mailto:kdubb@me.com\>\> wrote:
> > > > 
> > > > I get the gist of what you are requesting and I can see it might me useful but given that
> > > > 
> > > > if case .Foo(\_) == ex {  
> > > > }
> > > > 
> > > > Provides comparison, regardless of the # of associated values in .Foo, I’m not sure generating a second enum just to carry a diminished amount of information is worth it.
> > > > 
> > > > > On Dec 10, 2015, at 8:24 AM, plx via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > > > 
> > > > > FWIW, as long as we’re asking for some compiler assistance generating useful enumeration-related boilerplate, I’d like to request that something along these lines be possible in some version of Swift:
> > > > > 
> > > > > @synthesize\_case\_enum  
> > > > > enum Example {
> > > > > 
> > > > > &nbsp;&nbsp;case Foo(X)  
> > > > > &nbsp;&nbsp;case Bar  
> > > > > &nbsp;&nbsp;case Baz(Y)
> > > > > 
> > > > > }
> > > > > 
> > > > > …which would then by default expand to something like this:
> > > > > 
> > > > > enum ExampleCase : Int {  
> > > > > &nbsp;&nbsp;  
> > > > > &nbsp;&nbsp;case Foo  
> > > > > &nbsp;&nbsp;case Bar  
> > > > > &nbsp;&nbsp;case Baz
> > > > > 
> > > > > }
> > > > > 
> > > > > extension Example {
> > > > > 
> > > > > &nbsp;&nbsp;var enumerationCase: ExampleCase {  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;get {  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch self {  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Foo(\_): return .Foo  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Bar(\_): return .Bar  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case .Baz(\_): return .Baz  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > > > > &nbsp;&nbsp;}
> > > > > 
> > > > > }
> > > > > 
> > > > > …in the default case, but with some customization of the synthesized enumeration-case-enum’s details.
> > > > > 
> > > > > For the remaining proposals:
> > > > > 
> > > > > - `isX()` is nice (and should always `-\> Bool`, IMHO)  
> > > > > - `projectX()` is nice and should:  
> > > > > &nbsp;&nbsp;- \*not\* be defined for enums w/out associated values  
> > > > > &nbsp;&nbsp;- `-\> T?` for enums w/ a single associated value  
> > > > > &nbsp;&nbsp;- -\> the full tuple, for enums w/ multiple associated values, e.g.:  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;- `Foo(A,B)` yields `projectFoo() -\> (A,B)?  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;- `Event(place: Place, time: Time)` -\> (place: Place, time: Time)?  
> > > > > &nbsp;&nbsp;&nbsp;&nbsp;- (which is essentially the same as for the single-value case, just making it explicit)
> > > > > 
> > > > > …which has the benefit of predictability (and if you need more convenience, replace your tuples with actual classes-or-structs).
> > > > > 
> > > > > Finally, as convenient as the `associatedValue` proposal is down below, it seems better-served by some sort of generalized delegation construct; at a minimum, I don’t think it's that uncommon to have N cases all wrapping the same underlying type, and in such cases working with an `Any?` would feel rather clunky.
> > > > > 
> > > > > > On Dec 9, 2015, at 3:00 PM, Andrew Bennett via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > > > > 
> > > > > > I really like this solution and perhaps you can also go @projectable("empyValue") if the default name is a bad choice. See @obc for similar usage.
> > > > > > 
> > > > > > On Thursday, 10 December 2015, Alex Lew via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:  
> > > > > > Semantically, I believe enums with more than one associated value are actually just enums with one associated value, of tuple type.
> > > > > > 
> > > > > > I'm not convinced it would be bad to do magic function generation, but it's worth considering explicit syntax. If we were to use @ compile-time attributes, maybe it could be a word before the case -- like @projectable or @selectable (or some better name)?
> > > > > > 
> > > > > > enum List\<T\> {  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@projectable case Empty  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indirect case FirstAndRest(T, List\<T\>)  
> > > > > > }
> > > > > > 
> > > > > > generates:  
> > > > > > myList.isEmpty() -\> Bool
> > > > > > 
> > > > > > Another option: some sort of @reflectable attribute on the enum itself.
> > > > > > 
> > > > > > @reflectable enum Pet {  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Cat(name: String, color: String)  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Dog(name: String, breed: String)  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Bear(name: String, isHibernating: Bool)  
> > > > > > }
> > > > > > 
> > > > > > And one other option, in a very different direction, that seems weird but maybe has its benefits:
> > > > > > 
> > > > > > What if we exposed an associatedValue computed property of type Any? (It would be unit type for cases with no associated value.)
> > > > > > 
> > > > > > You could then do something like this:
> > > > > > 
> > > > > > enum Contact {  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Person(String) // name  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Business(String) // org name  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case FamilyMember(String) // relation name  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case RecentCall(Int) // a contact from caller id, only store the phone number
> > > > > > 
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func name() -\> String {  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return associatedValue as? String ?? "Unknown (\(associatedValue as! Int))"  
> > > > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > > > > > }
> > > > > > 
> > > > > > Essentially, it allows you to project out a relatively common associated value (in this case a string) without much boilerplate. It's also just one thing for the compiler to generate, instead of n. Not crazy about any of these... just brainstorming. It may also be that a concise switch-like control flow expression eliminates the need for this.
> > > > > > 
> > > > > > -Alex
> > > > > > 
> > > > > > On Wed, Dec 9, 2015 at 11:49 AM, thorsten@portableinnovations.de \<javascript:\_e(%7B%7D,'cvml','thorsten@portableinnovations.de');\> \<thorsten@portableinnovations.de \<javascript:\_e(%7B%7D,'cvml','thorsten@portableinnovations.de');\>\> wrote:  
> > > > > > I would prefer if no "magic" methods would be generated automatically, but only when marked with @derivestandardmethods (fill in better name here).
> > > > > > 
> > > > > > As to naming I like the proposal #1 by Alex.
> > > > > > 
> > > > > > What about enums with more than one associated value?
> > > > > > 
> > > > > > -Thorsten
> > > > > > 
> > > > > > Am 09.12.2015 um 07:29 schrieb Alex Lew via swift-evolution \< swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>\>:
> > > > > > 
> > > > > > > Thanks, Chris, for all the time you're putting into responding to these proposals (and the kindness with which you're responding!). I really like that solution.
> > > > > > > 
> > > > > > > Brainstorming some names for the auto-generated functions:
> > > > > > > 
> > > > > > > 1. If a case has no associated values, isX() -\> Bool is generated, where X is the case name.  
> > > > > > > &nbsp;&nbsp;&nbsp;&nbsp;If a case has an associated value of type T, asX() -\> T? is generated, where X is the case name.  
> > > > > > > &nbsp;&nbsp;&nbsp;&nbsp;This mirrors is/as? operators, which return Bool / Optional respectively.  
> > > > > > > 2. projectX() -\> Bool / projectX() -\> T?  
> > > > > > > 3. isX() -\> Bool / xValue() -\> T?
> > > > > > > 
> > > > > > > Another option (probably the wrong option, but it's worth putting out there) is that instead of returning Bool in the no-associated-value case, we return ()?. This would make me feel better about using the same naming convention (asX(), projectX(), xValue(), etc.) for each case, and would allow for != nil checks on all cases. But it would probably be a little confusing for newcomers to the language.
> > > > > > > 
> > > > > > > One (potentially misguided) question. I noticed in proposal 0002 (on removing function currying) that there are "plans to move away from the arguments-are-a-single-tuple model" in the near future. Would this also affect associated values of enums? That is, might
> > > > > > > 
> > > > > > > case Dog(name: String, age: Int, breed: String)
> > > > > > > 
> > > > > > > one day not have the semantics of a single associated value of type (name: String, age: Int, breed: String)? Or is the de-ML-ification planned only for function arguments?
> > > > > > > 
> > > > > > > -Alex
> > > > > > > 
> > > > > > > On Wed, Dec 9, 2015 at 12:45 AM, Chris Lattner \<clattner@apple.com \<javascript:\_e(%7B%7D,'cvml','clattner@apple.com');\>\> wrote:
> > > > > > > 
> > > > > > > \> On Dec 7, 2015, at 8:05 PM, Alex Lew via swift-evolution \<swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>\> wrote:  
> > > > > > > \>  
> > > > > > > \> Hi all,  
> > > > > > > \>  
> > > > > > > \> Curious to hear thoughts on allowing non-binding pattern matches to be used as boolean values outside of an if, guard, for...in, while, switch, etc. Something like:  
> > > > > > > \>  
> > > > > > > \> enum List\<T\> {  
> > > > > > > \> case Empty  
> > > > > > > \> indirect case Link(T, List\<T\>)  
> > > > > > > \>  
> > > > > > > \> func isEmpty() -\> Bool {  
> > > > > > > \> return case .Empty = self  
> > > > > > > \> }  
> > > > > > > \> }
> > > > > > > 
> > > > > > > I agree with you that this is a problem that we should solve, but I think it could be solved in a different way. Imagine if:
> > > > > > > 
> > > > > > > enum Foo {  
> > > > > > > &nbsp;&nbsp;case X(a : Float), Y, Z(a : Int)  
> > > > > > > }
> > > > > > > 
> > > > > > > automatically synthesized these members (the exact names are just a strawman proposal, not serious :-)
> > > > > > > 
> > > > > > > extension Foo {  
> > > > > > > &nbsp;&nbsp;func isX() -\> Float? {…}  
> > > > > > > &nbsp;&nbsp;func isY() -\> Bool {…}  
> > > > > > > &nbsp;&nbsp;func isZ() -\> Int? {…}  
> > > > > > > }
> > > > > > > 
> > > > > > > This would tie into all of the mechanics we have for dealing with optionals, e.g. if/let and ??
> > > > > > > 
> > > > > > > -Chris
> > > > > > > 
> > > > > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > > > > swift-evolution mailing list  
> > > > > > > swift-evolution@swift.org \<javascript:\_e(%7B%7D,'cvml','swift-evolution@swift.org');\>  
> > > > > > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > > > > 
> > > > > > Untracked with Trackbuster \<[Your contacts automatically up to date | evercontact](https://trackbuster.com/?sig&gt);
> > > > > > 
> > > > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > > > swift-evolution mailing list  
> > > > > > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > > > > > [https://lists.swift.org/mailman/listinfo/swift-evolution](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](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](https://lists.swift.org/mailman/listinfo/swift-evolution)
