views:

2349

answers:

52

I'm personally an advocate of the ternary operator: () ? : ; I do realize that it has its place, but I have come across many programmers that are completely against ever using it, and some that use it too often.

What are your feelings on it? What interesting code have you seen using it?

+10  A: 

In my mind, it only makes sense to use the ternary operator in cases where an expression is needed.

In other cases, it seems like the ternary operator decreases clarity.

John Mulder
the problem being that is 99% of the language, an expression can be replaced by a function ... and ppl avoiding the ternary operator will even prefer that solution.
PierreBdR
+2  A: 

Well, the syntax for it is horrid. I find functional ifs very useful, and often makes code more readable.

I would suggest making a macro to make it more readable, but I'm sure someone can come up with a horrible edge case (as there always is with CPP).

Marcin
many BASIC implementations and variants have an IF function that takes the place of the ternary operator. I have seen a number of codebases with that defined as a macro in C.
Sparr
Well, I was thinking of functional programming languages, but yes.
Marcin
"Making a macro to make it more readable," you're quite the joker!
niXar
+7  A: 

I use it quite often in places where I'm constrained to work in a constructor - for example, the new .NET 3.5 LINQ to XML constructs - to define default values when an optional parameter is null.

Contrived example:

var e = new XElement("Something",
    param == null ? new XElement("Value", "Default")
                  : new XElement("Value", param.ToString())
);

or (thanks asterite)

var e = new XElement("Something",
    new XElement("Value",
        param == null ? "Default"
                      : param.ToString()
    )
);

No matter whether you use the ternary operator or not, making sure your code is readable is the important thing. Any construct can be made unreadable.

Erik Forbes
Or... var e = new XElement("Something", new XElement("value", param == null ? "Default" : param.toString()));
asterite
I like that you are formatting it for readability, so many don't.
bruceatk
What good is human readable source code if it's not human readable? =)
Erik Forbes
+1  A: 

I treat ternary operators a lot like GOTO. They have their place, but they are something which you should usually avoid to make the code easier to understand.

Dan Walker
+9  A: 

It makes debugging slightly more difficult since you can not place breakpoints on each of the sub expressions. I use it rarely.

David Segonds
That's the best argument against the ternary operator I ever heard. I don't buy the "not readable" argument (it sounds to me like people being too lazy to get used to it) but this actually has substance.
EpsilonVector
+4  A: 

I agree with jmulder: it shouldn't be used in place of a if, but it has its place for return expression or inside an expression:

echo "Result: " + n + " meter" + (n != 1 ? "s" : "");
return a == null ? "null" : a;

The former is just an example, a better i18n support of plural should be used!

PhiLho
The first ternary is incorrect - you've got a : where the ? should go: (n != 1 ***?*** "s" : "")
Erik Forbes
Yes, thanks for pointing that out! Fixed.
PhiLho
+6  A: 

I use the ternary operator where ever I can, unless it makes the code extremely hard to read, but then that's usually just an indication that my code could use a little refactoring.

It always puzzles me how some people think the ternary operator is a "hidden" feature or is somewhat mysterious. It's one of the first things I learnt when I start programming in C, and I don't think it decreases readability at all. It's a natural part of the language.

ilitirit
I am completely in agreement. There is nothing hidden or tricky about it.
mmattax
It can cause readability issues, especially when nested.
David Thornley
I think "*extremely* hard to read" is a bit too permissive, but overall I agree with you. There's nothing difficult or mystical about it.
EpsilonVector
+3  A: 

I think the ternary operator should be used when needed. It is obviously a very subjective choice, but I find that a simple expression (specially as a return expression) is much clearer than a full test. Example in C/C++:

return (a>0)?a:0;

Compared to:

if(a>0) return a;
else return 0;

You also have the case where the solution is between the ternary operator and creating a function. For example in Python:

l = [ i if i > 0 else 0 for i in lst ]

The alternative is:

def cap(value):
    if value > 0:
        return value
    return 0
l = [ cap(i) for i in lst ]

