• (disco)

    ternary operators....

    [image]
  • (disco)

    Can we get a classic from before this year or is this some kind of Discourse/new site design limitation?

  • (disco) in reply to hungrier
    hungrier:
    Can we get a classic from before this year or is this some kind of Discourse/new site design limitation?

    Ask that exact same question tomorrow and your wish will be granted.

    At least, probably, until the next non-classic article gets published...

  • (disco) in reply to PJH

    Tomorrow's article: "Happy New Year! Take a break!"

    Friday's article: "Classic WTF 2015 - Happy New Year! Take a break!"

  • (disco)

    I like ternaries to keep things short and simple, but once you get over 3 or 4 simple nested ones or a couple complicated ones, you're probably better off going to if statements.

  • (disco)

    I think ternary operators address a need for conditional expressions (as opposed to statements). I use them in languages that don't provide conditional expressions. But ideally, I'd rather do something like:

    foo = if (conditon)
    {
        1
    }
    else
    {
        2
    }
    

    This is easier to follow than two separate assignments to foo and it makes it makes the purpose of the whole conditional clearer.

  • (disco) in reply to accalia
    accalia:
    ternary operators
    Can be very useful when used correctly. Such circumstances are rare, but they do happen.
  • (disco) in reply to RaceProUK

    Yeah, ternary operators are actually awesome. Nested ones are usually WTF-ey.

  • (disco)

    Didn't really read all of it but at a quck glance I would replace most of the code with some hefty binary mask operators...

  • (disco)

    Hold on, I've got a reaction for code like this...

    [image]

    Ah, there we go.

  • (disco)

    The way I tend to use ternary operators is in special cases for strings. For example, in C++:

    cout << "You have to open " << iCount << " more case" << (iCount == 1 ? "" : "s") << " before the next offer." << endl;
    

    Otherwise, I tend to use the if-else structures.

  • (disco) in reply to hungrier

    Christmas is special and sacred. Meant to be spent with loved ones.

    New Years though is about drinking, staying up late, and (occasionally) making poor decisions as a result. Since any of these three things can be pinpointed as the root cause behind many, if not most, of the WTFs that we publish, anything goes!

    Oh, I plan to run an Errord on Friday.

  • (disco)

    I don't think a human wrote this code, but I can't decide between decompiler or orangutan.

    ETA: I don't always use ternaries, but when I do, I'm usually trying to a. avoid dereferencing a null pointer, b. get NULLIF or two-argument COALESCE action, or c. making my code harder to internationalize like Nutster.

    Curly brace languages are simply a PDP-11 macro assembler that is about 2/3 of the way to reading mail.

  • (disco) in reply to kjordan2001

    Nested ternaries are awesome, if you follow the correct association rule. Consider:

      case1 ? action1 
    : case2 ? action2
    : case3 ? action3
    : case4 ? action4
    : failureAction;
    

    If you end up needing parentheses to do the nesting, you're doing it wrong and will regret it. lalalalaalla body is too similar to what I recently posted wah discourse wah why

  • (disco) in reply to Captain

    PHP gets the ternary's asssociativity wrong, of course.

    $ cat ternary.php
    <?php
    echo (FALSE ? "a" : FALSE ? "b" : "c")."\n";
    echo (FALSE ? "a" : TRUE ? "b" : "c")."\n";
    echo (TRUE ? "a" : FALSE ? "b" : "c")."\n";
    echo (TRUE ? "a" : TRUE ? "b" : "c")."\n";
    ?>
    
    $ php ternary.php
    c
    b
    b
    b
    
  • (disco) in reply to kjordan2001

    I use ternaries for all assignements and returns, if statements are for flow control.

    Good indentation makes most ternaries very readable.

    But for more complex or nested ternaries I usually try to break out part of them into functions that through the name makes the intention clear.

    Deeply nested ifs are no better than deeply nested ternaries for readability ;)

    If I still end up with unreadable code I probably need to refactor the whole part of the code :D

  • (disco) in reply to Zylon
    Zylon:
    Hold on, I've got a reaction for code like this...
    [image]

    FTFY

  • (disco) in reply to tar

    No, it just follows its own rules.

  • (disco) in reply to CoyneTheDup
    CoyneTheDup:
    [PHP] just follows its own rules

    Its own rules which are wrong.

  • (disco) in reply to tar

    The comments on the article @CoyneTheDup linked explain that well enough.

  • (disco) in reply to ben_lubar

    Then we are all in agreement then.

    <img src=http://whydoesitsuck.com/public/why-does-php-suck/thumbnail.png" alt="PHP sucks!">

  • (disco) in reply to David_Martensson
    David_Martensson:
    If I still end up with unreadable code I probably need to refactor the whole part of the code

    QFT

  • (disco)

    The funny thing is, the code in article is basically concatenation of string constants based on bit fields values. No ifs or ?:s needed at all.

  • (disco)

    Ternaries are bad, yes. But the real problem are those && || destoperators. Aside from the few l33tkings, no programmer really knows what they mean or how they work. They often just turn a piece of code into an unreadable mess of symbol soup.

    You tell me - what's more readable: (A)

    x=a&&b==c||d>e||f<g&&h&&i
    

    (B)

    if (a)
    {
        x = Constants.True;
    }
    else if (b == c)
    {
        x = Constants.True;
    }
    else
    {
        x = Constants.False;
    }
    
    if (x == Constants.False)
    {
        if (d > e)
        {
            x = Constants.True;
        }
    }
    
    if (x == Constants.False)
    {
        if (f < g)
        {
            x = Constants.True;
        }
        else if (h)
        {
            x = Constants.True;
        }
        else if (i)
        {
            x = Constants.True;
        }
    }
    
  • (disco) in reply to CreatedToDislikeThis

    :trolleybus:

  • (disco) in reply to Nutster

    Don't do this! Plurals don't work the same way in all languages! Use ngettext and friends instead!

  • (disco) in reply to CreatedToDislikeThis
    created_just_to_disl:
    x=a&&b==c||d>e||f<g&&h&&i

    ###(C)

    var boolA = a && b == c;
    var boolB = d > e;
    var boolC = F < g && h && i;
    x = boolA || boolb || boolC;
    

    also either put spaces around your operators or don't but mixing modes between examples is cheating! :-P

  • (disco) in reply to CreatedToDislikeThis

    Does (B) even test things the same way as (A) does?

    • (a&&(b==c)) is true if a and also b==c in (A)
    • (a&&(b==c)) is true if a is true in (B), even if b==c is wrong.
  • (disco) in reply to aliceif

    this too.

    the second example might (and i say might, because i think (C) is best) be more readable, but it also gets different answers for same input compared to (A)

  • (disco) in reply to accalia

    (D)

    x=a?b==c?a:d>e?true:f<g?h?i:h:false:d>e?true:f<g?h?i:h:false;
    
  • (disco) in reply to aliceif

    http://i.imgur.com/bj3qaA6.gif

  • (disco) in reply to aliceif

    (E)

    x = (a && (b == c))     ||
        (d > e)             ||
        ((F < g) && h && i)
    
  • (disco) in reply to PleegWat

    Added note: I only advocate pattern (E) in the illustrated example, where all lines are of acceptable line length. If one of the conjunctive (or disjunctive, if the logic is the other way around) subclauses does not fit on a line, this pattern very quickly becomes unreadable.

  • (disco)

    (F)

    http://www.reactiongifs.us/wp-content/uploads/2013/03/kill_it_with_fire.gif

  • (disco)

    What I want to know is why nobody uses a good old fashioned switch for this sort of thing. It might take more lines of code and might be one whole lot clearer. That might be seen as a good idea…

  • (disco) in reply to CreatedToDislikeThis

    (A) is in disjunctive normal form. So... (A).

  • (disco) in reply to PleegWat

    It can be okay to have long clauses. I do prefer prefix notation to postfix notation. For example:

    x = (a && (b == c)
     || (d > e)
     || ((F < g) && foo()
                 && bar()
                 && baz() )
    
  • (disco) in reply to CreatedToDislikeThis
    created_just_to_disl:
    Constants.True

    What unmerciful god rules over you?

  • (disco)

    (G)

    x = a if b == c
    x = d > e unless x
    x = f < g unless x or not h or not i
    

Leave a comment on “Classic WTF - One Bad Ternary Operator Deserves Another”

Log In or post as a guest

Replying to comment #:

« Return to Article