# Ternary operator considered harmful? [closed]

For example, would you prefer this one-liner

``````int median(int a, int b, int c) {
return (a<b) ? (b<c) ? b : (a<c) ? c : a : (a<c) ? a : (b<c) ? c : b;
}
``````

or an if/else solution involving multiple return statements?

When is `?:` appropriate, and when is it not? Should it be taught to or hidden from beginners?

• This particular use of it is :) – Keith Gaddis Dec 20 '10 at 16:48
• Who coded that, and what does their version of a median for four numbers look like? Or five? – Mason Wheeler Dec 20 '10 at 21:56
• The more correct name is 'conditional operator'. It just happens to be the most common ternary operator in use. – Alan Pearce Dec 21 '10 at 15:11
• This was asked over two years ago on stackoverflow. Are we going to re-ask everything over here now? stackoverflow.com/questions/160218/to-ternary-or-not-to-ternary – webbiedave Dec 21 '10 at 16:30
• I am surprised why such questions keep coming up. The answer is always "whatever works and is readable." --the last one being equally important. – Apoorv Nov 26 '12 at 6:18

Is the ternary operator evil?

No it's a blessing.

When is ?: appropriate?

When it's something so simple you don't want to waste many lines for.

and when is it not?

When the readability and clearness of code suffers and a potential for a mistake through insufficient attention increases, for example, with many chained operators, just like in your example.

The litmus test is when you begin to doubt your code is easily readable and maintainable in the long run. Then don't do it.

• +1 for When the readability and clearness of code suffers. With many chained operators, just like in your example. The example takes longer to understand than equivalent if/else's. – sange Dec 20 '10 at 16:44
• +1 bravo for the great explanation! Developers don't tend to realise that some things are judgement calls, they want everything to be black and white. It drives me nuts. I've encountered to many people of the opinion "X is evil, lets never use it.". I prefer "X is great if you use it for what it's good at". – Doctor Jones Dec 20 '10 at 16:48
• It is also evil if it's used: myVar = (someExpression) ? true : false; Aaaaarrgh! – adamk Dec 20 '10 at 17:55
• @adamk: Try this for evil: `myVar = someExpression ? false : true;` – Dean Harding Dec 20 '10 at 22:00
• How about `(someExpression ? var1 : var2)++` :-) – fredoverflow Dec 21 '10 at 10:42

I think the unnested ternary operator (i.e., a statement where it's used only once) is fine, but if you're nesting more than one, it becomes somewhat hard to read.

• This might be considered an oversimplification, but it's a very easy guideline to follow and it works in most cases. – Alan Pearce Dec 21 '10 at 15:08
• It's actually my rule of thumb: you should never nest them, otherwise replace them with if/else's, it will be clearer that way. – Piovezan Jan 28 '14 at 19:06
• If you would use them, and would nest them, then for the love of humanity use parenthesis and white space to make it readable. If-else can be made just as ugly. Resist the urge to show off how 'smart' you are by writing things that compilers can read but humans can't. Someday you will be the human who can't. – candied_orange Aug 29 '14 at 3:00

When is ?: appropriate

and when is it not?

• If you're doing it just to please a refactoring tool like ReSharper and not the person who has to maintain the code

If you have any logic or function calls inside the ternary expression, you're making it horrible to look at.

• This one deserves a lot of upvotes! – Piovezan Jan 28 '14 at 19:07

One difference that (I think) no-one has pointed out is that if-else can't return a value, whereas the ternary operator can.

Coming from F#, I sometimes like to use the ternary operator to mimic pattern matching.

``````match val with
| A -> 1
| B -> 3
| _ -> 0
``````

vs

``````return val == A ? 1 :
val == B ? 3 :
0;
``````
• That's pretty cool. Never thought of that. – Rei Miyasaka Dec 21 '10 at 14:14
• +1 @Benjol: I was going to point out the same thing (that in F#, everything is an expression, including if/elif/else). I use ternaries like in your example too, so far also undiscovered :). Another thing I've been doing, in Javascript, perhaps over the top, is: `var res = function() {switch(input) {case 1: return "1"; case 2: return "2"; ...}}()` to emulate switches as expressions. – Stephen Swensen Dec 21 '10 at 15:05
• @Stephen, I was going to use the words `expression` and `statement` but I'm always worried I'll get them the wrong way round and make a fool of myself :) – Benjol Dec 22 '10 at 6:02
• @Benjol: I know what you mean! – Stephen Swensen Dec 22 '10 at 13:16
• Also useful in C and C++ for initializing `const` variables that can't be changed later. – David Thornley Jan 25 '11 at 19:53

An example (IMHO) of a valid use:

``````printf("Success in %d %s\n", nr_of_tries, (nr_of_tries == 1 ? "try" : "tries"));
``````

This results in more readable code than having 2 distinct print statements. Nested examples depend: (understandable ? yes : no)

• Just keep in mind that if you do this, you're making it hell for whoever has to localize your application. Of course, if that's not a problem, go right ahead. – Anon. Dec 20 '10 at 20:23
• That's my rule of thumb: 1 level of nesting (under some circumstances). – Oliver Weiler Dec 20 '10 at 22:56

Absolutely not evil. In fact, it's pure, and if-then-else isn't.

In functional languages like Haskell, F#, ML etc., it's the if-then-else statements that are considered evil.

The reason for this is that any "action" like an imperative if-then-else statement requires you to separate a variable declaration from its definition, and introduces state to your function.

For instance, in the following code:

``````const var x = n % 3 == 1
? Parity.Even
: Parity.Odd;
``````

vs.

``````Parity x;
if (n % 3 == 1)
x = Parity.Even;
else
x = Parity.Odd;
``````

The first one has two advantages aside from being shorter:

1. `x` is a constant, and so offers much fewer chance of introducing bugs, and can potentially be optimized in ways the second could never be.
2. The type is made clear by the expression, so the compiler can effortlessly infer that `x` needs to be of type `Parity`.

Confusingly, in functional languages, the ternary operator is often called if-then-else. In Haskell, you might say `x = if n mod 3 == 1 then Odd else Even`.

• yep, this is the point @Benjol made as well. See my comment to his answer for a fun way of emulating switch statements as expressions in Javascript. – Stephen Swensen Dec 21 '10 at 15:10

That particular expression makes my eyes hurt; I'd lash out an any developer on my team that used it because it's unmaintainable.

Ternary operators are not evil when used well. They don't even have to be single lines; A long one that is formatted well can be very clear and easy to understand:

``````return
( 'a' == \$s ) ? 1
: ( 'b' == \$s ) ? 2
: ( 'c' == \$s ) ? 3
:                 4;
``````

I like that better than the equivalent if/then/else chain:

``````if ( 'a' == \$s ) {
\$retval = 1;
}
elsif ( 'b' == \$s ) {
\$retval = 2;
}
elsif ( 'c' == \$s ) {
\$retval = 3;
}
else {
\$retval = 4;
}

return \$retval;
``````

I'll reformat those into:

``````if    ( 'a' == \$s ) { \$retval = 1; }
elsif ( 'b' == \$s ) { \$retval = 2; }
elsif ( 'c' == \$s ) { \$retval = 3; }
else                { \$retval = 4; }

return \$retval;
``````

if the conditions and assignments allow easy alignment. Still I prefer the ternary version because it's shorter and doesn't have as much noise around the conditions and assignments.

• Why can't I put linebreaks in comments? Arrgghh! – Christopher Mahan Jan 25 '11 at 20:36

ReSharper in VS.NET sometimes suggests to replace `if...else` with the `?:` operator.

It seems that ReSharper suggests only if the conditions/blocks are below a certain complexity level, otherwise it sticks with `if...else`.

• another great feature I love about ReSharper – Anonymous Type Dec 20 '10 at 21:39
1. "Evil" arguments aside, in my experience I've found a high correlation between a programmer's use the ternary operator and the likelihood of his or her entire codebase being difficult to read, follow, and maintain (if not outright undocumented). If a programmer's more concerned with saving a few 1-2 character lines than someone being able to understand his or her code, then any minor confusion understanding a ternary statement is usually the tip of the iceberg.

2. Ternary operators attract magic numbers like s**t attracts flies.

If I was looking for an Open Source library to solve a particular problem, and I saw code such as the original poster's ternary operators in a candidate for said library, warning bells would start going off in my head and I'd start considering moving on to some other project to borrow from.

Anything that makes your code uglier is evil.

If you use ternary to make your code cleaner then sure use it. Sometimes in like php it's great to do inline substitutions, e.g.

``````"Hello ".(\$Male?"Mr":"Ms")." \$Name
``````

That saves a few lines, and it pretty clear, but your example needs at least better formatting to be clear, and ternary isn't really good for multi-line, then you might as well use if/else.

Far from being evil, the ternary operator is a godsend.

• It is most useful when you want to make a decision in a nested expression. The classic example is a function call:

``````printf("I see %d evil construct%s in this program\n", n, n == 1 ? "" : "s");
``````
• In your particular example, the ternary is nearly gratuitous, since it is the top-level expression under a `return`. You can lift the conditional out to the statement level without duplicating anything other than the `return` keyword.

N.B. Nothing will ever make that particular algorithm for median easy to read.

• It's hard to be so readable that you can't make it better. `printf("I see %d evil construct%s in this program\n", n, "s" unless (n == 1) "s");` – Pacerier Feb 6 '15 at 13:48

Here's an example of when it is evil:

``````oldValue = newValue >= 0 ? newValue : oldValue;
``````

It's confusing and wasteful. The compiler could optimize out the second expression (oldValue = oldValue), but why did the coder do this in the first place?

Another doozy:

``````thingie = otherThingie != null ? otherThingie : null;
``````

Some people are just not meant to be coders...

Greg says that the equivalent if statement is 'noisy'. It is if you write it noisily. But that same if can be written as:

``````if ('a' == \$s) return 1;
if ('b' == \$s) return 2;
if ('c' == \$s) return 3;
return 4;
``````

Which is no noisier than the ternary. I wonder if the ternary short-cuts; do all of the expressions get evaluated?

• Your second example reminds me of `if (x != 0) x = 0;`... – fredoverflow Jan 25 '11 at 19:55

Evil? Look, they're just different.

`if` is a statement. `(test ? a : b)` is an expression. They're not the same thing.

Expressions exist to express values. Statements exist to perform actions. Expressions can appear inside statements, but not vice-versa. So you can use ternary expressions within other expressions, like for terms in a summation, or for arguments to a method, and so on. You don't have to, but you can if you want to. There's nothing wrong with that. Some people might say that's evil, but that's their opinion.

One value of a ternary expression is it makes you to handle both true and false cases. `if` statements don't.

Somehow "evil" crept into the programming vocabulary. I'd love to know who first dropped it. (Actually, I have a suspect - he's at MIT.) I would rather we had objective reasons for value judgements in this field, not just peoples' taste and name-calling.

• May I have a hint on who the suspect is? Just to improve my knowledge of the field a bit. – mlvljr Jan 26 '11 at 10:52
• @mlvljr: Well I could be wrong, so better not to. – Mike Dunlavey Jan 26 '11 at 16:52

It has a place. I've worked at a lot of companies where the skill levels of developers range from terrible to wizard. Since the code has to be maintained, and I won't be there forever, I try to write stuff so that it looks like it belongs there (without looking at the comments with my initials, it is extremely rare for you to be able to look at code I've worked on to see where I made changes), and that someone with less skill than myself can maintain it.

While the ternary operator looks nitziffic and way cool, my experience is that line of code is going to be about impossible to maintain. At my current employer, we have products that have been shipping for almost 20 years. I wouldn't use that example anywhere.

I do not think that the ternary operator is evil.

Here is a gotcha that had me stumped, though. I was a C programmer for many (10+) and in the late 1990s I moved into web based application programming. As a web programmer, I soon ran across PHP which also has a ternary operator. I had a bug in a PHP program which I finally traced to a line of code with a nested ternary operator. It turns out that the PHP ternary operator associated left to right but the C ternary operator (which I was used to) associates right to left.

This can be reformatted to be as nice-looking as the if/else combination:

``````int median(int a, int b, int c)
{
return
(a<b)
?
(b<c)
? b
:
(a<c)
? c
: a
:
(a<c)
? a
:
(b<c)
? c
: b;
}
``````

But the problem is that I am not really sure if I got the indentation right to represent what will actually happen. :-)

• +1 I think this is far better than an equivalent `if-else` structure. The key is the formatting. – Orbling Dec 20 '10 at 22:13
• If I saw this in a code base, I would seriously consider looking for a new job. – Nick Larsen Dec 21 '10 at 14:50
• +1 Not for this actual indentation, but this is the best solution for this example. – Mark Hurd Jan 26 '11 at 2:32
• Only that another accidental automatic formatting would wipe out all that indenting, and time for another round of restructuring - hugely productive :) – nawfal Apr 23 '13 at 19:43

Can I say it? I can't manage to find this particular application of the ternary operation evil:

1. the operation it performs is pretty trivial, and once you went trough it once it's hardly possible some bugs will come out;
2. what it does is clearly stated in the function name;
3. taking >1 line for something so obvious and that so clearly wouldn't be improved in the future (unless a magic median algorithm has lived undetected until now).

Biggest win: Showing that there is a single target of action.

``````if ( \$is_whatever )
\$foo = 'A';
else
\$foo = 'B';
``````

There are two code paths that you can follow, and the reader must read carefully to see which two variables are being set. In this case, it's only one variable, but the reader has more to read to figure that out. After all, it could have been this:

``````if ( \$is_whatever )
\$foo = 'A';
else
\$bar = 'B';
``````

With the ternary operator, it's clear that only one variable is being set.

``````\$foo = \$is_whatever ? 'A' : 'B';
``````

At the very lowest level, it is the DRY (Don't Repeat Yourself) principle at its most basic. If you can specify `\$foo` only once, do so.

If ... then ... else tends to emphasize the condition and therfore de-emphasize the operations being conditionally done.

the ternary operator is the opposite, it tends to hide the condition and is therfore useful when the operation being done is more important than the condition itself.

There is the minor technical niggle, in some languages, that they aren't quite interchangeble due to one being a statement and one an expression e.g. conditionally initialising consts in C++

When is appropriate, and when is it not?

I think that when developing for a homogeneous group of people, there is no problem but when you have to deal with people that handle different levels, this kind of oneliners only introduce a further level of complexyti to the code. So, my policy on the matter is: code clear and dont explain rather than code short and explain 123123 times.

Should it be taught to or hidden from beginners?

I should not be taught to beginners, rather prefert them to figure it out when need emerges, so it'll be used only when necesary and not every time you need an if.

IMO, the operator itself isn't evil, but the syntax used for it in C (and C++) is excessively terse. IMO, Algol 60 did it better, so something like this:

``````A = x == y ? B : C;
``````

would look more like this (but sticking to C-like syntax in general):

``````A = if (x==y) B else C;
``````

Even with that, excessively deep nesting can lead to problems with readability, but at least A) anybody who's done programming at all can figure it out a simple one, and B) people who understand it can handle considerably deeper nesting pretty easily. OTOH, I'd also note that in LISP (for example) a `cond` is pretty much like a ternary statement -- not a set of statements, but a single expression the yields a value (then again, most of LISP is like that...)

• Why not just do this for readability? `A = (x==y) ? B : C` – Jeremy Heiler Jan 25 '11 at 20:22
• @Jeremy: while some people find the parens useful, even at best they don't help much. Nest more than a couple deep and you still need careful indentation (as a bare minimum) to keep things sorted out. Undoubtedly the same would happen eventually in Algol, but I never say a problem arise in it like I often do in C... – Jerry Coffin Jan 25 '11 at 20:28
• I just assumed everyone was in agreement that nesting a ternary operator is bad. I was speaking specifically about the examples you provided. In particular, how the first one can be more like the second one in most languages. – Jeremy Heiler Jan 25 '11 at 20:31

A shop that regularly writes 600-1200-line methods should not tell me that a ternary is "hard to understand". Any shop that regularly allows five conditions to evaluate a code branch should not tell me that concretely summarized conditions in a ternary are "hard to read".

When is ?: appropriate, and when is it not?

• If you don't get a performance gain, don’t use it; it affects the readability of your code.
• Use it once and don’t nest it.
• It’s harder to debug.

Should it be taught to or hidden from beginners?

Doesn't matter, but it should not be intentionally hidden as it's not too complex for a “beginner” to learn.

``````def median(a, b, c):
if a < b < c: return b
if a < c < b: return c
if b < a < c: return a
if b < c < a: return c
if c < a < b: return a
if c < b < a: return b
``````

is very simple to read, and obvious. The variable between the < < is the return value.

## Update

same, but fewer lines of code. Still simple I think.

``````def median(a, b, c):
if b<a<c or c<a<b: return a
if a<b<c or c<b<a: return b
if a<c<b or b<c<a: return c
``````
• This requires 12 comparisons in the worst case... – fredoverflow Jan 25 '11 at 20:58
• Perhaps, but it's legible. – Christopher Mahan Jan 25 '11 at 21:29

It's also necessary for const

``````const int nLegs  = isChicken ? 2: 4 ;
``````
• Strange. I think its C++ or something. I thought const had always been compile time constant (as in C#) – nawfal Apr 23 '13 at 19:48
• @nawfal - if you don't know isChicken until runtime – Martin Beckett Apr 23 '13 at 22:47
• yes thats what. i think `const` is so in certain languages. In C# `const` should always be compile time known value. which means `const int nLegs = isChicken ? 2: 4 ;` wont work, but `const int nLegs = true ? 2: 4 ;` will – nawfal Apr 24 '13 at 4:04