[swift-evolution] ternary operator ?: suggestion

Jo Albright me at jo2.co
Tue Jan 5 11:10:17 CST 2016


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”


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160105/eea06f50/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: TernarySwitch.playground.zip
Type: application/zip
Size: 11589 bytes
Desc: not available
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160105/eea06f50/attachment.zip>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160105/eea06f50/attachment-0001.html>


More information about the swift-evolution mailing list