[swift-evolution] [Pitch] Replace the ternary operator with an in-language function

Xiaodi Wu xiaodi.wu at gmail.com
Fri Oct 28 19:56:16 CDT 2016


As Chris mentioned, such a proposal is entirely out of scope for this phase
of Swift 4, it's a commonly rejected proposal that required a high bar for
reconsideration even during the Swift 3 evolution process, and that bar is
even higher going forward because source breaking changes will be extremely
frowned upon. Because it's such a high-traffic list, this is really not an
ideal thread to resurrect...

On Fri, Oct 28, 2016 at 5:56 PM Soroush Khanlou via swift-evolution <
swift-evolution at swift.org> wrote:

> +1 from me as well.
>
> I was initially unconvinced, until Charlotte showed me her proposal. She
> lays out the case very well, and I agreed to help edit the proposal.
>
> It’s a confusing and bad operator, and it doesn’t give us anything that a
> function on Bool can’t give us. The way I see it, this isn’t very different
> from C-style for loops, the ++ operator, or explicit optionality, which are
> all features where Swift departs from traditional C orthodoxy.
>
> It’s easy to abuse and hard to reason about. Special cases like this
> operator have to really earn their place in the language. This one doesn’t
> carry its weight.
>
> Soroush
>
> On Oct 26, 2016, at 11:42 AM, Joshua Alvarado via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> -1
>
> I love the idea of challenging the syntax but without any real benefit I
> can see it harder for new devs and it will cause breaking changes that
> doesn't outweigh the cause. The syntax z ? x : y is  not hard to comprehend
> and expresses powerful statements in just a simple line. I do agree it is
> abused. It is used in places that a fuller if statement would help make
> sense of the code. It is on the developer to help make the operator easier
> to understand. The operator is the same across many languages which helps
> create a standard.
>
> Alvarado, Joshua
>
> On Oct 26, 2016, at 9:12 AM, Mark Sands via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> Strong *+1* from me.
>
> This simply feels like the right approach for Swift, as we see the
> language head in a direction that has abandoned traditional C-style idioms.
> As swift has already dropped support for the ++/-- operators and C-style
> for loops it makes logical sense that dropping the ternary operator (or
> replacing with a more Swift-like idiom) should follow.
>
> As a side note, after upgrading my swift code to Swift 3, I feel as though
> I've become un-phased at future source breaking changes until full
> stability is met and set in stone. If they're worth it, bring them on, I
> say.
>
> Mark
>
> On Wed, Oct 26, 2016 at 8:52 AM, Mike Kasianowicz via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> I like the idea in theory, but I also like the existing ternary operator.
> Could some of this be accomplished without drastic changes?
>
> Some alternative ideas-
>
> 1) Codify ternary operator declaration in the language, but make some
> common-sense restrictions to reduce expression parsing complexity (no line
> breaks, enforced parens, 'simple' arguments, stuff like that).  If there
> were an extension like you propose in addition, my preference would be a
> verb like "select".
>
> 2) Make it a binary operator with autoclosure tuple on the RHS (is it
> possible to put autoclosure within a tuple?):
>
> public static func ?<T>(_ value: Bool, _ branches: (_ t: @autoclosure ()
> -> T, _ f: @autoclosure () -> T)) -> T {
>         if value {
>             return branches.t()
>         } else {
>             return branches.f()
>         }
>     }
>
>
>
> On Tue, Oct 25, 2016 at 11:51 PM, Charlotte Angela Tortorella via
> swift-evolution <swift-evolution at swift.org> wrote:
>
> Preamble: I've read over the threads that already exist about the ternary
> operator and to be honest they're a complete mess without a single fully
> formed proposal.
>
> Pitch: I'd like to simplify the syntax, compiler complexity and learning
> curve for newcomers when it comes to dealing with the ternary function. The
> best way to do that, in my opinion, is to remove it entirely and add a new
> function with better semantics that takes care of ternary operations
> entirely within the Swift language.
>
> gist: https://gist.github.com/Qata/25a11c21200f1cf8f43ed78e9ffd727c
>
> Replace the `?:` operator with an in-language function
>
> Proposal: TBD
> Author: [Charlotte Tortorella](https://github.com/qata)
> Editor: [Soroush Khanlou](https://github.com/khanlou)
> Review Manager: TBD
> Status: TBD
>
> Introduction
> <https://gist.github.com/Qata/25a11c21200f1cf8f43ed78e9ffd727c#introduction>
>
> The ternary operator in Swift was added early in development, as a holdover
> from C.  This document is an attempt to provide a clear look at the ternary
> operator without the baggage of the languages that came before, and comes
> to the conclusion that we should deprecate and remove the ternary operator
> in favor of an extension to `Bool`.
>
> As a quick refresher, here's what the ternary operator looks like:
>
> let a = 10
> let b = 20
> // If a is less than b, sets e to "foo", else sets e to "bar"
> let e = a < b ? "foo" : "bar"
>
> Advantages of The Ternary Operator
> <https://gist.github.com/Qata/25a11c21200f1cf8f43ed78e9ffd727c#advantages-of-the-ternary-operator>
>
> The primary advantage of this operator is its terseness and expressive
> capability. It's shorthand for (e.g.):
>
> let a = 10
> let b = 20
> let e: String
> if a < b {
>   e = "foo"
> } else {
>   e = "bar"
> }
>
> The second advantage of Swift supporting the ternary operator is continuity
> with C, and other common languages in the extended C family (C++,
> Objective-C,
> Java, C#, Javascript, etc).  People coming to Swift from these other
> languages
> may reasonably expect this operator to exist.  That said, there are also
> popular languages which have kept the majority of C operators but dropped
> the
> ternary operator (e.g. [Go](
> https://golang.org/doc/faq#Does_Go_have_a_ternary_form) and [Rust](
> https://github.com/rust-lang/rfcs/issues/1362)).
>
>
> Disadvantages of The Ternary Operator
> <https://gist.github.com/Qata/25a11c21200f1cf8f43ed78e9ffd727c#disadvantages-of-the-ternary-operator>
>
> 1. The existence of the ternary operator as a holdover from C is to
> increase
> the familiarity of the Swift language for C family developers, at the
> expense
> of newcomers.  Established developers do much better with learning concepts
> than newcomers to programming and probably don't need their hands held
> with this carry over of an operator.
>
> 2. The ternary operator adds complexity to the compiler, because it
> requires
> special handling.  It is the only operator that requires two components to
> work (both the `?` and the `:`), it uses a character that is excluded from
> being used in other operators (`:`), and it isn't defined in the standard
> library.
>
> 3. The ternary operator's usage of `?` can be confusing
> to new users.  Every other instance of `?` is associated with
> `Optional` values.
>
> 4. The ternary operator uses `:`, which is already a heavily overloaded
> symbol in Swift.  `:` is used in hash tables, type annotations for
> variables,
> class inheritance, and protocol conformance.
>
> 5. The ternary operator's short length lends it to being abused in the
> nested ternary operator anti-pattern.  This is similar to the `++` and
> `--` operators, which were removed in Swift 3.  While they worked fine and
> were
> readable enough when used alone, using them multiple times in a single
> expression like `function(a++, ++a)` made them highly unreadable and
> confusing.
>
> 6. This operator is only applicable to a single type, `Bool`.
>
> 7. If the ternary operator weren't in common usage, it would not be
> proposed
> for Swift.  Higher clarity can be achieved with common language features by
> creating an extension to `Bool`.
>
> 8. The ternary operator was created for and is much more suited to a
> language
> like C, where there were no generics and as such no alternative to an
> unintuitive operator.
>
> 9. Several other modern languages, like Rust and Go discussed earlier, have
> eschewed the usage of the ternary operator entirely.  Other languages that
> have
> special constructs similar to `?:`, such as `if then else` in Haskell have
> [discussed removing it](
> https://wiki.haskell.org/If-then-else#Is_If-Then-Else_so_important.3F).
>  `if then else` is identical to the `?:` operator,
> excepting that it's prefixed by `if`, while `?:` has no prefix.
>
>  Example: `if True then 10 else 20`
>
> 10. On a more personal and anecdotal note, the ternary operator gave me
> more
> trouble than any other operator when I was first learning how to program.
> I’ve also spoken to several other people who expressed similar sentiments
> about this operator’s inscrutability.
>
> Proposed Approach
> <https://gist.github.com/Qata/25a11c21200f1cf8f43ed78e9ffd727c#proposed-approach>
>
> We should drop the ternary operator in favor of a new extension to `Bool`.
> There are a few possibilities for the naming of this function.  We've
> provided
> four for consideration in this proposal, but are open to other options as
> well.
> This proposal is much more about the concept than the naming of the
> replacement
> function.
>
> extension Bool {
>     /// If `self == true`, returns `t`, otherwise, returns `f`.
>     func transformed<T>(true t: @autoclosure () -> T, false f:
> @autoclosure () -> T) -> T {
>         if self {
>             return t()
>         } else {
>             return f()
>         }
>     }
>
>     func when<T>(true t: @autoclosure () -> T, false f: @autoclosure () ->
> T) -> T {
>       ...
>     }
>
>     func if<T>(true t: @autoclosure () -> T, false f: @autoclosure () ->
> T) -> T {
>       ...
>     }
>
>     func if<T>(then t: @autoclosure () -> T, else f: @autoclosure () -> T)
> -> T {
>       ...
>     }
> }
>
> Only one of these should be chosen.  We're not proposing adding multiple
> functions that achieve the same thing.
>
> Example usage:
>
> let a = 10
> let b = 20
> _ = (a < b).transformed(true: "foo", false: "bar")
> _ = (a < b).when(true: "foo", false: "bar")
> _ = (a < b).if(true: "foo", false: "bar")
> _ = (a < b).if(then: "foo", else: "bar")
>
> Impact on existing code
> <https://gist.github.com/Qata/25a11c21200f1cf8f43ed78e9ffd727c#impact-on-existing-code>
>
> This proposal is breaking and would require migration.
>
> Alternatives considered
> <https://gist.github.com/Qata/25a11c21200f1cf8f43ed78e9ffd727c#alternatives-considered>
>
> Simplest alternative: we could leave the ternary operator as is and not
> introduce any new concepts.
>
> It'd also be possible to add an `if then else` Haskell-esque expression.
> This would have the disadvantages of still needing special handling by the
> compiler.  Since this proposal's intention is partially to remove compiler
> complexity, this would be counterproductive and would probably confuse new
> users in a similar way to how `?:` does.
>
>
> _______________________________________________
> 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
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161029/2977ca2d/attachment.html>


More information about the swift-evolution mailing list