views:

134

answers:

5

A discussion has come up in my office about the use of ternary operators. There are two sides to this discussion.

Side 1) That ternary operators are easy to write and read, therefore convenience is a net cost-savings.

Side 2) That ternary operators are difficult to maintain because they require excess code-churn should they ever need to be modified to be even the slightest bit more complex.

Extra nerd points if you can cite any actual studies done by a top-tier institution on this subject... I'm very interested to see hard data on this.


My theory is that the best code is code that can change and adapt easily, and that the less complexity that change requires, the less chance there is for a break. Example:

$id = $user->isRegistered() ? $user->id : null;

Ok, so this is completely valid, but what happens when the code needs to change to become something slightly more complex?

$id = null;
if ($user->isRegistered() || $user->hasEmail()) {
    $id = $user->id;
}

Any sane programmer would look at the ternary and convert to standard if/else. However, this required a 4-line change versus starting with:

if ($user->isRegistered()) {
    $id = $user->id;
}

Which would only require a 1-line change.

Thoughts? Opinions? Flame throwers?

+2  A: 

I'd stick with the ternery operator in your example.

   $id = ($user->isRegistered() ||  $user->hasEmail())? $user->id : null;

As long as the only "branch" is to decide what value is to be assigned to a variable, the ternery operator is more readable than if-else clauses, because it does not potentially duplicate the actual function being performed, (in this case - this is the code "$id =") If the logical conditions become complex, simplify them.

   bool $isReg    = $user->isRegistered(),
        $hasEmail = $user->hasEmail();
   $id = ($isReg || $hasEmail)?  $user->id : null;
Charles Bretana
for clarity, I would group the `$isReg || $hasEmail` in parens.
akf
Agree - edited to implement
Charles Bretana
Obviously my example was simple. The real pain in ass comes when the then or else clauses need to be added to.
thesmart
If they all do the same thing (set the value of $id) then no matter how complex the conditions are, using the ternary operator is still simpler, because it isolates the complexity in the area it belongs (in the conditions) instead of obfuscating the issue by duplicating the " $id = " part in every single nested if or elseif clause ....
Charles Bretana
+4  A: 

I find that once you get used to the syntax both options are equally as readable (provided you aren't going overboard with either) and so that's not an issue for me.

As for which is more time-efficient, I'm going to answer with an obnoxious question - why do you care? Either option takes less than 20 seconds to convert to an equivalent if statement.

Personally I find that when I'm finding ways to chisel seconds off my programming time it's a form of procrastination. I work best when I'm concentrating on getting things done and let the small readability details work themselves out through experience.

Kai
I would accept this as answer, but wondering if someone can find any hard data.
thesmart
No problem -- I always like to consider the purpose of the problem before I actually try to answer it with hard data ;p
Kai
+1  A: 

I like to use the ternary operator whenever I have a one-line expression where the value depends on an appropriate boolean condition. In effect, if I need to choose between assigning to a variable, and I can choose between Expression 1 and Expression 2, then I often use a ternary.

However, if the expressions have a side effect, then I will immediately rewrite the whole thing as an if() statement. Using the ternary operator for flow control is rather confusing to most people.

jprete
A: 

Ternary operations have their place; it's usually to simplify the code when performing a trivial task. At some point, however, you may need to rethink your strategy if the conditional statement becomes too complex. It's determining when that point is that becomes the challenge. Only experience can guide you then.

So, I don't think there's one "right" answer as long as the end result is clean, readable, and maintainable code. The extra lines of code for the if statement shouldn't even be considered when making this determination (since the number of lines of code doesn't necessarily correlate 1-to-1 to the complexity of the code.)

Ryan Emerle
But doesn't the cost of 1 defect outweigh the time-savings of using ternary? That is, what threshold could their possibly be that make ternary worth it?
thesmart
A: 

If you consider ternary operators as conditionals in general, they do tend to bug and defect injection. The concept is called Cyclomatic Complexity. From a very high level, it's pretty easy to grasp -- the more options the code has of executing, the higher the risk of having a defect.

I'll quote the Wikipedia article on Cyclomatic Complexity:

A number of studies have investigated cyclomatic complexity's correlation to the number of defects contained in a module. Most such studies find a strong positive correlation between cyclomatic complexity and defects: modules that have the highest complexity tend to also contain the most defects.

If the argument is focused solely on the semantics of typing a small if-statement versus the ternary syntax, the argument would have to focus on developer experience, knowledge, etc. and it becomes a case-by-case basis. For example, if a new developer starts doing things a non-traditional (WRT the company culture), then others using his code may be more prone to adding defects. You can really argue this to with any two similar ways of solving a problem.

Austin Salonen
The question seems to me to be ternary operators vs. explicit if statements, both of which raise cyclomatic complexity. I don't see it as an issue.
David Thornley
What does this have to do with it? If a logical structire is complex it will be equally complex with If Else construct as it is with a ternary construct... In fact, if all the construct is doing is assigning one of multiple values to a variable, then the ternary construct will exhiibit less cyclomatic complexity.
Charles Bretana