[swift-evolution] ternary operator ?: suggestion

Thorsten Seitz tseitz42 at icloud.com
Tue Jan 5 11:23:58 CST 2016


While it is real nice what can be done with a library solution, the switch-expression allows more than just comparing with a value. Library solutions won't be able to achieve the following features:

- pattern matching
- where clauses
- exhaustiveness check

-Thorsten 

> Am 05.01.2016 um 18:10 schrieb Jo Albright via swift-evolution <swift-evolution at swift.org>:
> 
> I am really enjoying this conversation. I think the ternary switch is useful for advanced one line case values. I have been playing to see what can currently be done. Attached is a playground for those who want to see results… the range case takes a second to run. I know there can be optimizations done, but just wanted to add my thoughts to the conversation. 
> 
> Chose ??? to denote a ternary switch, to be inline with ? = ternary, ?? = nil coalescing … the other two operators where just placeholders. I don’t believe || is a great solution as it is a comparison operator and —> is confusing and resembles return… but again, nothing serious... just playing with playground (indulging my current obsession with custom operators).
> 
> With the below, I don’t feel there is a huge need to change the language… unless incorporating the actual switch optimization is worth it.
> 
> Thanks,
> Jo Albright
> 
> 
> // ??? loops array and returns first element where lhs == element.0
> infix operator ??? { associativity left precedence 200 }
> 
> // || merges values into an array
> infix operator || { associativity left precedence 210 }
> 
> // --> convert lhs & rhs to tuple (lhs,rhs)
> infix operator --> { associativity left precedence 220 }
> 
> func ??? <T: Equatable>(lhs: T?, rhs: [(T,AnyObject)]) -> AnyObject? {
>     
>     for r in rhs { if lhs == r.0 { return r.1 } }; return nil
>     
> }
> 
> func ??? <T: Equatable>(lhs: T, rhs: [(T,AnyObject)]) -> AnyObject? {
>     
>     for r in rhs { if lhs == r.0 { return r.1 } }; return nil
> 
> }
> 
> func || <T>(lhs: (T,AnyObject), rhs: (T,AnyObject)) -> [(T,AnyObject)] {
>     
>     return [lhs,rhs]
> 
> }
> 
> func || <T>(lhs: [(T,AnyObject)], rhs: (T,AnyObject)) -> [(T,AnyObject)] {
>     
>     return lhs + [rhs]
> 
> }
> 
> func || <T>(lhs: (Range<T>,AnyObject), rhs: (Range<T>,AnyObject)) -> [(T,AnyObject)] {
>     
>     return lhs.0.map { ($0,lhs.1) } + rhs.0.map { ($0,rhs.1) }
>     
> }
> 
> func || <T>(lhs: (Range<T>,AnyObject), rhs: (T,AnyObject)) -> [(T,AnyObject)] {
>     
>     return lhs.0.map { ($0,lhs.1) } + [rhs]
> 
> }
> 
> func || <T>(lhs: [(T,AnyObject)], rhs: (Range<T>,AnyObject)) -> [(T,AnyObject)] {
>     
>     return lhs + rhs.0.map { ($0,rhs.1) }
> 
> }
> 
> func --> <T>(lhs: T, rhs: AnyObject) -> (T,AnyObject) {
>     
>     return (lhs,rhs)
> 
> }
> 
> 
> enum LifeStatus { case Alive, Dead, Zombie }
> 
> let life: LifeStatus? = .Dead
> 
> // embedded ternary operators … how I have built a ternary switch in past
> let color1 = life == .Alive ? UIColor.greenColor() : life == .Dead ? UIColor.redColor() : life == .Zombie ? UIColor.grayColor() : UIColor.whiteColor()
> 
> // using custom operators
> let color2 = life ??? .Alive --> UIColor.greenColor() || .Dead --> UIColor.redColor() || .Zombie --> UIColor.grayColor() ?? UIColor.whiteColor()
> 
> let age = 15
> 
> // works with ranges
> let ageGroup = age ??? (0...1) --> "baby" || (2...4) --> "toddler" || (5...12) --> "kid" || (13...19) --> "teen" ?? "adult"
> 
> ageGroup // “teen”
> 
> 
> <TernarySwitch.playground.zip>
> _______________________________________________
> 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/20160105/d9e3c344/attachment-0001.html>


More information about the swift-evolution mailing list