[swift-evolution] ternary operator ?: suggestion

Paul Ossenbruggen possen at gmail.com
Wed Jan 6 13:03:14 CST 2016


To point 1: I agree it needs a new name, I came up with the “demux expression” but maybe there is a better name. 

To point 2: Taking a more complex example which uses _ adapted from the swift book. The original 

switch somePoint {
case (0, 0):
    print("(0, 0) is at the origin")
case (_, 0):
    print("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
    print("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
    print("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
    print("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}

with the proposed format so the underscore does kind of act like a default in the existing switch statement: 

let string = somePoint ?
    (0, 0): 		"(0, 0) is at the origin"
    (_, 0):		"(\(somePoint.0), 0) is on the x-axis"
    (0, _):		"(0, \(somePoint.1)) is on the y-axis"
    (-2...2, -2...2):   "(\(somePoint.0), \(somePoint.1)) is inside the box"
    (_, _):		"(\(somePoint.0), \(somePoint.1)) is outside of the box"

So, it kind of used like a default. Note, I am suggesting that this also work, if it seems too loose, this would help add structure in more complex cases. 

let string = somePoint ?
    case (0, 0): 		"(0, 0) is at the origin"
    case (_, 0):		"(\(somePoint.0), 0) is on the x-axis"
    case (0, _):		"(0, \(somePoint.1)) is on the y-axis"
    case (-2...2, -2...2):   	"(\(somePoint.0), \(somePoint.1)) is inside the box"
    default:			"(\(somePoint.0), \(somePoint.1)) is outside of the box"

So you could still do as you suggest: 

let string = somePoint ?
    (0, 0): 		"(0, 0) is at the origin"
    (_, 0):		"(\(somePoint.0), 0) is on the x-axis"
    (0, _):		"(0, \(somePoint.1)) is on the y-axis"
    (-2...2, -2...2):   "(\(somePoint.0), \(somePoint.1)) is inside the box"
    default:		"(\(somePoint.0), \(somePoint.1)) is outside of the box"

Mathew says that he thinks that parenthesis should not be required, but I think it seems a little loose without them. It is similar to how control structures have { } around things and I am worried about creating ambiguity. 

let string = somePoint ?(
    (0, 0): 		"(0, 0) is at the origin"
    (_, 0):		"(\(somePoint.0), 0) is on the x-axis"
    (0, _):		"(0, \(somePoint.1)) is on the y-axis"
    (-2...2, -2...2):   "(\(somePoint.0), \(somePoint.1)) is inside the box"
    (_, _):		"(\(somePoint.0), \(somePoint.1)) is outside of the box"
}

I don’t think the “case” and “default" is as necessary with the parenthesis around it. 

Arg! I still want to put the control value inside though! It just kind of floats out there otherwise. 

let string = ?(somePoint,
    (0, 0): 		"(0, 0) is at the origin"
    (_, 0):		"(\(somePoint.0), 0) is on the x-axis"
    (0, _):		"(0, \(somePoint.1)) is on the y-axis"
    (-2...2, -2...2):   "(\(somePoint.0), \(somePoint.1)) is inside the box"
    (_, _):		"(\(somePoint.0), \(somePoint.1)) is outside of the box"
}

To point 3: That the ternary presents confusion by using the colon. I think that confusion drops away with the _ as the default. The rule would be that switch expressions would always be exhaustively specified or must use default. For the boolean and index forms the colon does not create confusion, they are used to return the case that does not match one of the choices. 

let fb = pickOne ? “A", "B", "C", "D", "E", "F", "G” : "Z"
let fe = truthy == truth ? “unlikely” : “likely”

or:

let fb = pickOne ? “A", "B", "C", "D", "E", "F", "G” default:"Z"
let fe = truthy == truth ? “unlikely” default: “likely”

or maybe:

let fb = pickOne ? “A", "B", "C", "D", "E", "F", "G” else:"Z"
let fe = truthy == truth ? “unlikely” else: “likely”

Not necessarily recommending that last one but trying it out. Since boolean “ifs" use “else" rather than default. 

> 
> On Jan 6, 2016, at 9:03 AM, Jo Albright <me at jo2.co> wrote:
> 
> Just a couple of thoughts swirling in my brain. 
> 
> 1. Ternary means : composed of three parts …. if we add case functionality, it no longer is a ternary and should be renamed (ex : nil coalescing … was used instead of calling it a ternary optional). Would love to hear thoughts on what names it could have … if the proposal moves forward.
> 
> ---
> 
> I am leaning towards this pattern (someone else introduced), yet I don’t feel it is perfect.
> 
> let val = color ?  .Red: 0xFF0000, .Green: 0x00FF00,  .Blue: 0x0000FF,   _: 0xFFFFFF
> 
> 2. I have a problem with “_”. I don’t agree with it being the default value. It is currently used to discard or ignore values … using it as a default will add unnecessary confusion that does not align with Swift. Writing out the word default instead of _ is only 6 more characters. Please correct me if I am wrong on this note.
> 
> let val = color ?  .Red: 0xFF0000, .Green: 0x00FF00,  .Blue: 0x0000FF,   default: 0xFFFFFF
> 
> 3. Having “?” for the Bool operator and “:” for the cases presents confusion with the current ? : ternary design pattern. This is another potential issue … just not a big of a deal as the “default as _”.
> 
> let val = color case .Red: 0xFF0000, .Green: 0x00FF00,  .Blue: 0x0000FF,   default: 0xFFFFFF
> let val = color ???  .Red: 0xFF0000, .Green: 0x00FF00,  .Blue: 0x0000FF,   default: 0xFFFFFF
> 
> And some less serious ones.
> 
> switch let val = color case .Red: 0xFF0000, .Green: 0x00FF00,  .Blue: 0x0000FF,   default: 0xFFFFFF
> case let val = color ??? .Red: 0xFF0000, .Green: 0x00FF00,  .Blue: 0x0000FF,   default: 0xFFFFFF
> 
> I do believe this functionality is worth adding to Swift core lib. I just want to see it as closely aligned with Swift as possible.
> 
>  Nerd . Designer . Developer
> Jo Albright

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160106/66ebef69/attachment.html>


More information about the swift-evolution mailing list