ternary operator ?: suggestion


(Howard Lovatt) #1

How about removing ?: and adding a simple library:

    struct IfFalse<T> {
        let condition: Bool

        let ifTrue: () -> T

        init(condition: Bool, ifTrue: () -> T) {
            self.condition = condition
            self.ifTrue = ifTrue
        }

        func ifFalse(ifFalse: () -> T) -> T {
            if condition {
                return ifTrue()
            }
            return ifFalse()
        }
    }

    extension Bool {
        func ifTrue<T>(ifTrue: () -> T) -> IfFalse<T> {
            return IfFalse(condition: self, ifTrue: ifTrue)
        }
    }

Used:

    print(true.ifTrue{"True"}.ifFalse{"False"})
    print(false.ifTrue{"True"}.ifFalse{"False"})

Likely to be slower than ?: at the moment, but maybe could be optimised in
the future.

  -- Howard.


(Paul Ossenbruggen) #2

All,

I have continued work on my proposal. I am trying to gauge whether people feel that this syntax which is currently in the proposal is better or worse than the last two variations. The current proposal syntax:

let a = ?(x == y: a, b)
let b = ?(colorEnum : Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = ?(pickOne : “A”, “B”, “C:, default: “Z”)

The preceding is the unified ?( operator approach and is the closest to the existing ternary. but expands its capabilities to support more types of control than just bool. It is the most concise and adds no new keywords. It determines the kind of expression based upon the format inside the braces. The next version is the full keyword approach which has the same capabilities but separates each kind out:

let a = if(x == y then "A" else "B")
let b = switch(colorEnum then .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = select(pickone then "A", "B", "C", default: "Z”)

or to avoid a new keyword and be slightly more concise. This one is the hybrid approach:

let a = if(x == y : "A" else "B")
let b = switch(colorEnum : .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF)
let c = select(pickone : "A", "B", "C", default: "Z")

Note that the use of parenthesis outside the entire expression in these is to emphasize that these are expressions, can be read almost like a regular function, they serve to group the entire expression, and they would be required around the full expression only the leading keyword is outside. This will disambiguate it from the statement form. Braces are for statements and parenthesis for expressions. Putting the “then”and “else” part inside the parens also avoids the problem of “then” with the following format:

x = if cond then A else B

With this we would have support “then” in the “if" statement form and it is hard to tell it from the statement form. By putting it in parenthesis, we can put whatever we want in there.

The advantage of the second or third approach is the syntax would be custom to each kind so additional checking could be performed to ensure it is correct for the keyword provided. The keywords would be context sensitive so may not interfere with other uses of it.

These last two possibilities may address some of the issues that Jordan Rose brought up…the first is the double colon, for the separator and for the cases. The issue he mentioned second is that he did not feel my proposal addressed any of the problems with the ternary, and third he wants to keep the ? just for optionals. If the colon to separate the control, in the last one is not good, I am open to suggestions for other separators, but keep in mind, that goes even further from the ternary which may or may not be a good thing.

I think I would be happy with any of these. If the consensus is that either of the last two are preferable, I will rewrite the proposal with that in mind. Please let me know if you have any questions or have other suggestions.

Thanks,
- Paul

For latest version of proposal and see Alternatives Considered section for more details on this:
https://github.com/possen/swift-evolution/blob/master/proposals/0024.md


(Tino) #3

Hi there,

I don't think the operator has a future in Swift:
Considering that the C-style for-loop and ++/— are doomed, "?:" would look like a living fossil in the language.
"??" can handle one use case really well, and if/switch aren't that bad in the other cases.
I'm quite sure those arguments already came up in the thread, so here is my conclusion:
I don't vote for ?: to be removed, but I wouldn't like to see a replacement that has more complexity.

Best regards,
Tino


(Thorsten Seitz) #4

Sorry, but I find all these very unreadable.

IMO trying to create one-line switch expressions is a non-goal as I would always write switch expressions in multiple lines, one per case. Anything else I personally consider unreadable.

-Thorsten

···

Am 22.12.2015 um 09:11 schrieb Paul Ossenbruggen via swift-evolution <swift-evolution@swift.org>:

All,

I have continued work on my proposal. I am trying to gauge whether people feel that this syntax which is currently in the proposal is better or worse than the last two variations. The current proposal syntax:

let a = ?(x == y: a, b)
let b = ?(colorEnum : Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = ?(pickOne : “A”, “B”, “C:, default: “Z”)

The preceding is the unified ?( operator approach and is the closest to the existing ternary. but expands its capabilities to support more types of control than just bool. It is the most concise and adds no new keywords. It determines the kind of expression based upon the format inside the braces. The next version is the full keyword approach which has the same capabilities but separates each kind out:

let a = if(x == y then "A" else "B")
let b = switch(colorEnum then .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = select(pickone then "A", "B", "C", default: "Z”)

or to avoid a new keyword and be slightly more concise. This one is the hybrid approach:

let a = if(x == y : "A" else "B")
let b = switch(colorEnum : .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF)
let c = select(pickone : "A", "B", "C", default: "Z")

Note that the use of parenthesis outside the entire expression in these is to emphasize that these are expressions, can be read almost like a regular function, they serve to group the entire expression, and they would be required around the full expression only the leading keyword is outside. This will disambiguate it from the statement form. Braces are for statements and parenthesis for expressions. Putting the “then”and “else” part inside the parens also avoids the problem of “then” with the following format:

x = if cond then A else B

With this we would have support “then” in the “if" statement form and it is hard to tell it from the statement form. By putting it in parenthesis, we can put whatever we want in there.

The advantage of the second or third approach is the syntax would be custom to each kind so additional checking could be performed to ensure it is correct for the keyword provided. The keywords would be context sensitive so may not interfere with other uses of it.

These last two possibilities may address some of the issues that Jordan Rose brought up…the first is the double colon, for the separator and for the cases. The issue he mentioned second is that he did not feel my proposal addressed any of the problems with the ternary, and third he wants to keep the ? just for optionals. If the colon to separate the control, in the last one is not good, I am open to suggestions for other separators, but keep in mind, that goes even further from the ternary which may or may not be a good thing.

I think I would be happy with any of these. If the consensus is that either of the last two are preferable, I will rewrite the proposal with that in mind. Please let me know if you have any questions or have other suggestions.

Thanks,
- Paul

For latest version of proposal and see Alternatives Considered section for more details on this:
https://github.com/possen/swift-evolution/blob/master/proposals/0024.md

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Charles Constant) #5

Just goofing on this a little. What if we called it a "which" statement,
instead of a "switch" statement? It's a bit cutesy, but not too verbose,
and it makes sense if you read it aloud.

let i = which color {
? .Red: 0xFF0000,
? .Green: 0x00FF00,
? .Blue: 0x00000FF
}

let i = which boo {
? true: 1,
? false: 0,
? nil: -1
}


(Félix Cloutier) #6

In my opinion, the operator has a future. Swift is merely moving away from C-style constructs that promote mutable state. This kind of inline switch expression actually reminds me of pattern matching constructs in functional languages, and it may pick up more steam if the proposal for single-expression functions from the functional folks goes in.

I personally like the hybrid approach.

Félix

···

Le 22 déc. 2015 à 04:07:34, Tino Heth via swift-evolution <swift-evolution@swift.org> a écrit :

Hi there,

I don't think the operator has a future in Swift:
Considering that the C-style for-loop and ++/— are doomed, "?:" would look like a living fossil in the language.
"??" can handle one use case really well, and if/switch aren't that bad in the other cases.
I'm quite sure those arguments already came up in the thread, so here is my conclusion:
I don't vote for ?: to be removed, but I wouldn't like to see a replacement that has more complexity.

Best regards,
Tino
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Paul Ossenbruggen) #7

This is interesting, the “which" out front helps to keep conditional from just “floating" as it does with the ternary and using the square brackets and a dictionary like sequence is pretty cool. I did think a bit along these lines too. You could have a Array like and Dictionary like form. The melding of the nil-coalescing operator is also a nice way to deal with the else part. Not sure “which” works with the array form but perhaps.

i really would like to support pattern matching. I also have concerns about the different but not better comments I got.

- Paul

···

On Dec 22, 2015, at 7:04 AM, Félix Cloutier via swift-evolution <swift-evolution@swift.org> wrote:

I like the gist of it too, though you seem to introduce both a new keyword and a new syntax. (To be clear, I like the syntax but I'm ambivalent towards reusing switch instead of which.)

My minor suggestions would to avoid braces for things that aren't scopes; that either the comma or the the question mark is redundant in their current position (you need a start delimiter or an end delimiter but you don't need both); and that it needs a way to handle a default case if enumeration isn't exhaustive (I'd do that by returning an optional).

let i = which color (.Red: 0xff0000, .Green: 0x00ff00, .Blue: 0x0000ff) ?? 0x000000

Thinking out loud, once you remove the question marks it really looks like a dictionary literal, so maybe it could even use square brackets to close the gap.

let i = which color [.Red: 0xff0000, .Green: 0x00ff00, .Blue: 0x0000ff] ?? 0x000000

I thought about subscripting a dictionary literal in place:

[Color.Red: 0xff0000, ...][color] ?? 0x000000

but that won't support elaborate pattern matching, and I think that this is a deal breaker for the functional folks.

Félix

Le 22 déc. 2015 à 09:31:32, Charles Constant <charles@charlesism.com> a écrit :

Just goofing on this a little. What if we called it a "which" statement, instead of a "switch" statement? It's a bit cutesy, but not too verbose, and it makes sense if you read it aloud.

let i = which color {
  ? .Red: 0xFF0000,
  ? .Green: 0x00FF00,
  ? .Blue: 0x00000FF
}

let i = which boo {
  ? true: 1,
  ? false: 0,
  ? nil: -1
}

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Félix Cloutier) #8

I like the gist of it too, though you seem to introduce both a new keyword and a new syntax. (To be clear, I like the syntax but I'm ambivalent towards reusing switch instead of which.)

My minor suggestions would to avoid braces for things that aren't scopes; that either the comma or the the question mark is redundant in their current position (you need a start delimiter or an end delimiter but you don't need both); and that it needs a way to handle a default case if enumeration isn't exhaustive (I'd do that by returning an optional).

let i = which color (.Red: 0xff0000, .Green: 0x00ff00, .Blue: 0x0000ff) ?? 0x000000

Thinking out loud, once you remove the question marks it really looks like a dictionary literal, so maybe it could even use square brackets to close the gap.

let i = which color [.Red: 0xff0000, .Green: 0x00ff00, .Blue: 0x0000ff] ?? 0x000000

I thought about subscripting a dictionary literal in place:

[Color.Red: 0xff0000, ...][color] ?? 0x000000

but that won't support elaborate pattern matching, and I think that this is a deal breaker for the functional folks.

Félix

···

Le 22 déc. 2015 à 09:31:32, Charles Constant <charles@charlesism.com> a écrit :

Just goofing on this a little. What if we called it a "which" statement, instead of a "switch" statement? It's a bit cutesy, but not too verbose, and it makes sense if you read it aloud.

let i = which color {
  ? .Red: 0xFF0000,
  ? .Green: 0x00FF00,
  ? .Blue: 0x00000FF
}

let i = which boo {
  ? true: 1,
  ? false: 0,
  ? nil: -1
}


(Jordan Rose) #9

I think this is a good point. We definitely want to keep the boolean ternary operator compact for the simple cases, and that may be at odds with a general switch expression (with multi-case pattern match).

Jordan

···

On Dec 22, 2015, at 10:03 , Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:

Sorry, but I find all these very unreadable.

IMO trying to create one-line switch expressions is a non-goal as I would always write switch expressions in multiple lines, one per case. Anything else I personally consider unreadable.

-Thorsten

Am 22.12.2015 um 09:11 schrieb Paul Ossenbruggen via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

All,

I have continued work on my proposal. I am trying to gauge whether people feel that this syntax which is currently in the proposal is better or worse than the last two variations. The current proposal syntax:

let a = ?(x == y: a, b)
let b = ?(colorEnum : Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = ?(pickOne : “A”, “B”, “C:, default: “Z”)

The preceding is the unified ?( operator approach and is the closest to the existing ternary. but expands its capabilities to support more types of control than just bool. It is the most concise and adds no new keywords. It determines the kind of expression based upon the format inside the braces. The next version is the full keyword approach which has the same capabilities but separates each kind out:

let a = if(x == y then "A" else "B")
let b = switch(colorEnum then .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = select(pickone then "A", "B", "C", default: "Z”)

or to avoid a new keyword and be slightly more concise. This one is the hybrid approach:

let a = if(x == y : "A" else "B")
let b = switch(colorEnum : .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF)
let c = select(pickone : "A", "B", "C", default: "Z")

Note that the use of parenthesis outside the entire expression in these is to emphasize that these are expressions, can be read almost like a regular function, they serve to group the entire expression, and they would be required around the full expression only the leading keyword is outside. This will disambiguate it from the statement form. Braces are for statements and parenthesis for expressions. Putting the “then”and “else” part inside the parens also avoids the problem of “then” with the following format:

x = if cond then A else B

With this we would have support “then” in the “if" statement form and it is hard to tell it from the statement form. By putting it in parenthesis, we can put whatever we want in there.

The advantage of the second or third approach is the syntax would be custom to each kind so additional checking could be performed to ensure it is correct for the keyword provided. The keywords would be context sensitive so may not interfere with other uses of it.

These last two possibilities may address some of the issues that Jordan Rose brought up…the first is the double colon, for the separator and for the cases. The issue he mentioned second is that he did not feel my proposal addressed any of the problems with the ternary, and third he wants to keep the ? just for optionals. If the colon to separate the control, in the last one is not good, I am open to suggestions for other separators, but keep in mind, that goes even further from the ternary which may or may not be a good thing.

I think I would be happy with any of these. If the consensus is that either of the last two are preferable, I will rewrite the proposal with that in mind. Please let me know if you have any questions or have other suggestions.

Thanks,
- Paul

For latest version of proposal and see Alternatives Considered section for more details on this:
https://github.com/possen/swift-evolution/blob/master/proposals/0024.md

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Paul Ossenbruggen) #10

This is good feedback anything that makes people think it is more confusing is bad. I don’t want to prevent it but I think I should be emphasizing the multi line format. I am definitely not trying to come up one line switch statements. In fact most ternaries I use are multiline. I will switch to multiline in my examples.

- Paul

···

On Dec 22, 2015, at 10:03 AM, Thorsten Seitz <tseitz42@icloud.com> wrote:

Sorry, but I find all these very unreadable.

IMO trying to create one-line switch expressions is a non-goal as I would always write switch expressions in multiple lines, one per case. Anything else I personally consider unreadable.

-Thorsten

Am 22.12.2015 um 09:11 schrieb Paul Ossenbruggen via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

All,

I have continued work on my proposal. I am trying to gauge whether people feel that this syntax which is currently in the proposal is better or worse than the last two variations. The current proposal syntax:

let a = ?(x == y: a, b)
let b = ?(colorEnum : Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = ?(pickOne : “A”, “B”, “C:, default: “Z”)

The preceding is the unified ?( operator approach and is the closest to the existing ternary. but expands its capabilities to support more types of control than just bool. It is the most concise and adds no new keywords. It determines the kind of expression based upon the format inside the braces. The next version is the full keyword approach which has the same capabilities but separates each kind out:

let a = if(x == y then "A" else "B")
let b = switch(colorEnum then .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = select(pickone then "A", "B", "C", default: "Z”)

or to avoid a new keyword and be slightly more concise. This one is the hybrid approach:

let a = if(x == y : "A" else "B")
let b = switch(colorEnum : .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF)
let c = select(pickone : "A", "B", "C", default: "Z")

Note that the use of parenthesis outside the entire expression in these is to emphasize that these are expressions, can be read almost like a regular function, they serve to group the entire expression, and they would be required around the full expression only the leading keyword is outside. This will disambiguate it from the statement form. Braces are for statements and parenthesis for expressions. Putting the “then”and “else” part inside the parens also avoids the problem of “then” with the following format:

x = if cond then A else B

With this we would have support “then” in the “if" statement form and it is hard to tell it from the statement form. By putting it in parenthesis, we can put whatever we want in there.

The advantage of the second or third approach is the syntax would be custom to each kind so additional checking could be performed to ensure it is correct for the keyword provided. The keywords would be context sensitive so may not interfere with other uses of it.

These last two possibilities may address some of the issues that Jordan Rose brought up…the first is the double colon, for the separator and for the cases. The issue he mentioned second is that he did not feel my proposal addressed any of the problems with the ternary, and third he wants to keep the ? just for optionals. If the colon to separate the control, in the last one is not good, I am open to suggestions for other separators, but keep in mind, that goes even further from the ternary which may or may not be a good thing.

I think I would be happy with any of these. If the consensus is that either of the last two are preferable, I will rewrite the proposal with that in mind. Please let me know if you have any questions or have other suggestions.

Thanks,
- Paul

For latest version of proposal and see Alternatives Considered section for more details on this:
https://github.com/possen/swift-evolution/blob/master/proposals/0024.md

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Paul Ossenbruggen) #11

I have definitely been trying to keep this in mind with these designs. Compact representations should be possible.

···

On Dec 22, 2015, at 10:07 AM, Jordan Rose <jordan_rose@apple.com> wrote:

I think this is a good point. We definitely want to keep the boolean ternary operator compact for the simple cases, and that may be at odds with a general switch expression (with multi-case pattern match).

Jordan

On Dec 22, 2015, at 10:03 , Thorsten Seitz via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sorry, but I find all these very unreadable.

IMO trying to create one-line switch expressions is a non-goal as I would always write switch expressions in multiple lines, one per case. Anything else I personally consider unreadable.

-Thorsten

Am 22.12.2015 um 09:11 schrieb Paul Ossenbruggen via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

All,

I have continued work on my proposal. I am trying to gauge whether people feel that this syntax which is currently in the proposal is better or worse than the last two variations. The current proposal syntax:

let a = ?(x == y: a, b)
let b = ?(colorEnum : Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = ?(pickOne : “A”, “B”, “C:, default: “Z”)

The preceding is the unified ?( operator approach and is the closest to the existing ternary. but expands its capabilities to support more types of control than just bool. It is the most concise and adds no new keywords. It determines the kind of expression based upon the format inside the braces. The next version is the full keyword approach which has the same capabilities but separates each kind out:

let a = if(x == y then "A" else "B")
let b = switch(colorEnum then .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = select(pickone then "A", "B", "C", default: "Z”)

or to avoid a new keyword and be slightly more concise. This one is the hybrid approach:

let a = if(x == y : "A" else "B")
let b = switch(colorEnum : .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF)
let c = select(pickone : "A", "B", "C", default: "Z")

Note that the use of parenthesis outside the entire expression in these is to emphasize that these are expressions, can be read almost like a regular function, they serve to group the entire expression, and they would be required around the full expression only the leading keyword is outside. This will disambiguate it from the statement form. Braces are for statements and parenthesis for expressions. Putting the “then”and “else” part inside the parens also avoids the problem of “then” with the following format:

x = if cond then A else B

With this we would have support “then” in the “if" statement form and it is hard to tell it from the statement form. By putting it in parenthesis, we can put whatever we want in there.

The advantage of the second or third approach is the syntax would be custom to each kind so additional checking could be performed to ensure it is correct for the keyword provided. The keywords would be context sensitive so may not interfere with other uses of it.

These last two possibilities may address some of the issues that Jordan Rose brought up…the first is the double colon, for the separator and for the cases. The issue he mentioned second is that he did not feel my proposal addressed any of the problems with the ternary, and third he wants to keep the ? just for optionals. If the colon to separate the control, in the last one is not good, I am open to suggestions for other separators, but keep in mind, that goes even further from the ternary which may or may not be a good thing.

I think I would be happy with any of these. If the consensus is that either of the last two are preferable, I will rewrite the proposal with that in mind. Please let me know if you have any questions or have other suggestions.

Thanks,
- Paul

For latest version of proposal and see Alternatives Considered section for more details on this:
https://github.com/possen/swift-evolution/blob/master/proposals/0024.md

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Thorsten Seitz) #12

I still don't understand why we are not simply writing

let i = switch color {
        case .Red: 0xFF0000
        case .Green: 0x00FF00
        case .Blue: 0x00000FF
    }

No additional keywords, no wondering why different keywords and different syntax is used for something so similar. And not really longer than the alternative proposals (I do not count swapping "case" with "?" to be a gain, especially not if it requires to add a comma after each case).

-Thorsten

···

Am 22.12.2015 um 15:31 schrieb Charles Constant via swift-evolution <swift-evolution@swift.org>:

Just goofing on this a little. What if we called it a "which" statement, instead of a "switch" statement? It's a bit cutesy, but not too verbose, and it makes sense if you read it aloud.

let i = which color {
  ? .Red: 0xFF0000,
  ? .Green: 0x00FF00,
  ? .Blue: 0x00000FF
}

let i = which boo {
  ? true: 1,
  ? false: 0,
  ? nil: -1
}

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Craig Cruden) #13

I see no need to remove the existing ternary command — for simple conditions of assignment (one condition, one then value, one else value) that fit on one line…. nested conditions regardless of syntax can quickly become nightmare.

What I would like to be able to do is write code in a functional paradigm by default, falling back to OOP / imperative where it makes sense because of the model or because of performance requirements. Preferably merging my other favorite language into Swift where it makes sense. Flow control becomes more of a byproduct of breaking things down into smaller and smaller tasks (recursion), and “statements" such as switch / match / if become just functions/expressions unto themselves. This means that the switch / match / if actually returns a value which if you are programming in a less functional way can just be ignored (maybe also by the compiler) and the “expressions” fall back to simple flow control statements.

C style syntax is not bad just because it is C style - the vast majority of languages are derived from C style syntax - being different just to be different should not be the goal.

···

On 2015-12-22, at 20:59:06, Félix Cloutier via swift-evolution <swift-evolution@swift.org> wrote:

In my opinion, the operator has a future. Swift is merely moving away from C-style constructs that promote mutable state. This kind of inline switch expression actually reminds me of pattern matching constructs in functional languages, and it may pick up more steam if the proposal for single-expression functions from the functional folks goes in.

I personally like the hybrid approach.

Félix

Le 22 déc. 2015 à 04:07:34, Tino Heth via swift-evolution <swift-evolution@swift.org> a écrit :

Hi there,

I don't think the operator has a future in Swift:
Considering that the C-style for-loop and ++/— are doomed, "?:" would look like a living fossil in the language.
"??" can handle one use case really well, and if/switch aren't that bad in the other cases.
I'm quite sure those arguments already came up in the thread, so here is my conclusion:
I don't vote for ?: to be removed, but I wouldn't like to see a replacement that has more complexity.

Best regards,
Tino
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Angelo Villegas) #14

I for one feels like the ternary operator still has a future with Swift.

If the discussion with ternary will go on though, I would like to weigh in a suggestion:

    let a | x == y = a
          > otherwise = b

    let b | colour.Red = 0xff0000
          > colour.Green = 0x00ff00
          > colour.Blue = 0x0000ff
          > otherwise = 0x000000

My rule of thumb for a style like this is that if you can read it as if it was English (read | (bar) as "when", | otherwise (bar otherwise) as "otherwise" and = as "is" or "be"), you're probably doing something right.


(David Waite) #15

In the case where your input is hashable, you could just do:

let i = [.Red:0xff0000, .Green:0x00ff00, .Blue:0x0000ff][color]

this would mean that color must be a Color and not an Optional<Color> (because of swift 2.x limitations)

-DW

···

On Dec 22, 2015, at 8:04 AM, Félix Cloutier via swift-evolution <swift-evolution@swift.org> wrote:

I like the gist of it too, though you seem to introduce both a new keyword and a new syntax. (To be clear, I like the syntax but I'm ambivalent towards reusing switch instead of which.)

My minor suggestions would to avoid braces for things that aren't scopes; that either the comma or the the question mark is redundant in their current position (you need a start delimiter or an end delimiter but you don't need both); and that it needs a way to handle a default case if enumeration isn't exhaustive (I'd do that by returning an optional).

let i = which color (.Red: 0xff0000, .Green: 0x00ff00, .Blue: 0x0000ff) ?? 0x000000

Thinking out loud, once you remove the question marks it really looks like a dictionary literal, so maybe it could even use square brackets to close the gap.

let i = which color [.Red: 0xff0000, .Green: 0x00ff00, .Blue: 0x0000ff] ?? 0x000000

I thought about subscripting a dictionary literal in place:

[Color.Red: 0xff0000, ...][color] ?? 0x000000

but that won't support elaborate pattern matching, and I think that this is a deal breaker for the functional folks.

Félix

Le 22 déc. 2015 à 09:31:32, Charles Constant <charles@charlesism.com> a écrit :

Just goofing on this a little. What if we called it a "which" statement, instead of a "switch" statement? It's a bit cutesy, but not too verbose, and it makes sense if you read it aloud.

let i = which color {
  ? .Red: 0xFF0000,
  ? .Green: 0x00FF00,
  ? .Blue: 0x00000FF
}

let i = which boo {
  ? true: 1,
  ? false: 0,
  ? nil: -1
}

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Craig Cruden) #16

IMHO, I think the issue is that (at least in my case) we may be trying to create expression versions of “if” and “switch” (multi-line) and not are trying to create them in such a way as to keep statements and expressions as separate syntax / keywords…. which is leading to a more cryptic solution. Not being a compiler guy, I have no idea what the complication is with regards to why the syntax has to be different.

Or we are trying to create new syntax for a simple C ternary because somewhere along the line some people have an aversion to syntax just because C uses it.

Those two are combining in an unholy alliance :o

Craig

···

On 2015-12-23, at 1:07:26, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

I think this is a good point. We definitely want to keep the boolean ternary operator compact for the simple cases, and that may be at odds with a general switch expression (with multi-case pattern match).

Jordan

On Dec 22, 2015, at 10:03 , Thorsten Seitz via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sorry, but I find all these very unreadable.

IMO trying to create one-line switch expressions is a non-goal as I would always write switch expressions in multiple lines, one per case. Anything else I personally consider unreadable.

-Thorsten

Am 22.12.2015 um 09:11 schrieb Paul Ossenbruggen via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

All,

I have continued work on my proposal. I am trying to gauge whether people feel that this syntax which is currently in the proposal is better or worse than the last two variations. The current proposal syntax:

let a = ?(x == y: a, b)
let b = ?(colorEnum : Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = ?(pickOne : “A”, “B”, “C:, default: “Z”)

The preceding is the unified ?( operator approach and is the closest to the existing ternary. but expands its capabilities to support more types of control than just bool. It is the most concise and adds no new keywords. It determines the kind of expression based upon the format inside the braces. The next version is the full keyword approach which has the same capabilities but separates each kind out:

let a = if(x == y then "A" else "B")
let b = switch(colorEnum then .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = select(pickone then "A", "B", "C", default: "Z”)

or to avoid a new keyword and be slightly more concise. This one is the hybrid approach:

let a = if(x == y : "A" else "B")
let b = switch(colorEnum : .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF)
let c = select(pickone : "A", "B", "C", default: "Z")

Note that the use of parenthesis outside the entire expression in these is to emphasize that these are expressions, can be read almost like a regular function, they serve to group the entire expression, and they would be required around the full expression only the leading keyword is outside. This will disambiguate it from the statement form. Braces are for statements and parenthesis for expressions. Putting the “then”and “else” part inside the parens also avoids the problem of “then” with the following format:

x = if cond then A else B

With this we would have support “then” in the “if" statement form and it is hard to tell it from the statement form. By putting it in parenthesis, we can put whatever we want in there.

The advantage of the second or third approach is the syntax would be custom to each kind so additional checking could be performed to ensure it is correct for the keyword provided. The keywords would be context sensitive so may not interfere with other uses of it.

These last two possibilities may address some of the issues that Jordan Rose brought up…the first is the double colon, for the separator and for the cases. The issue he mentioned second is that he did not feel my proposal addressed any of the problems with the ternary, and third he wants to keep the ? just for optionals. If the colon to separate the control, in the last one is not good, I am open to suggestions for other separators, but keep in mind, that goes even further from the ternary which may or may not be a good thing.

I think I would be happy with any of these. If the consensus is that either of the last two are preferable, I will rewrite the proposal with that in mind. Please let me know if you have any questions or have other suggestions.

Thanks,
- Paul

For latest version of proposal and see Alternatives Considered section for more details on this:
https://github.com/possen/swift-evolution/blob/master/proposals/0024.md

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Matthew Johnson) #17

This looks reasonable in declarations but how would it work in expressions? Or are you suggesting that it is only usable for declarations?

···

Sent from my iPad

On Dec 22, 2015, at 9:25 AM, Angelo Villegas via swift-evolution <swift-evolution@swift.org> wrote:

I for one feels like the ternary operator still has a future with Swift.

If the discussion with ternary will go on though, I would like to weigh in a suggestion:

    let a | x == y = a
          > otherwise = b

    let b | colour.Red = 0xff0000
          > colour.Green = 0x00ff00
          > colour.Blue = 0x0000ff
          > otherwise = 0x000000

My rule of thumb for a style like this is that if you can read it as if it was English (read | (bar) as "when", | otherwise (bar otherwise) as "otherwise" and = as "is" or "be"), you're probably doing something right.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Paul Ossenbruggen) #18

These are some very interesting ideas to explore. I definitely want to play with the bar character as a separator. This could nicely deal with the problem of the double colon in the hybrid approach.

I like this thinking as it really explores a different approach.It is cool the way it can be lined up like that and it reads well when you think of the bar as “when”. I am a little concerned that some may be considered weird but not better than the ternary, which is some of the feedback I got from my earlier designs. I suppose if we are making a breaking change though, that may be okay but keep in mind it there should be a reason for making it different. This suggestion definitely has a different feel than the existing ternary. How do people feel about that?

I also agree, I am not sure how that would work for expressions.

···

On Dec 22, 2015, at 7:36 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

This looks reasonable in declarations but how would it work in expressions? Or are you suggesting that it is only usable for declarations?

Sent from my iPad

On Dec 22, 2015, at 9:25 AM, Angelo Villegas via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I for one feels like the ternary operator still has a future with Swift.

If the discussion with ternary will go on though, I would like to weigh in a suggestion:

    let a | x == y = a
          > otherwise = b

    let b | colour.Red = 0xff0000
          > colour.Green = 0x00ff00
          > colour.Blue = 0x0000ff
          > otherwise = 0x000000

My rule of thumb for a style like this is that if you can read it as if it was English (read | (bar) as "when", | otherwise (bar otherwise) as "otherwise" and = as "is" or "be"), you're probably doing something right.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Paul Ossenbruggen) #19

I think trying to mix statements and expressions will definitely lead to a more complex solution I have tried going down that path. The second and third approaches in my email last night attempt to straddle the line between more cryptic ? syntax of the ternary and the if, switch, approach.

I don’t have an aversion to the ternary just because it is in C. In fact, when I first started writing the proposal, it was intending to keep it exactly as is, but it became clear that there would be two different forms, and that what I was proposing would be better than ternary. I think my proposal addresses many of the shortcomings of the ternary and provides more capability.

Just to list a few, but in my proposal I have a much more exhaustive list:

• it is hard to tell when a ternary begins and ends, especially when nested.
• It is not until you get to the question mark that you realize it is a ternary.
• it is hard to read something like this x = y == z ? “A”, “B” does the == get read first or second.

With my proposal all these issues are addressed which makes it better than ternary.

- Paul

···

On Dec 22, 2015, at 10:14 AM, Craig Cruden via swift-evolution <swift-evolution@swift.org> wrote:

IMHO, I think the issue is that (at least in my case) we may be trying to create expression versions of “if” and “switch” (multi-line) and not are trying to create them in such a way as to keep statements and expressions as separate syntax / keywords…. which is leading to a more cryptic solution. Not being a compiler guy, I have no idea what the complication is with regards to why the syntax has to be different.

Or we are trying to create new syntax for a simple C ternary because somewhere along the line some people have an aversion to syntax just because C uses it.

Those two are combining in an unholy alliance :o

Craig

On 2015-12-23, at 1:07:26, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I think this is a good point. We definitely want to keep the boolean ternary operator compact for the simple cases, and that may be at odds with a general switch expression (with multi-case pattern match).

Jordan

On Dec 22, 2015, at 10:03 , Thorsten Seitz via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sorry, but I find all these very unreadable.

IMO trying to create one-line switch expressions is a non-goal as I would always write switch expressions in multiple lines, one per case. Anything else I personally consider unreadable.

-Thorsten

Am 22.12.2015 um 09:11 schrieb Paul Ossenbruggen via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

All,

I have continued work on my proposal. I am trying to gauge whether people feel that this syntax which is currently in the proposal is better or worse than the last two variations. The current proposal syntax:

let a = ?(x == y: a, b)
let b = ?(colorEnum : Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = ?(pickOne : “A”, “B”, “C:, default: “Z”)

The preceding is the unified ?( operator approach and is the closest to the existing ternary. but expands its capabilities to support more types of control than just bool. It is the most concise and adds no new keywords. It determines the kind of expression based upon the format inside the braces. The next version is the full keyword approach which has the same capabilities but separates each kind out:

let a = if(x == y then "A" else "B")
let b = switch(colorEnum then .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF, default: 0xFFFFFF)
let c = select(pickone then "A", "B", "C", default: "Z”)

or to avoid a new keyword and be slightly more concise. This one is the hybrid approach:

let a = if(x == y : "A" else "B")
let b = switch(colorEnum : .Red: 0xFF0000, .Green: 0x00FF00, .Blue: 0x00000FF)
let c = select(pickone : "A", "B", "C", default: "Z")

Note that the use of parenthesis outside the entire expression in these is to emphasize that these are expressions, can be read almost like a regular function, they serve to group the entire expression, and they would be required around the full expression only the leading keyword is outside. This will disambiguate it from the statement form. Braces are for statements and parenthesis for expressions. Putting the “then”and “else” part inside the parens also avoids the problem of “then” with the following format:

x = if cond then A else B

With this we would have support “then” in the “if" statement form and it is hard to tell it from the statement form. By putting it in parenthesis, we can put whatever we want in there.

The advantage of the second or third approach is the syntax would be custom to each kind so additional checking could be performed to ensure it is correct for the keyword provided. The keywords would be context sensitive so may not interfere with other uses of it.

These last two possibilities may address some of the issues that Jordan Rose brought up…the first is the double colon, for the separator and for the cases. The issue he mentioned second is that he did not feel my proposal addressed any of the problems with the ternary, and third he wants to keep the ? just for optionals. If the colon to separate the control, in the last one is not good, I am open to suggestions for other separators, but keep in mind, that goes even further from the ternary which may or may not be a good thing.

I think I would be happy with any of these. If the consensus is that either of the last two are preferable, I will rewrite the proposal with that in mind. Please let me know if you have any questions or have other suggestions.

Thanks,
- Paul

For latest version of proposal and see Alternatives Considered section for more details on this:
https://github.com/possen/swift-evolution/blob/master/proposals/0024.md

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Félix Cloutier) #20

This is essentially the latest proposal that Paul offered.

Félix

···

Le 22 déc. 2015 à 13:11:37, Thorsten Seitz <tseitz42@icloud.com> a écrit :

I still don't understand why we are not simply writing

let i = switch color {
        case .Red: 0xFF0000
        case .Green: 0x00FF00
        case .Blue: 0x00000FF
    }

No additional keywords, no wondering why different keywords and different syntax is used for something so similar. And not really longer than the alternative proposals (I do not count swapping "case" with "?" to be a gain, especially not if it requires to add a comma after each case).

-Thorsten

Am 22.12.2015 um 15:31 schrieb Charles Constant via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

Just goofing on this a little. What if we called it a "which" statement, instead of a "switch" statement? It's a bit cutesy, but not too verbose, and it makes sense if you read it aloud.

let i = which color {
  ? .Red: 0xFF0000,
  ? .Green: 0x00FF00,
  ? .Blue: 0x00000FF
}

let i = which boo {
  ? true: 1,
  ? false: 0,
  ? nil: -1
}

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution