[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