It is needed enough that in Python (as an example), such an idiom could be seen regularly:

l = [ ((i>0 and [i]) or [0])[0] for i in lst ]

this line uses properties of the logical operators in Python: they are lazy and returns the last value computed if it is equal to the final state.

PierreBdR
That last line hurts my brain...
Erik Forbes
+23  A: 

It's a question of style, really; the subconscious rules I tend to follow are:

  • Only evaluate 1 expression - so foo = (bar > baz) ? true : false, but NOT foo = (bar > baz && lotto && someArray.Contains(someValue)) ? true : false
  • If I'm using it for display logic, e.g. <%= (foo) ? "Yes" : "No" %>
  • Only really use it for assignment; never flow logic (so never (foo) ? FooIsTrue(foo) : FooIsALie(foo) ) Flow logic in ternary is itself a lie, ignore that last point.

I like it because it's concise and elegant for simple assignment operations.

Keith Williams
good guidelines and nice examples!
nickf
I think most langauges won't let you use it for flow logic, so you couldn't do (foo)?True(foo):False(foo); unless it was an assignment.
PintSizedCat
Oops, yes you're right, my bad.
Keith Williams
In C# you can use it for flow control if you're assigning a delegate from within the ternary, and then invoking it afterwards. Well, that's kind of flow control...
Erik Forbes
Your two first examples are really bad. The results of comparisons are already boolean values, so your ternary operators are useless and only complicate the code.
Trillian
+3  A: 

I almost never use the ternary operator because whenever I DO use it, it always makes me think a lot more than I have to later when I try to maintain it.

I like to avoid verbosity, but when it makes the code a lot easier to pick up, I will go for the verbosity.

Consider:

String name = firstName;

if (middleName != null) {
    name += " " + middleName;
}

name += " " + lastName;

Now, that is a bit verbose, but I find it a lot more readable than:

String name = firstName + (middleName == null ? "" : " " + middleName)
    + " " + lastName;

or:

String name = firstName;
name += (middleName == null ? "" : " " + middleName);
name += " " + lastName;

It just seems to compress too much information into too little space, without making it clear what's going on. Everytime I see ternary operator used, I have always found an alternative that seemed much easier to read... then again, that is an extremely subjective opinion, so if you and your colleagues find ternary very readable, go for it.

Mike Stone
That's not exactly the same thing though. In the second example you're compressing all three statements into one line. That is what decreases readability, not the ternary operator.
ilitirit
Fair enough, I updated to incorporate your comment, but it still just feels cluttered to me... but again, it's subjective... I'm not saying ternary is not readable, I'm saying it's not readable to me (99% of the time)
Mike Stone
+4  A: 

I like using the operator in debug code to print error values so I don't have to look them up all the time. Usually I do this for debug prints that aren't going to remain once I'm done developing.

int result = do_something();
if( result != 0 )
{
  debug_printf("Error while doing something, code %x (%s)\n", result,
                result == 7 ? "ERROR_YES" :
                result == 8 ? "ERROR_NO" :
                result == 9 ? "ERROR_FILE_NOT_FOUND" :
                "Unknown");
}
indiv
scnr: http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
Meinersbur
A: 

I'm a big fan of it ... when appropriate.

Stuff like this is great and, personally, I don't find it too hard to read/understand:

$y = ($x == "a" ? "apple"
   : ($x == "b" ? "banana"
   : ($x == "c" ? "carrot"
   : "default")));

I know that probably makes a lot of people cringe, though.

One thing to keep in mind when using it in PHP is how it works with function that return a reference.

class Foo {
    var $bar;
    function Foo() {
        $this->bar = "original value";
    }
    function &tern() {
        return true ? $this->bar : false;
    }
    function &notTern() {
        if (true) return $this->bar;
        else      return false;
    }
}

$f = new Foo();
$b =& $f->notTern();
$b = "changed";
echo $f->bar;  // "changed"

$f2 = new Foo();
$b2 =& $f->tern();
$b2 = "changed";
echo $f2->bar;  // "original value"
nickf
That's because ternary operator evaluates the result and returns $this -> bar by its value whereas the other one just plain returns the variable.
Nouveau
it's strange how that doesn't cause an error, since you're therefore not returning a reference.
nickf
+48  A: 

Use it for simple expressions only:

int a = (b > 10) ? c : d;

Don't chain or nest ternary operators as it hard to read and confusing:

int a = b > 10 ? c < 20 ? 50 : 80 : e == 2 ? 4 : 8;

Moreover, when using ternary operator, consider formatting the code in a way that improve readability:

int a = (b > 10) ? some_value                 
                 : another_value;
marcospereira
Totally agree with the first few statements but totally disagree with your example of "improved readability". If you're going for multi-line why not just use an if statement?
Joe Philllips
just because if else is a quite more verbose for simple decisions: int a = 0; if(b > 10) a = some_value; else a = another_value;What do you prefer?
marcospereira
@d03boy: Because if-statement is just that, a statement, and won't do when all you want is an expression.
roe
+1  A: 

I recently saw a variation on ternary operators (well, sort of) that make the standard "() ? :" variant seem to be a paragon of clarity:

var Result = [CaseIfFalse, CaseIfTrue][(boolean expression)]

or, to give a more tangible example:

var Name = ['Jane', 'John'][Gender == 'm'];

Mind you, this is Javascript, so things like that might not be possible in other languages (thankfully).

Nouveau
wow, that's awful! imagine nesting a couple of those together! The only vaguely useful thing I can see with that is if you had a function which returned a 2-element array: var Name = getNames()[Gender == 'm']; ...but that's even LESS readable!
nickf
+1  A: 

Only when:

$var = (simple > test ? simple_result_1 : simple_result_2);

KISS.

why the parenthesis?
niXar
A: 

How would anyone win an obfuscated code contest without the ternary operator?!

I'm personally for using it, when appropriate, but I don't think I'd ever nest it. It's very useful, but it has a couple knocks against it in that it makes code harder to read and is in use in some other languages in other operations (like Groovy's null-check).

Bill James
+18  A: 

The Ternary ?: operator is merely a functional equivalent of the procedural if construct. So as long as you are not using nested ?: expressions, the arguments for/against the functional representation of any operation applies here. But nesting ternary operations can result in code that is downright confusing (exercise for the reader: try writing a parser that will handle nested ternary conditionals and you will appreciate their complexity).

But there are plenty of situations where conservative use of the ?: operator can result in code that is actually easier to read than otherwise. For example:

int compareTo(Object object) {
    if((isLessThan(object) && reverseOrder) || (isGreaterThan(object) && !reverseOrder)) {
       return 1;
    if((isLessThan(object) && !reverseOrder) || (isGreaterThan(object) && reverseOrder)) {
       return -1;
    else
      return 0;              
}

Now compare that with this:

int compareTo(Object object) {
    if(isLessThan(object))
        return reverseOrder ? 1 : -1;         
    else(isGreaterThan(object))
        return reverseOrder ? -1 : 1;
    else        
       return 0;              
}

As the code is more compact it there is less syntactic noise, and by using the ternary operator judiciously (that is only in relation with the reverseOrder property) the end result isn't particularly terse.

Ryan Delucchi
i would still advocate using accolades on every if/then/else construction that is not ternary tho, so your second example is missing a few imho.
Kris
+1  A: 

For simple if cases, I like to use it. Actually it's much easier to read/code for instance as parameters for functions or things like that. Also to avoid the new line I like to keep with all my if/else.

Neseting it would be a big NO-NO in my book.

So, resuming, for a single if/else I'll use the ternary operator. For other cases a regular if/else if/else (or switch)

Rodrigo Gómez
A: 

Interesting anecdote: I have seen the optimizer weigh ternary operator as less "heavy" for the purposes of inlining than the equivalent if. I noticed this with Microsoft compilers, but it could be more widespread.

In particular functions like this would inline:

int getSomething()
{
   return m_t ? m_t->v : 0;
}

But this wouldn't:

int getSomething() 
{
    if( m_t )
        return m_t->v;
    return 0;
}
Don Neufeld
+1  A: 

I typically use in things like this:

before:

if(isheader)
    drawtext(x,y,WHITE,string);
else
    drawtext(x,y,BLUE,string);

after:

    drawtext(x,y,isheader==true?WHITE:BLUE,string);
KPexEA
Of course in most languages, you wouldn't need the "==true" part of that ternary either.
Michael Haren
I realize that, although I tend to put it in just to make the code more readable since the compiler should optimize it to the same thing as without the ==true anyways
KPexEA
in *no* language can you possibly need "==true"
niXar
I had hard times deciding whether to upvote or not. The example is nice but the ==TRUE is something I can't stand seeing in other people's code.
Peter Perháč
A: 

I like it a lot. When I use it, I write it like an if-then-else: one line each for condition, true action, and false action. That way, I can nest them easily.

Example:

x = (a == b 
     ? (sqrt(a)-2)
     : (a*a+b*b)
     );

x = (a == b 
     ? (sqrt(a)-2)
     : (a*a+b*b)
     );
x = (a == b 
     ? (c > d
        ? (sqrt(a)-2)
        : (c + cos(d))
       )
     : (a*a+b*b)
     );

To me, this is reasonably easy to read. It also makes it easy yo add subcases or change existing cases.

I thought I was a huge fan until I saw that example. That would take some getting used to. I use them for one-liners, not blocks.
Michael Haren
Just go buy yourself a Lisp, you closeted homoschemual.
niXar
This looks horrible. And I consider myself a fan of the operator.
EpsilonVector
+5  A: 

Chained I'm fine with - nested, not so much.

I tend to use them more in C simply b/c they're an if statement that has value, so it cuts down on unnecessary repetition or variables:

x = (y < 100) ? "dog" :
    (y < 150) ? "cat" :
    (y < 300) ? "bar" : "baz";

rather than

     if (y < 100) { x = "dog"; } 
else if (y < 150) { x = "cat"; }
else if (y < 300) { x = "bar"; } 
else              { x = "baz"; }

In assignments like this, I find it's less to refactor, and clearer.

When I'm working in ruby on the other hand, I'm more likely to use if...else...end because it's an expression too.

x =   if (y < 100) then "dog"
    elif (y < 150) then "cat"
    elif (y < 300) then "bar"
    else                "baz"
    end

(although, admittedly, for something this simple, I might just use the ternary operator anyway).

rampion
I like your first example - I hadn't thought of chaining them like that before. Thanks for sharing. =)
Erik Forbes
A: 

I use and recommend ternaries to avoid code lines in situations where the logic is trivial.

int i;
if( piVal ) {
    i = *piVal;
} else {
    i = *piDefVal;
}

In the above case I would choose a ternary, because it has less noise:

int i = ( piVal ) ? *piVal : *piDefVal;

Likewise conditional return values are good candidates:

return ( piVal ) ? *piVal : *piDefVal;

I think compactness can improve readability which in turn helps to improve the code quality.

But readability always depends on the code's audience.

The readers must be able to understand the a ? b : c pattern without any mental effort. If you can not presume this, go for the long version.

mar10
I agree. Once you understand how they work, it is way more readable. Ternary operators are the greatest thing since the foreach loop!
+1  A: 

I like Groovy's special case of the ternary operator, called the Elvis operator: ?:

expr ?: default

This code evaluates to expr if it's not null, and default if it is. Technically it's not really a ternary operator, but it's definitely related to it and saves a lot of time/typing.

Steve Losh
Yeah, I love that one as well - it's `??` in C#, the null coalesce operator: http://stackoverflow.com/questions/278703/unique-ways-to-use-the-null-coalescing-operator
Jarrod Dixon
A: 

if your ternary operator ends up taking the whole screen width, then I wouldn't use it. I keep it to just checking one simple condition and returning single values:

int x = something == somethingElse ? 0 : -1;

We actually have some nasty code like this in production...not good:

int x = something == (someValue == someOtherVal ? string.Empty : "Blah blah") ? (a == b ? 1 : 2 ): (c == d ? 3 : 4);
Ricardo Villamil
There is actually a language where writing string.Empty makes any sense? What happened to ""?
niXar
A: 

The ternary operator is extremely useful for concisely producing comma separated lists. Here is a Java example:

    int[] iArr = {1,2,3};
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < iArr.length; i++) {
        sb.append(i == 0 ? iArr[i] : "," + iArr[i]);
    }
    System.out.println(sb.toString());

produces: "1,2,3"

Otherwise, special casing for the last comma becomes annoying.

Julien Chastang
A: 

If you are trying to reduce the amount of lines in your code or are refactoring code, then go for it.

If you care about the next programmer that has to take that extra 0.1 millisecond to understand the expression, then go for it anyways.

Jobo
+25  A: 

I love them, especially in type-safe languages.

I don't see how this:

int count = (condition) ? 1 : 0;

is any harder than this:

int count;

if (condition)
{
  count = 1;
} 
else
{
  count = 0;
}

edit -

I'd argue that ternary operators make everything less complex and more neat than the alternative.

Ian P
+1  A: 

For simple tasks like assigning a different value depending on a condition they're great. I wouldn't use them when there are longer expressions depending on the condition tho.

Svet
+1  A: 

If you and your workmates understand what they do and they aren't created in massive groups I think they make the code less complex and easier to read because there is simply less code.

The only time i think ternary operators make code harder to understand is when you have about 3 or 4 or more in the one line. Most people don't remember that they are right based precedence and when you have a stack of them it makes reading the code a nightmare.

EDIT: 5 in one group? What was I thinking!! thats way to much :) 3 or 4 is more reasonable.

Alex
A: 

No, ternary operators do not increase complexity. Unfortunately, some developers are so oriented to an imperative programming style that they reject (or won't learn) anything else. I do not believe that, for example:

int c = a < b ? a : b;

is "more complex" than the equivalent (but more verbose):

int c;
if (a < b) {
    c = a;
} else {
    c = b;
}

or the even more awkward (which I've seen):

int c = a;
if (!a < b) {
    c = b;
}

That said, look carefully at your alternatives on a case-by-case basis. Assuming a propoerly-educated developer, ask which most succinctly expresses the intent of your code and go with that one.

joel.neely
int c = MIN( a, b ); // Seems clearer than the ternary operator.
And MIN is defined where in the C standard? You still have to write code to implement it, as in: int MIN (int n1, int n2) { return (n1 < n2) ? n1 : n2; }".
paxdiablo
@causualcode: It was an example.
joel.neely
+12  A: 

Like so many opinion questions, the answer is inevitably: it depends

For something like:

return x ? "Yes" : "No";

I think that is much more concise (and quicker for me to parse) than:

if (x) {
    return "Yes";
} else {
    return "No";
}

Now if your conditional expression is complex, then the ternary operation is not a good choice. Something like:

x && y && z >= 10 && s.Length == 0 || !foo

is not a good candidate for the ternary operator.

As an aside, if you are a C programmer, GCC actually has an extension that allows you to exclude the if-true portion of the ternary, like this:

/* 'y' is a char * */
const char *x = y ? : "Not set";

Which will set x to y assuming y is not NULL. Good stuff.

Sean Bright
Fixed slight syntax and grammar prob, Sean :-) Missing y from last bit of code and "assign x to y" means "y = x", so I chgd to "set x to y".
paxdiablo
@Pax: Thanks! I rolled back the syntax change since I was trying to point out that with GCC extensions you don't need the if-true portion of the ternary.
Sean Bright
Sorry, didn't see that paragraph. Don't know that I agree with that sort of stuff though since it allows people to write code that won't compile with a ISO-standard compiler. Still, when GCC is the last man standing, that won't matter :-)
paxdiablo
It is voodoo, for sure... And who doesn't use GCC? :D
Sean Bright
A: 

I used to be in the “ternary operators make a line un-readable” camp, but in the last few years I’ve grown to like them when used in moderation. Single line ternary operators can increase readability if everybody on your team understands what’s going on. It’s a concise way of doing something without the overhead of lots of curly braces for the sake of curly braces.

The two cases where I don’t like them: if they go too far beyond the 120 column mark or if they are embedded in other ternary operators. If you can’t quickly, easily and readably express what you’re doing in a ternary operator. Then use the if/else equivalent.

Joe Basirico
A: 

It depends :)

