4
$\begingroup$

There are some languages that support ternary operator. There are Python, C, JavaScript, PHP.

In languages like C and JavaScript, the syntax is like this:

condition ? do_true : do_false

Python has another form:

do_true if condition else do_false

But some languages did not support ternary operator, like Go.

So, what are the pros and cons of it?

$\endgroup$
3

9 Answers 9

11
$\begingroup$

Pro: Readability

While plenty of people talk about the readability problems with misused ternary operators, there are also situations where using a full if/else would be annoyingly bulky, spreading a simple statement across five lines, and significantly reducing readability. Here are some sample statements pulled from a project I'm working on:

bg_2d.fillStyle = is_in_bounds(x, y) ? grid_colors[x][y] : "#ffffff";
const diagonal_slowdown = is_diagonal() ? Math.SQRT2 : 1;
const color = (team == "red") ? "#ff0000" : "#0000ff";

When you have a simple situation where you have two things to pick from based on a condition, which happens all the time, ternary is perfect. Having a short syntax for ternary massively improves readability in these situations.

$\endgroup$
0
6
$\begingroup$

Pros:

It's an expression, and in languages with distinction between expressions and statements it's crucial to have a selection operator available as an expression. Ternary operator is not necessarily the best syntax though, as the other answers highlighted how convoluted it can become with very little effort. A good alternative is an if-then-else available as an expression and not just statement.

Cons:

It's introducing control flow into expressions, just like logic operators in many languages. When side effects are possible, it's making expressions less visually obvious to follow.

The C-style syntax of C?T:F often leads to convoluted and error-prone code.

$\endgroup$
0
5
$\begingroup$

Con: One more darned thing to remember

The ternary syntax is very different from everything else, and requires somewhat complex additions to the precedence table.

