[swift-evolution] Allowing non-binding pattern matching as a Bool expression?

Alex Lew alexl.mail+swift at gmail.com
Wed Dec 9 12:56:16 CST 2015


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> {
     @projectable case Empty
     indirect case FirstAndRest(T, List<T>)
}

generates:
myList.isEmpty() -> Bool

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

@reflectable enum Pet {
     case Cat(name: String, color: String)
     case Dog(name: String, breed: String)
     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 {
     case Person(String) // name
     case Business(String) // org name
     case FamilyMember(String) // relation name
     case RecentCall(Int) // a contact from caller id, only store the phone
number

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

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 at portableinnovations.de <
thorsten at 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 at 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.
>     If a case has an associated value of type T, asX() -> T? is generated,
> where X is the case name.
>     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 at apple.com>
> wrote:
>
>>
>> > On Dec 7, 2015, at 8:05 PM, Alex Lew via swift-evolution <
>> swift-evolution at 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 {
>>   case X(a : Float), Y, Z(a : Int)
>> }
>>
>> automatically synthesized these members (the exact names are just a
>> strawman proposal, not serious :-)
>>
>> extension Foo {
>>   func isX() -> Float? {…}
>>   func isY() -> Bool {…}
>>   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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> Untracked with Trackbuster <https://trackbuster.com/?sig>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151209/f4d7a826/attachment.html>


More information about the swift-evolution mailing list