They are useful when dealing with possibly null references (btw: Java really needs a way to easily compare two possibly null strings).

The problem begins, when you are nesting many ternary operators in one expression.

Actually I disagree with your 'BTW'. Does a NULL string equal another NULL string or not? My opinion is they're not actually strings until they're non-NULL.
paxdiablo
Maybe I'm a little biased - recently I do mostly eclipse rcp, and I can't count places in code where I've seen variations on this theme:if ( (evt.getNewValue()!=null }//do sth
A: 

No (unless they're misused). Where the expression is part of a larger expression, the use of a ternary operator is often much clearer.

Denis Hennessy
+5  A: 

I like 'em. I don't know why, but I feel very cool when I use the ternary expression.

JimDaniel
+5  A: 

I've seen such beasts like (it was actually much worse since it was isValidDate and checked month and day as well, but I couldn't be bothered trying to remember the whole thing):

isLeapYear =
    ((yyyy % 400) == 0)
    ? 1
    : ((yyyy % 100) == 0)
        ? 0
        : ((yyyy % 4) == 0)
            ? 1
            : 0;

where, plainly, a series of if-statements would have been better (although this one's still better than the macro version I once saw).

I don't mind it for small things like:

reportedAge = (isFemale && (Age >= 21)) ? 21 + (Age - 21) / 3 : Age;

or even slightly tricky things like:

printf ("Deleted %d file%s\n", n, (n == 1) ? "" : "s");
paxdiablo
A: 

Excel does not give you a choice. Here is my favorite Excel macro. Can you figure out what it does? :-)

=IF(DASHBOARD!$F$6=1,
IF(VLOOKUP($C10,IND.WORKSHEET!$C$6:$GS$208,152,FALSE)=DASHBOARD!$A$227,
(VLOOKUP($C10,IND.WORKSHEET!$C$6:$GS$208,153,FALSE)*
VLOOKUP($C10,IND.WORKSHEET!
$C$6:$GS$208,150,FALSE)*VLOOKUP(VLOOKUP($C10,IND.WORKSHEET!
$C$6:$GS$208,151,FALSE),ORG.WORKSHEET!$B$126:$Q$137,13,FALSE)*1000),0),
IF(VLOOKUP($C10,IND.WORKSHEET!$C$6:$GS$208,122,FALSE)=DASHBOARD!$A$227,
(VLOOKUP($C10,IND.WORKSHEET!$C$6:$GS$208,123,FALSE)*
VLOOKUP($C10,IND.WORKSHEET!
$C$6:$GS$208,120,FALSE)*VLOOKUP(VLOOKUP($C10,IND.WORKSHEET!
$C$6:$GS$208,121,FALSE),ORG.WORKSHEET!$B$126:$Q$137,13,FALSE)*1000),0))

Please, before any more down-votes, read my comment.

cdonner
Err, can't you create user functions in Excel VBA that can be called as a cell function?
paxdiablo
I was kidding. Sorry that it did not come across that way. I did not write this macro.
cdonner
Er, kidding not for the sake of the joke, but the underline the point that others have made - namely that once you reach a certain level of complexity, you want to look for other options.
cdonner
If by "read my comment" you mean the comments not in the answer itself, you can edit your answer to include the comments.
ShreevatsaR
I know, but that I prefer not to tamper with the "evidence".
cdonner
+7  A: 

By the measure of cyclomatic complexity, the use of if statements or the ternary operator are equivalent. So by that measure, the answer is no, the complexity would be exactly the same as before.