$\endgroup$
1
  • 2
    $\begingroup$ The thing about C-style conditional expressions is that they aren’t much different from conditional statements—nor other ternary operators like assignment—yet they’re seen very differently, so it becomes an important usability-design question. if (a) b else c starts with two more tokens if ( compared to a ? b : c, and if and else are better mnemonics than ? and (especially) :. Tuning the amount of such redundancy is one of the few objective ways of improving readability and reducing clerical errors. Otherwise, they have the same form, associativity, and relative precedence. $\endgroup$
    – Jon Purdy
    Jun 24, 2023 at 20:27
5
$\begingroup$

There is a very specific pitfall with ternary operators in statically typed languages which allow type coercions, like Java. Programmers like to refactor code like this to avoid repetition:

if(condition) {
    System.out.println(3);
} else {
    System.out.println(4.5);
}

This can almost be rewritten as:

System.out.println(condition ? 3 : 4.5);

Unfortunately, the two are not equivalent, as the first version prints 3 when the condition is true, whereas the second version prints 3.0 because the ternary expression needs to have a static type, so it's double. In general with overloaded methods this can cause arbitrarily different behaviour, though it only rarely makes a difference; I only came across this once when writing an interpreter in Java, where a method like this had a bug because I was too eager to simplify it:

Object getDefaultValue(Type t) {
    if(t == Type.DOUBLE) {
        return 0.0;
    } else {
        return 0;
    }
}

The refactored version unconditionally returns a boxed value of 0.0 as a Double, because ... ? 0.0 : 0 coerces to double before the result is coerced to Object.

It's genuinely rare for this refactoring to cause a significant problem in code, so this isn't really an argument against having the ternary operator in your language. But generally no programmer ever wants two type conversions in a row (here, 0 gets coerced to double then Object) without making both conversions explicit, so it's something to be careful of. (Perhaps there should be a warning for serial implicit type conversions.)

$\endgroup$
2
  • $\begingroup$ This kind of problem is caused by type coercions as well as the ternary operator, not the ternary operator alone $\endgroup$ Jun 27, 2023 at 17:26
  • $\begingroup$ @CoffeeTableEspresso Indeed, but for ergonomic reasons you do generally want type coercion to be part of the ternary operator's semantics. $\endgroup$
    – kaya3
    Jun 27, 2023 at 17:59
4
$\begingroup$

Con: Can lead to unreadable code

The syntax of ?: is pretty unintuitive. Python's X if Y else Z is slightly better. However, this problem becomes worse if many such if-else expressions are nested. For example, (a) ? (b ? c : d) : (e ? f : g) or even the following where it is easy to see what the code does but may be difficult to reason about how it does it:

String result = a ? "A" :
                b ? "B" :
                c ? "C" :
                d ? "D" :
                e ? "E" :
                f ? "F" :
                g ? "G" :
                h ? "H" :
                "I";

Though these examples are contrived, they show how ternary operators can lead to unwieldy code pretty quickly. Ternary operators are good for short conditional expressions; for larger conditions, if-else statements are better.

$\endgroup$
3
  • 1
    $\begingroup$ The right alternative to a ternary expression would have been an if-then-else expression. Statement cannot replace expression as statements in most languages cannot be used in the same place as expressions. $\endgroup$
    – SK-logic
    Jun 23, 2023 at 10:17
  • $\begingroup$ @SK-logic an if-then-else expression is just a ternary operator with different syntax. $\endgroup$ Jun 27, 2023 at 17:24
  • 1
    $\begingroup$ @CoffeeTableEspresso it's exactly the C?T:F syntax that people have problems with. A more verbose syntax removes pretty much all the criticism of ternary expressions. $\endgroup$
    – SK-logic
    Jun 27, 2023 at 17:27
2
$\begingroup$

Recommendation:

For expressions, provide the "same" set of conditional constructs that you provide for statements, and for readability, use similar syntax constructs.

The ternary operator's semantics match the if-then-else statement, but its syntax is very different - the operator uses special characters, the if-then-else statement uses readable keywords.

Typically, your language might also provide a switch-case statement, so you should also include a switch-case expression syntax.

Or you might even go one step further: make everything an expression, meaning that even "statements" return something. Then the if-then-else "statement" immediately replaces the ternary operator, without the need to learn two different syntaxes.

Rationale:

Expressions that evaluate differently based on some condition are a very intuitive concept. See e.g. Absolute Value, it uses an expression with two cases, and we all immediately understand what that means.

The main problem I see with the ternary operator is its syntax. It comes from the C language and follows the typical C cryptic style (is there any special character that we didn't use yet?).

$\endgroup$
2
$\begingroup$

If statement duplicates the part specifying what to do with the conditionally selected value:

if (condition) {
   use_value_now(alpha, beta, 0);
} else { 
   use_value_now(alpha, beta, 1);
}

It may be OK when the selected value is just assigned to the variable, but for the function call as in this example it almost looks like a dedicated variable should be defined for it. Then it is not so clear how (and if) this variable should be initialized when declared. Curly brackets (or they analogs in other languages) are also now mostly a requirement for the good coding style.

Compare this with

use_value_now(alpha, beta, condition ? 0 : 1);
$\endgroup$
2
  • $\begingroup$ This isn't necessarily true, e.g. let gamma; if (condition) { gamma = 0 } else { gamma = 1 }; use_value_now(alpha, beta, gamma);. $\endgroup$
    – Bbrk24
    Jun 30, 2023 at 17:49
  • $\begingroup$ It is how you write. But does not look very short. $\endgroup$ Jun 30, 2023 at 20:07
1
$\begingroup$

Pro:It’s more consice

This pretty much speaks for itself. Makes life considerably easier and more optimized.

$\endgroup$
1
$\begingroup$

Ternary operators are needed only in languages where if/else is not an expression. For example, in Java if/else is a statement so it cannot produce a value, thus the ternary operator. Contrast it with something like Ruby where if/else is an expression. Now, Ruby also features a C-style ternary operator. Using it can result it more concise code, though some may say at the cost of readability.

One difference between having a ternary conditional operator and if expressions is that the body of an if branch may contain multiple statements and usually the last expression in the block serves as the return value, whereas the ternary operator can only contain a single expression in its branches. The latter limitation may be surpassed by extracting the set of statements into a separate function.

As for pros and cons, I think we should use the most expressive tools we can as long as we don't sacrifice readability. The ternary operator is pretty common across programming languages (or the equivalent if expression), so I say use it whenever it's convenient.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .