As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
If this question can be reworded to fit the rules in the help center, please edit the question.

+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.
–
sangeDec 20 '10 at 16:44

20

+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 JonesDec 20 '10 at 16:48

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.

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".

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.

If you're worried about readability, you can format them readably.

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.

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...)

"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.

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.

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.

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.

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.

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.