By other measures such as readability, maintainability, and DRY (Don't-Repeat-Yourself), either choice may prove better than the other.

Greg Hewgill
A: 

I think it really depends on the context they are used in.

Something like this would be a really confusing, albeit effective, way to use them:

 __CRT_INLINE int __cdecl getchar (void)
{
   return (--stdin->_cnt >= 0)
          ?  (int) (unsigned char) *stdin->_ptr++
          : _filbuf (stdin);
}

However, this:

c = a > b ? a : b;

is perfectly reasonable.

I personally think they should be used when they cut down on overly verbose IF statements. The problem is people are either petrified of them, or like them so much they get used almost exclusively instead of IF statements.

Onion-Knight
+4  A: 

If you're using the ternary operator for a simple conditional assignment I think it's fine. I've seen it (ab)used to control program flow without even making an assignment, and I think that should be avoided. Use an if statement in these cases.

Bill the Lizard
+1  A: 

As others have pointed out they are nice for short simple conditions. I especially like them for defaults (kind of like the || and or usage in javascript and python), e.g.

int repCount = pRepCountIn ? *pRepCountIn : defaultRepCount;

Another common use is to initialize a reference in C++. Since references have to be declared and initialized in the same statement you can't use an if statement.

SomeType& ref = pInput ? *pInput : somethingElse;
maccullt
Amazing that this is the first mention of initialising references, which is one of the few places where "if" cannot be used instead of ?:. (I guess because this is not a C++-specific question...) They are also useful in constructor initialisation lists, for the same reason.
j_random_hacker
A: 

No. They are hard to read. If/Else is much easier to read.

This is my opinion. Your mileage may vary.

Genericrich
+1  A: 

A so many answers have said, it depends. I find that if the ternary comparison is not visible in a quick scan down the code, then it should not be used.

As a side issue, I might also note that its very existence is actually a bit of an anomoly due to the fact that in C, comparison testing is a statement. In Icon, the if construct (like most of Icon) is actually an expression. So you can do things like:

x[if y > 5 then 5 else y] := "Y"

... which I find much more readable than a ternery comparison operator. :-)

There was a discussion recently about the possibility of adding the ?: operator to Icon, but several people correctly pointed out that there was absolutely no need because of the way if works.

Which means that if you could do that in C (or any of the other languages that have the ternery operator), then you wouldn't, in fact, need the ternery operator at all.

staticsan
A: 

string someSay = bCanReadThis ? "No" : "Yes";

Steven A. Lowe
A: 

In small doses they can reduce the number of lines and make code more readable; particularly if the outcome is something like setting a char string to "Yes" or "No" based on the result of a calculation.

Example:

char* c = NULL;
if(x) {
  c = "true";
}else {
  c = "false";
}

compared with:

char* c = x ? "Yes" : "No";

The only bug that can occur in simple tests like that is assigning an incorrect value, but since the conditional is usually simple it's less likely the programmer will get it wrong. Having your program print the wrong output isn't the end of the world, and should should be caught in all of code review, bench testing and production testing phases.

I'll counter my own argument with now it's more difficult to use code coverage metrics to assist in knowing how good your test cases are. In the first example you can test for coverage on both the assignment lines; if one is not covered then your tests are not exercising all possible code flows.

In the second example the line will show as being executed regardless of the value of X, so you can't be certain you've tested the alternate path (YMMV depending on the ability of your coverage tools).

This matters more with the increasing complexity of the tests.

Adam Hawes
+1  A: 

My recently formulated rule of thumb for determining whether you should use the ternary operator is:

  • if your code is choosing between two different values, go ahead and use the ternary operator.
  • if your code choosing between two different code paths, stick to an if statement.

And be kind to readers of your code. If you are nesting ternary operators, format the code to make that nesting obvious.

Travis
A: 

One reason noone seems to mention for using the ternary operator, at least in languages like D that support type inference is to allow type inference to work for amazingly complicated template types.

auto myVariable = fun();  
// typeof(myVariable) == Foo!(Bar, Baz, Waldo!(Stuff, OtherStuff)).

// Now I want to declare a variable and assign a value depending on some
// conditional to it.
auto myOtherVariable = (someCondition) ? fun() : gun();

// If I didn't use the ternary I'd have to do:
Foo!(Bar, Baz, Waldo!(Stuff, OtherStuff)) myLastVariable;  // Ugly.
if(someCondition) {
    myLastVariable = fun();
} else {
    myLastVariable = gun():
}
dsimcha
A: 

I like the operator in some situations, but I think some people tend to over use it and that it can make the code harder to read.

I recently stumbled acorss this line in some open source code I am working to modifiy.

where 
               (active == null ? true : 
               ((bool)active ? p.active : !p.active)) &&... 

Instead of

where ( active == null || p.active == active) &&...

I wonder if the ternary use adds extra overhead to the LINQ statement in this case.

Tim
A: 

I agree with the sentiments of many of the posters here. The ternary operator is perfectly valid as long as it is used correctly and does not introduce ambiguity (to be fair, you can say that about any operator/construct).

I use the ternary operator often in embedded code to clarify what my code is doing. Take the following (oversimplified for clarity) code samples:

Snippet 1:

int direction = read_or_write(io_command);

// Send an I/O
io_command.size = (direction==WRITE) ? (32 * 1024) : (128 * 1024);
io_command.data = &buffer;
dispatch_request(io_command);

Snippet 2:

int direction = read_or_write(io_command);

// Send an I/O
if (direction == WRITE) {
    io_command.size = (32 * 1024);
    io_command.data = &buffer;
    dispatch_request(io_command);
} else {
    io_command.size = (128 * 1024);
    io_command.data = &buffer;
    dispatch_request(io_command);
}

Here, I am dispatching an input or output request. The process is the same whether the request is a read or a write, only the default I/O size changes. In the first sample, I use the ternary operator to make it clear that the procedure is the same and that the size field gets a different value depending on the I/O direction. In the second example, it is not as immediately clear that the algorithm for the two cases is the same (especially as the code grows much longer than three lines). The second example would be more difficult to keep the common code in sync. Here, the ternary operator does a better job of expressing the largely parallel nature of the code.

The ternary operator has another advantage (albeit one that is normally only an issue with embedded software). Some compilers can only perform certain optimizations if the code is not "nested" past a certain depth (meaning inside a function, you increase the nesting depth by 1 every time you enter an if, loop, or switch statement and decrease it by 1 when you leave it). On occasion, using the ternary operator can minimize the amount of code that needs to be inside a conditional (sometimes to the point where the compiler can optimize away the conditional) and can reduce the nesting depth of your code. In some instances, I was able to re-structure some logic using the ternary operator (as in my example above) and reduce the nested depth of the function enough that the compiler could perform additional optimization steps on it. Admittedly this is a rather narrow use case, but I figured it was worth mentioning anyway.

bta
Why don't you move io_command.data = and dispatch_request(io_command); outside of the if-else statement though? Just place them afterward. Less code duplication.
EpsilonVector
+1  A: 

The ternary operator hands down. They aren't complex if you format properly. Take the leap year example from @paxdiablo:

$isLeapYear = 
   (($year % 400) == 0)
   ? 1
   : ((($year % 100) == 0)
      ? 0
      : ((($year % 4) == 0)  
         ? 1 
         : 0));

This can be written more concise and be made much more readable with this formatting:

//--------------test expression-----result
$isLeapYear = (($year % 400) == 0) ? 1 : 
              ((($year % 100) == 0)? 0 : 
              ((($year % 4) == 0)  ? 1 : 
                                     0));//default result

See: http://www.dnawebagency.com/the-ternary-operator-usage-and-examples

jeremysawesome
A: 

(Hack of the day)

define IF(x) x ?

define ELSE :

Then you can do if-then-else as expression:

int b = IF(condition1) res1 ELSE IF(condition2) res2 ELSE IF(conditions3) res3 ELSE res4;

John John