Does Scala have Java’s ternary operator?

I hear this question a lot. Yes it does. Instead of c ? p : q, it is written if(c) p else q.

This may not be preferable. Perhaps you’d like to write it using the same syntax as Java. Sadly, you can’t. This is because : is not a valid identifier. Fear not, | is! Would you settle for this?

c ? p | q

Then you’ll need the following code. Notice the call-by-name (=>) annotations on the arguments. This evaluation strategy is required to correctly rewrite Java’s ternary operator. This cannot be done in Java itself.

case class Bool(b: Boolean) {
  def ?[X](t: => X) = new {
    def |(f: => X) = if(b) t else f
  }
}
 
object Bool {
  implicit def BooleanBool(b: Boolean) = Bool(b)
}

Here is an example using the new operator that we just defined:

object T {
  val condition = true
 
  import Bool._
 
  // yay!
  val x = condition ? "yes" | "no"
}

Have fun ;)

5 Responses to “Does Scala have Java’s ternary operator?”

  1. Ricky Clarkson Says:

    Note that the operator precedence does not match Java’s, so you’ll have to parenthesise most calls to this.

  2. Erkki Lindpere Says:

    Nice, why didn’t I think of that?

  3. Pawel Badenski Says:

    And the big question is “do we really need it ?”. “if a else b” is a nice Scala idiom, and in my opinion introducing “a ? b | c” is just bringing old habits to a new environment. It doesn’t really hurt in this case but I can resist the feeling it’s some sort of a bad smell…

  4. Tony Morris Says:

    Pawel, Yes it is needed. Not because of the terser syntax (I happen to prefer it though), but because it allows composition of the smaller parts.

    e.g.
    val t = _ ? b | c is a function that takes a boolean and returns the least common superclass of b and c. In other words ‘if’ should be a regular function (which the compiler optimises), not a language specialty. The bad habit here, is copying older languages without call-by-name semantics by making it a language feature.

  5. jherber Says:

    anyone else care for the look of R’s ifelse function?

    def ifelse[U](c:Boolean, t_exp: =>U, f_exp: =>U) = if (c) t_exp else f_exp

    val x = ifelse(condition, “true”, “false”) // no parenthesis corner cases
    val x = condition ? “true” | “false”

    unfortunately, scala doesn’t infer the type on the partial :(

    val t = ifelse( _:Boolean, b, c)

Leave a Reply