[swift-evolution] [Idea] Find alternatives to `switch self`

Maximilian Hünenberger m.huenenberger at me.com
Wed Mar 23 07:46:11 CDT 2016


Hi Brent,

First of all, I like your suggestions however there was already a proposal about "Pattern matching partial functions" which could address this and many other issues (See pull request #111; unfortunately the discussion doesn't went on... Hopefully this time).

This proposal addresses the issue of switch statements which return something in every "case". It uses special closures as unapplied switch statements and uses a global "match" function:

func match<T, U>(value: T, closure: T -> U) -> U {
         return closure(value)
}

The case you describe could now be rewritten to:

// no returns
enum Suit: Int {
       case Hearts, Spades, Diamonds, Clubs

       static var all: Suit[] { return [ Hearts, Spades, Diamonds, Clubs ] }

       var description: String {
           return match(self) {
               case .Hearts: "♥️"
               case .Spades: "♠️"
               case .Diamonds: "♦️"
               case .Clubs: "♣️"
           }
       }

       var isRed: Bool {
           return match(self) {
               case .Hearts, .Diamonds: true
               case .Spades, .Clubs: false
           }
       }
   }

// or even without case (which was highly controversial in the discussions)
enum Suit: Int {
       case Hearts, Spades, Diamonds, Clubs

       static var all: Suit[] { return [ Hearts, Spades, Diamonds, Clubs ] }

       var description: String {
           return match(self) {
               cases .Hearts: "♥️", .Spades: "♠️", .Diamonds: "♦️", .Clubs: "♣️"
           }
       }

       var isRed: Bool {
           return match(self) {
               cases .Hearts, .Diamonds: true, .Spades, .Clubs: false
           }
       }
   }

What do you think about this?

Kind regards
- Maximilian

> Am 23.03.2016 um 11:13 schrieb Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org>:
> 
> If you've written enums before, you've no doubt noticed the irritating phenomenon of `switch self` being absolutely everywhere. I first discovered this in some of my very first Swift code, code so old we were still using the `T[]` shorthand syntax:
> 
>    enum Suit: Int {
>        case Hearts, Spades, Diamonds, Clubs
> 
>        static var all: Suit[] { return [ Hearts, Spades, Diamonds, Clubs ] }
> 
>        var description: String {
>            switch(self) {
>            case .Hearts:
>                return "♥️"
>            case .Spades:
>                return "♠️"
>            case .Diamonds:
>                return "♦️"
>            case .Clubs:
>                return "♣️"
>            }
>        }
> 
>        var isRed: Bool {
>            switch(self) {
>            case .Hearts, .Diamonds:
>                return true
>            case .Spades, .Clubs:
>                return false
>            }
>        }
>    }
> 
> It would be nice if we could somehow eliminate that. I have two suggestions:
> 
> * Implicitly switch on `self` at the top level of a function or accessor (or at least an enum one with top-level `case` statements).
> 
>    enum Suit: Int {
>        case Hearts, Spades, Diamonds, Clubs
> 
>        static var all = [ Hearts, Spades, Diamonds, Clubs ]
> 
>        var description: String {
>        case .Hearts:
>            return "♥️"
>        case .Spades:
>            return "♠️"
>        case .Diamonds:
>            return "♦️"
>        case .Clubs:
>            return "♣️"
>        }
> 
>        var isRed: Bool {
>        case .Hearts, .Diamonds:
>            return true
>        case .Spades, .Clubs:
>            return false
>        }
>    }
> 
> * Allow you to attach member definitions to particular cases. It would be an error if they didn't all define the same members, unless there was a top-level catchall.
> 
>    enum Suit: Int {
>        var isRed: Bool { return false }
> 
>        case Hearts {
>            let description: String { return "♥️" }
>            let isRed: Bool { return true }
>        }
>        case Spades {
>            let description: String { return  "♠️" }
>        }
>        case Diamonds {
>            let description: String { return  "♦️" }
>            let isRed: Bool { return true }
>        }
>        case Clubs {
>            let description: String { return  "♣️" }
>        }
> 
>        static var all = [ Hearts, Spades, Diamonds, Clubs ]
>    }
> Any thoughts? This has, to be honest, bothered me since approximately the third day I used the language; I'd love to address it sooner or later.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160323/0ec2eced/attachment.html>


More information about the swift-evolution mailing list