[swift-evolution] ternary operator ?: suggestion

Alex Lew alexl.mail+swift at gmail.com
Sun Dec 6 15:32:14 CST 2015


To clarify, I would want parens around the entire expression (only when
necessary). So

let myColor = match yourColor
case .Blue :  .Red
case .Green: .Blue
case .Red: .Green
default: .Yellow

or

let myColor = match boolCondition
  case true: .Blue
  case false: .Red

or

let myColor = match boolCondition
  case true: (match yourColor
                      case .Red: .Blue
                      default: .Yellow)
  case false: .Red

But I actually think that the parens are unnecessary, as long as we require
matches to be exhaustive and for there to be no unreachable cases.

On Sun, Dec 6, 2015 at 4:17 PM, Paul Ossenbruggen <possen at gmail.com> wrote:

> I agree that ? may imply optional, this may be similar to what you
> suggested, just filling in the example: Not sure parenthesis are better
> than braces though:
>
> et myColor = match yourColor ( .Blue :  .Red, .Green: .Blue, .Red: .Green,
> default: .Yellow )
>
> let myColor = match yourColor ( case .Blue : .Red; case .Green: .Blue;
>  case .Red: .Green; default: .Yellow )
>
> let myColor = match yourColor (
> case .Blue :  .Reds
> case .Green: .Blue
> case .Red: .Green
> default: .Yellow
> )
>
> let myColor = match yourColor (
> .Blue :  .Reds
> .Green: .Blue
> .Red: .Green
> default: .Yellow
> )
>
> let myColor = match boollCondition ( .Blue, .Red )
>
>
>
> On Dec 6, 2015, at 12:54 PM, Alex Lew < alexl.mail+swift at gmail.com>
> wrote:
>
> Hmm. Something about braces inside expressions just feels wrong to me.
>
> I also read switch? and if? as being some optional-related versions of
> switch and if. And I don't love putting the condition / value-to-switch-on *before
> *the keyword, if we're going to use a keyword.
>
> (Also: exhaustiveness checking *could *theoretically allow resolution of
> ambiguity in nested switch expressions. We would just have to require that
> as soon as you've exhausted all possibilities, you don't add more cases and
> the expression is over.)
>
> On Sun, Dec 6, 2015 at 3:46 PM, Paul Ossenbruggen <possen at gmail.com>
> wrote:
>
>> Yep probably does need braces: So for switch? if? suggestion i just
>> made.
>>
>> let myColor = yourColor switch? { .Blue :  .Red, .Green: .Blue, .Red:
>> .Green, default: .Yellow }
>>
>> let myColor = yourColor switch? { case .Blue : .Red; case .Green: .Blue;
>>  case .Red: .Green; default: .Yellow }
>>
>> let myColor = yourColor switch? {
>> case .Blue :  .Reds
>> case .Green: .Blue
>> case .Red: .Green
>> default: .Yellow
>> }
>>
>> let myColor = yourColor switch? {
>> .Blue :  .Reds
>> .Green: .Blue
>> .Red: .Green
>> default: .Yellow
>> }
>>
>> let myColor = condition if?  { .Blue; .Red }
>>
>> I don’t find that looks bad.
>>
>> - Paul
>>
>>
>> On Dec 6, 2015, at 12:24 PM, Alex Lew via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> Thanks for the feedback, Matthew. It's sensible to me to consider
>> dropping the ternary operator. I like it because the analogy "C's if is to
>> Swift's if as C's ternary operator is to Swift's ternary operator" is (sort
>> of) satisfied. But it is also confusing, both for the reasons you mention,
>> and because ? has other meanings in Swift:
>>
>>  // compiler error without space betw thatColor and ?
>> let thisColor = thatColor?
>>      case .Red: .Green
>>      default: .Blue
>>
>> On the other hand, is it really worth it to have control flow expressions
>> if they don't let your code look nicer?
>>
>> let thisColor = switch thatColor {
>>      case .Red:
>>           return .Green;
>>      default:
>>           return .Yellow;
>> }
>>
>> really isn't much nicer than
>>
>> let thisColor: Color
>> switch thatColor {
>>      case .Red:
>>           thisColor = .Green
>>      default:
>>           thisColor = .Yellow
>> }
>>
>> Maybe we could do a compromise, something like
>>
>> let thisColor = switch thatColor
>>      case .Red: .Green // must be an expression
>>      default: .Yellow      // must be an expression
>>
>> Or we could introduce a new keyword? Like   *match*:
>>
>> let thisColor = match thatColor
>>       case .Red: .Green    // must be an expression
>>       default: .Yellow         // must be an expression
>>
>>
>> I sort of like the new-keyword approach, because even though this is
>> similar to a switch, it's not a switch: there's no fallthrough, you can't
>> put statements inside, etc.
>>
>> The problem with all these proposals:
>>
>> let thisColor = match thatColor
>>      case .Red: match thatOtherColor
>>                            case .Blue: .Green
>>                            case .Pink: .Yellow
>>                            default: .Orange
>>      default: .Orange
>>
>> is ambiguous. (Does case .Pink match thatColor or thatOtherColor? We can
>> know because of exhaustiveness checking, but this won't always work.) You
>> could solve this problem either by using parentheses around the whole
>> expression when necessary
>>
>> let thisColor = match thatColor
>>      case .Red: (match thatOtherColor
>>                            case .Blue: .Green
>>                            case .Pink: .Yellow
>>                            default: .Orange)
>>      default: .Orange
>>
>> or by adding curly braces in again
>>
>> let thisColor = match thatColor {
>>      case .Red: match thatOtherColor {
>>                            case .Blue: .Green
>>                            case .Pink: .Yellow
>>                            default: .Orange
>>                         }
>>      default: .Orange
>> }
>>
>> But that starts to look like switch again. (Of course, the best way to
>> handle this is as a programmer is to just switch on the tuple (thatColor,
>> thatOtherColor), but the language should allow for nested control
>> expressions.)
>>
>>
>> On Sun, Dec 6, 2015 at 2:48 PM, Matthew Johnson via swift-evolution   <
>> swift-evolution at swift.org>  wrote:
>>
>>> I am not a fan of this approach based on the ternary operator.  The
>>> ternary operator is already a bit of an anomaly in that all other operators
>>> are unary or binary and do not perform any control flow (beyond possibly
>>> short circuiting an autoclosure argument).
>>>
>>> I would much rather features that perform control flow continue to use
>>> keywords, but allow them to be expressions.
>>>
>>> Once we have control flow expressions I would like to see the ternary
>>> operator removed from the language as it would no longer server a purpose.
>>> Removing the ternary operator seems to fit nicely with the direction to
>>> remove some features that are carried over from C-based languages but don’t
>>> necessarily fit with the direction Swift is heading.
>>>
>>>
>>> On Dec 6, 2015, at 1:19 PM, Kevin Lundberg via swift-evolution <
>>> swift-evolution at swift.org> wrote:
>>>
>>> Ostensibly, case may not be necessary if you could delimit each case on
>>> one line with something (perhaps a comma, or something else if that would
>>> not fit well within the grammar):
>>>
>>> let thisColor = thatColor ? .Blue: .Red, .Green: .Blue, .Red: .Green,
>>> default: .Yellow
>>>
>>> On Sun, Dec 6, 2015, at 01:57 PM, Paul Ossenbruggen via swift-evolution
>>> wrote:
>>>
>>> I like this too, seems more powerful.  Also, would single line
>>> expressions be allowed?  If not would case be required for example:
>>>
>>> let myFavoriteColor = yourFavoriteColor ?
>>>      case .Blue: .Red
>>>      case .Green: .Blue
>>>      case .Red: .Green
>>>      default: .Yellow
>>>
>>>
>>>
>>> On Dec 6, 2015, at 9:11 AM, Sean Heber via swift-evolution <
>>> swift-evolution at swift.org> wrote:
>>>
>>> I really like this train of thought. +1
>>>
>>> l8r
>>> Sean
>>>
>>> On Dec 6, 2015, at 11:02 AM, Alex Lew via swift-evolution <
>>> swift-evolution at swift.org> wrote:
>>>
>>> What if we left the if { ...} else { ... } syntax alone (as a
>>> statement), and updated the ternary expression to be a more general pattern
>>> matching expression (closer to "switch")? Something like
>>>
>>> let x = condition ?
>>>    true: "Hello"
>>>    false: "Goodbye"
>>>
>>> let x = optionalValue ?
>>>    .Some(let unwrapped): "Hello, \(unwrapped)"
>>>    .None: "To Whom It May Concern"
>>>
>>> let myFavoriteColor = yourFavoriteColor ?
>>>      .Blue: .Red
>>>      .Green: .Blue
>>>      .Red: .Green
>>>
>>> let quadrant = (x, y) ?
>>>      let (x, y) where x < 50 && y < 50: "top left"
>>>      let (x, y) where x < 50 && y > 50: "bottom left"
>>>      let (x, y) where x > 50 && y < 50: "top right"
>>>      default: "bottom right"
>>>
>>> The colon comes from the fact that this is sort of a light-weight
>>> expression-based "switch" statement, where each branch can only contain an
>>> expression, not a series of statements.
>>>
>>> This is very similar to pattern matching expressions in languages like
>>> Haskell, ML, and Coq.
>>>
>>> On Sun, Dec 6, 2015 at 11:25 AM, Thorsten Seitz   <thorsten.seitz at web.de
>>> >   wrote:
>>>
>>>
>>>
>>> Am 06.12.2015 um 01:28 schrieb Alex Lew via swift-evolution <
>>> swift-evolution at swift.org>:
>>>
>>> I don't think you can just get rid of the if statement in favor of an
>>> expression. You still want to be able to do this:
>>>
>>> if (condition) {
>>>     funcWithSideEffectsThatReturnsInt()
>>> } else {
>>>     funcWithSideEffectsThatReturnsString()
>>> }
>>>
>>> but that's not a valid expression (what is its type?).
>>>
>>>
>>>
>>> That would actually be no problem if Swift’s type system would have
>>> union types (Ceylon has union and intersection types which are quite
>>> awesome and enable lots of nice things quite naturally, see
>>> http://ceylon-lang.org/documentation/1.2/tour/types/).
>>>
>>> In that case the type of such an expression would just be the union of
>>> both types, which is written   Int | String   in Ceylon.
>>>
>>>
>>> -Thorsten
>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>>
>>> *_______________________________________________*
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>>
>>> Untracked with   Trackbuster <https://trackbuster.com/?sig>
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>>
>>  _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>>
>
> Untracked with Trackbuster <https://trackbuster.com/?sig>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151206/7f05a68f/attachment.html>


More information about the swift-evolution mailing list