• (cs) in reply to Schol-R-LEA
    Schol-R-LEA:
    As for the ternary operator, I have no problem with it when used both sparingly and correctly. This is not sparing, and more importantly, it's not correct.

    You've hit the nail on the head. The ternary operator doesn't kill code maintenance, abuse of the ternary operator does.

  • Jens (unregistered)

    Admittedly, there is an indentation error, which might have been introduced on submission rather than being in the original code.

    Once you correct indentation, i.e. shift everything starting with (? '' #'[Mailing in Progress]') one level to the left, you see that this very nicely and readably represents a decision tree structure that is NOT a series of elsifs.

    It is therefore entirely appropriate to indent in a way that represents branches in the tree, rather than use a block structure as if it was a case/switch/cond/whatever statement.

    I find this code very readable (apart from the indentation error at the end) as it shows you clearly:

    1. that this serves to assign a value to $send_button
    2. the decision process (tree structure) to determine that value

    Having if/then/else constructs for this, with individual $send_button = ... statements hidden in the different branches would be far less readable.

    P.S.: some people claimed that $send_now gets checked twice in a row, this is not the case. It gets checked in the $approved branch and in the !($approved) branch, with quite different results.

  • Michael (unregistered) in reply to tomh
    tomh:
    Oh, and to those who commented that the ternary operator is somehow evil, don't get me wrong: it is outstanding to use as an inline if/then/else because it is terse (for example in a logging message). But it's nothing more than a terse form. Words are better than symbols.

    Um, words are symbols too!!

    So in your universe... words > symbol words = symbol

    I think you need to revise the foundations of your universe.

    A better statement is that ? : should be used to return one of a selection of values of a given type. The process of choices shouldn't be repeated in a later ? : (hint to use if else)

    It is also usefull in initialization in c++. As if else is not permitted when intializing class variables.

    Mostly ? : should comfortably fit on the one line (readably so). If it starts to overlapping seriously consider if else constructs.

    CAPTCHA: kungfu nope, kung has fu anywhere.

  • Geraud (unregistered) in reply to jimrandomh
    jimrandomh:
    It's a simple matter of text-editor skills to turn this into the much more reasonable looking:

    ... 40 lines of non-working code ...

    Nice try. Another approach would be to use a good text editor with syntax highlighting. The kind that tells you at first glance where a comment starts and where it ends. And based on this, make a reasonable use of your brain. You may eventually come up with something like :

    my $send_button
        = ( ($rAuth->permits(SEND)) && ($status == 1) && ($approved) && (!$send_now) )
            ? qq(
                <form action="schedule" method="POST">
                

    <input type="image" name="send" src="$::root/sendit.png" alt="Send" border="0" class="form-align" >

    <input type="hidden" name="state" value="$sh" > </form> ) : '';

    Compact, readable, works for me.

  • (cs)

    You're all wrong with your fancy tabular indentations. The whole point of a ternary operator is to keep everything in one line. The correct way to do this snippet would be...

    my $send_button = ( !$rAuth->permits(SEND) ? '' : $status != 1 ? '' #'[Mailing must be unlocked to send now]' : $approved ? $send_now ? '' #'[Mailing in Progress]' : qq( <form action="schedule" method="POST">

    <input type="image" name="send" src="$::root/sendit.png" alt="Send" border="0" class="form-align">

    <input type="hidden" name="state" value="$sh"></form> ) : $send_now ? '' #'[Cancelling]' : '' #'[Approval Required]' ) );

    Just because most people are horisontally challenged doesn't mean I should ignore a perfectly good dimension.

  • (cs) in reply to Jens
    Jens:
    P.S.: some people claimed that $send_now gets checked twice in a row, this is not the case. It gets checked in the $approved branch and in the !($approved) branch, with quite different results.
    As I have said before, I agree that the use of the ternary operator rather than if/elsif seems okay to me. But - unless I am missing something obvious, it's still a WTF for a couple of reasons, for example: Apart from the comments (which might have been used for debugging with some tool that auto-generates warn statements based on comments), there are only two possible results: Print the button or don't. Again, unless I am missing something, it would appear to me that this simply amounts to:
    my $send_button = (  ($rAuth->permits(SEND))
                      && ($status == 1)
                      && ($approved)
                      && (!$send_now)
                      )
                          ? print_button($fh)
                          : '';
    # Only include Send button if all conditions met.
    

    sub print_button {

    Why aren't we using a templating system?

    return qq( # etc. etc. ) }

    Apart from that, IMHO the real WTF is mixing application logic, authorization, representation/HTML generation and persistence (via the hidden form field) in one variable assignment.

  • (cs) in reply to Geraud
    You may eventually come up with something like : ...
    I see we had the same idea - I suspect that useless decision tree was used for debugging...
  • Geraud (unregistered) in reply to Unomi
    Unomi:
    Good for Perl-mongers to obfuscate things into some new alchemy language, nice to keep them busy. But if certain business process are grinding to halt because nobody can read the code to modify anything it's gonna cost you money.

    Oh enough already! A guy who puts crappy Perl code in an application is not a paranoid willing to secure his job, he's just a crappy Perl coder and should be kicked out as such.

    Now repeat after me: You can write unreadable code in every language. Every goddamn one of them. All it takes is variables and methods named with one or two characters only.

    Now if people could stop assuming that every module in CPAN is Perl golf with documentation maybe they could realize that the dude who wrote this piece of code was a pizza delivery guy who woke up one day during the dotcom era with the strange idea that he was a software developer.

  • Ged (unregistered) in reply to anonymous workaholic
    anonymous workaholic:
    OK, so it's cleanly indented and perfectly readable code that - horror of horrors - uses the ternary operator. Why do people hate this little operator so much? It's essentially the same thing as an if clause, nothing complicated or obscure going on here. IMHO the actual WTF here is the use of global flag variables, especially the way $send_now is checked once and then again in the else branch of the first check.

    I don't think anyone hates the ternary operator. It's the abusing that hurts us. Just like the other day then one with the catch{} finally{}. When a dimwit programmer finds some new cool trick and tries to implement it without completely understanding why it should or shouldn't be done, things go boom. Here a classic case of if/else would clearly made it at least readable and thus maintainable.

  • anne (unregistered) in reply to mangobrain
    mangobrain:
    C gives you enough rope to hang yourself with, but warns you that you probably don't want to knot it that way. Perl gives you the rope, ties a noose in the end, blindfolds you, and stands you on a rickety chair.

    Don't forget, there's more than one way to do it in Perl. Perl also hands you a loaded gun, a bottle of pills and a glass of water, and does it all on a tall bridge. Oh, and a bottle of gasoline and a lit match. (thanks, captcha, "burned", for reminding me of that one.)

  • (cs)

    I like the ternary operator a lot for having sane default values for HTTP parameter input:

    $username = array_key_exists( "username", $HTTP_GET_VARS ) ? $HTTP_GET_VARS["username"] : "anonymous";

  • (cs) in reply to Tired Coder
    Tired Coder:
    Anonymous Coward:
    The whole "ternary operators produce unmaintainable code" myth is totally self-perpetuating. Because people are told the myth, they avoid coding with ternary operators, so when they come across a piece of code like in this example, it takes them ages to figure out what it does, so they think ternary operators produce unmaintainable code. I use ternary operators in my code, and I'm happy to nest them too (although not to that crazy extent). As a result, when I looked at that, I quickly knew exactly what it did (despite not knowing perl). The real WTF is the people who call themselves programmers can't cope with such a trivial concept.

    Wow, you must be really good to immediately know exactly what that piece of code was doing. How did you manage to type this so quickly with both hands patting yourself on the back? There are concrete reasons why the ternary operator is harder to read than the if/else block, some of which have already been pointed out here. A few that come to mind:

    1. No obvious standard for indentation and formatting so you have to go searching in a complex expression for that colon.

    2. Operator precedence isn't always immediately clear.

    3. Unlike an if statement, it can't be easily read from left to right (you don't know you are reading a branching condition until you see the "?").

    Yes, the ternary operator produces more succinct code than if/else blocks, making complex statements slightly more difficult to step through line by line (but it still should not be impossible for anyone who knows the language). Though so do many constructs in programming languages, such as functions, classes, closures, recursion, and they are not considered unmaintainable. In fact, they usually make the code more readable as a whole, despite the extra effort required for someone going through the program line by line. If someone were to forgo all these features and just code a single function with nothing but simple statements, it may be easy to follow each individual line of the program. However, the program as a whole will be long and virtually impossible to read.

    The obvious alternative in this case, an string of if/else ifs, would have looked horrendous. Yes, it would be easy to step through it and see what was happening, but there would have had to be a lot of if/else statements to go through. Instead thats all been reduced to a single (just long) statement that does one thing, assign a value to $send_button. If you are familiar with the ternary operator (which, as the gp stated, many unfortunately are not), its pretty clear what is going on.

    Addendum (2007-02-11 19:25): BTW, I'm not that familiar with Perl, so if all those "#'[Mailing in Progress]'" statements are nothing but comments, then indeed it could be simplified into just one check and let all the others default to "". But then the problem isn't with the ternary operator, it would look just as bad as if/else if statements.

  • (cs)

    Summing up this thread so far:

    We see a multi-layered decision tree, with weird indentation, whose sole purpose is

    • to assign a string to $send_button if all of four conditions are met
    • else assign it an empty string.

    Conclusion:

    a.) They should have used about 40 lines of useless nested conditional statements instead of the ternary operator. Even if incorrectly indented, this would be so much better. b.) They should not have used Perl. As you may have noticed, all the CodeSODs published on TDWTF so far have been in Perl.

    Frankly, WTF?!

  • charles bretana (unregistered) in reply to Anonymous Coward
    Anonymous Coward:
    The whole "ternary operators produce unmaintainable code" myth is totally self-perpetuating. Because people are told the myth, they avoid coding with ternary operators, so when they come across a piece of code like in this example, it takes them ages to figure out what it does, so they think ternary operators produce unmaintainable code. I use ternary operators in my code, and I'm happy to nest them too (although not to that crazy extent). As a result, when I looked at that, I quickly knew exactly what it did (despite not knowing perl). The real WTF is the people who call themselves programmers can't cope with such a trivial concept.

    Couldn't agree more! Ternery operators are syntactically equivilent to multiple nested if/ else ifs, except they are shorter and therefore much easier to read (Less duplicate meaningless characters for the eye to scan).
    Addiditonally, when the purpose is not to execute one of many different branches of code (where ternery cannot be used anyway), but simply to control which of multiple expressions will be assigned to a single variable, th ternery operator is MUCH cleaner and easier to read than multiple nexted If/Else Ifs. And the the greater the number of different expression values which must be discriminated, the greater the advantedge the ternery operator has over IF Else Ifs... Because with If Else Ifs, not only does the eye have to scan all the If Else Ifs, and decipher the parentheses, it also has to scan all the internal statements inside the If Elses, to ensure that the assignment statement is in fact assigning the different expression values to the same left side in each and every one. Compare readability...

    string msg = !IsConnected? "You are not Connected.": !IsAuthorized? "Not authorized to send Msg.": Success? "Message Successfully Sent.": KnownFailure? "Msg Failed- " + sReason: "Msg Failed - Unknown.";
    to

    string msg; if (IsConnected) { if (IsAuthorized) { if (Success) { msg = "Not authorized to send Msg.": } else { if (KnownFailure) { msg = "Msg Failed- " + sReason; } else { msg = "Msg Failed - Unknown."; } } } else { msg = "Not authorized to send Msg."; } }
    else { msg = "You are not Connected."; }

    There's absolutely no comparison as to which is clearer and more readable... All the extra characters for the Ifs and Elses add zero meaning or comprehension, and the multiple redundant instances of "msg =" are, just that --- multiple and redundant

  • brad (unregistered) in reply to Peter da Silva
    Peter da Silva:
    That's perfectly normal Lisp code. I don't know why they used a bunch of macros to make it look like Perl, though.

    captcha: "ninjas" - macro ninjas are the worst.

    captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,

    what's the deal with words that are terribly ungraceful. Let's come up with a better word for this, that sounds better in one's head. How about "dumb comment next -- dumcom"

  • charles bretana (unregistered) in reply to charles bretana

    Indentation (spaces I addded) in editor screen did not come through in submitted msg... How do you create indentation in this forum ??

  • (cs) in reply to charles bretana
    charles bretana:
    Indentation (spaces I addded) in editor screen did not come through in submitted msg... How do you create indentation in this forum ??

    Use BBCode code tags (http://thedailywtf.com/Info/BBCode.aspx).

  • stnever (unregistered) in reply to mangobrain
    What language do you prefer then?
    Um... if I answer that this will turn into a flamewar :)

    I think both extremes are evil. On one extreme, we develop code to solve a problem while hoping the language/optimizer/whatever will do everything for us and save our day. This is complete lazyness.

    On the other, we stop at every single statement to check if everything is as it should be, keep track of every single allocated byte to deallocate later, make many tests on an array index before acessing the array with it. This is premature optimization (the root of all evil).

    Perhaps the best approach is, as is often the case, the "middle" one. I usually develop with functionality in mind; along the way I take note of possible performance bottlenecks and/or error conditions. After a few rounds of testing, I attack the most important ones first and leave comments on the others. (I do not usually test array indexes or buffer lengths because, as I said before, my language of choice does that for me. Surely it chokes when bad data comes, but in these cases I simply log the error -- in my experience, more often than not it's my API client's fault).

    This got a little off-topic; it spawned because I consider the ternary operator an "advanced" feature, that only us "advanced coders" can understand. Newbies don't. And I believe no one but the geekest of them will understand it someday because they will likely learn to write "the code for the results" than to write "the code for the housekeeping".

  • (cs) in reply to Anonymous Coward
    Anonymous Coward:
    The whole "ternary operators produce unmaintainable code" myth is totally self-perpetuating. Because people are told the myth, they avoid coding with ternary operators, so when they come across a piece of code like in this example, it takes them ages to figure out what it does, so they think ternary operators produce unmaintainable code. I use ternary operators in my code, and I'm happy to nest them too (although not to that crazy extent). As a result, when I looked at that, I quickly knew exactly what it did (despite not knowing perl). The real WTF is the people who call themselves programmers can't cope with such a trivial concept.
    Amen.
  • Miral (unregistered)

    I've had one instance of the compiler (MSVC6) f**king up the ternary operator (actually, technically it was the optimiser, not the compiler), by evaluating all three expressions (in this particular case, causing the code to crash as it was a null-protection).

    So that's made me a little shy of using them in that particular compiler. But other than that I think they can be useful as long as they're kept fairly short or formatted nicely, as others have said.

  • (cs) in reply to brad
    brad:
    Peter da Silva:
    That's perfectly normal Lisp code. I don't know why they used a bunch of macros to make it look like Perl, though.

    captcha: "ninjas" - macro ninjas are the worst.

    captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,captcha, captcha,

    what's the deal with words that are terribly ungraceful. Let's come up with a better word for this, that sounds better in one's head. How about "dumb comment next -- dumcom"

    SIGH. A CAPTCHA (an initialism for "Completely Automated Public Turing test to tell Computers and Humans Apart", trademarked by Carnegie Mellon University) is a type of challenge-response test used in computing to determine whether or not the user is human.

  • clayne (unregistered) in reply to ChrisF

    Whoever wrote that "lookup table" version needs to learn about switch/case. An if cascade like that is absolutely crap for performance.

  • clayne (unregistered) in reply to dww

    "The thing to remember is that almost all code gets written ONCE but read MANY TIMES, and (except for those mathematicians who grok APL) humans read and understand words better than they do strings of punctuation. Which is why I instinctively disliked C the first time I saw it some 30 years ago. Even before I discovered its other fatal flaws such as uncheckable use of pointers and an IO system that reads in data without knowing if there's enough space in the buffer.

    With so many more readable and maintainable languages coming along, I though C was a temporary aberration. It turned out to be as temporary as income tax"

    Are you high? Perl is in no way easier to read than C. It is WORSE.

  • Rhamphoryncus (unregistered) in reply to charles bretana
    charles bretana:
    Couldn't agree more! Ternery operators are syntactically equivilent to multiple nested if/ else ifs,
    This I agree with, but it's not an argument either way. Nearly all languages are turing-complete, and thus equivalent.
    except they are shorter and therefore much easier to read (Less duplicate meaningless characters for the eye to scan).
    This is not so clear: * Less characters is always easier reading? Not true. A common english word, say "houses", can be read much faster than a string of random characters, say "3d*#x5" * Visual structure helps readability? Absolutely. You used whitespace to provide structure to your ternary operators, although you missed the code tag and they became harder to read. * Removing redundancy helps programmers? This is true, but I don't think it's so direct. The real goal is to let them think about higher level concepts and waste less time on petty details. * Ternary operators reduce redundancy? Sort of, sort of not. They let you skip the assignments, but this is usually the simplest (and least distracting) part of the code in question.
    charles bretana:
    Addiditonally, when the purpose is not to execute one of many different branches of code (where ternery cannot be used anyway), but simply to control which of multiple expressions will be assigned to a single variable, th ternery operator is MUCH cleaner and easier to read than multiple nexted If/Else Ifs. And the the greater the number of different expression values which must be discriminated, the greater the advantedge the ternery operator has over IF Else Ifs... Because with If Else Ifs, not only does the eye have to scan all the If Else Ifs, and decipher the parentheses, it also has to scan all the internal statements inside the If Elses, to ensure that the assignment statement is in fact assigning the different expression values to the same left side in each and every one. Compare readability...
    But you see, you had your if-else version backwards, and you demonstrate how poorly {} can be. Compare with how I would have written it:
    if (!Connected)
        msg = "You are not Connected.";
    else if (!Authorized)
        msg = "Not authorized to send Msg.";
    else (!Success) {
        if (KnownFailure)
            msg = "Msg Failed - " + sReason;
        else
            msg = "Msg Failed - Unknown";
    } else
        msg = "Message Successfully Sent.";
    

    This becomes much closer. I would have done it in python and perhaps made the "Unknown" failure reason into a default. If you really wanted you could have removed some of the line feeds, making them yet closer.

    At this point the question becomes: is the removal of redundancy worth having to learn a second way of doing things? The brain is not boundless, there is a real cost to be payed.. but I can't say if it's worth it.

    string msg = !IsConnected?  "You are not Connected.":
                 !IsAuthorized? "Not authorized to send Msg.":
                  Success?      "Message Successfully Sent.":
                  KnownFailure? "Msg Failed- " + sReason:
                                "Msg Failed - Unknown.";
    to
    string msg;
    if (IsConnected)
    { 
       if (IsAuthorized)
       {
          if (Success)
          { 
             msg = "Not authorized to send Msg.":
          }
          else
          {
             if (KnownFailure)
             {
                 msg = "Msg Failed- " + sReason;
             }
             else
             {
                 msg = "Msg Failed - Unknown.";
             }
          }
       }
       else
       {
           msg = "Not authorized to send Msg.";
       }
    }   
    else
    {
       msg = "You are not Connected.";
    }

    There's absolutely no comparison as to which is clearer and more readable... All the extra characters for the Ifs and Elses add zero meaning or comprehension, and the multiple redundant instances of "msg =" are, just that --- multiple and redundant

  • (cs) in reply to clayne
    clayne:
    Whoever wrote that "lookup table" version needs to learn about switch/case. An if cascade like that is absolutely crap for performance.
    That would be me then (among others). Some thoughts:
    • The switch/case syntax is not supported by the core perl distribution (will be in Perl 6, but as of now, you have to load an external module/library to support it).
    • For the above reason, I strongly doubt that the switch/case version would be better for performance (external library) than a type of syntax that (strongly optimizing) perl supports natively. Have you ever benchmarked it?
    • As others have pointed out, nested ternary operators (in tabular layout) offer the advantage of not having to repeat the assignment for each case. This has the potential of making the code more concise and readable.
  • Anonymous (unregistered)

    At first, a huge WTF. But reading comments seems that some people can read it. People acustomed to use "?:;". I can't read the code, but I know how to use "?:;", so I think to me, is too much "?:;". To me this mean that this is still a WTF, because you code something only old-Lisp guys and some guy to overuse ?:; will understand. And you want to write code for all people, not a subset. Also, the point of ?:; is oneline, that this code is not.

  • Tom Melly (unregistered)

    Yuk - and I like the ternary operator and perl... Here's a discussion on the ternary operator at perlmonks... http://www.perlmonks.org/?node_id=587227

  • Marcin (unregistered)

    No, functional if derives from lisp. Of course, they should have used cond. In scheme. That would have compiled to fast, efficient code because it's not a scripting language.

  • A.C. (unregistered)

    $quack ? "quack" : "no quack";

  • (cs)

    I have seen worse :-D At least the indentation makes it vaguely readable.

  • PC Paul (unregistered) in reply to ChrisF
    ChrisF:
    charles bretana:
    Indentation (spaces I addded) in editor screen did not come through in submitted msg... How do you create indentation in this forum ??

    Use BBCode code tags (http://thedailywtf.com/Info/BBCode.aspx).

    Is there a code that will wrap the text to a sane length, 'cos the forum s/w certainly doesn't do it.

    Todays comments are all about a mile wide, and the white background runs out after the first screen...

    Insert ObTheRealWTFisTheForumSoftware here.

  • (cs) in reply to ChrisF
    ChrisF:
    Never thought I'd write a classic "The Real WTF(TM) Is" comment, but here we go. Some people have commented that the cascading ternary operators are the WTF, but at least the code is nicely indented. I beg to differ - nested ternaries would be perfectly okay in this case (even recommended in Perl Best Practices for conditional assignment), but with a tabular layout that resembles a lookup table like so:
             # Condition            # Value
    my $post = $comment_number == 1 ? 'Frist psot 111 eleventy-one'
             : $comment_number == 2 ? 'The Real WTF'
             : $comment_number == 3 ? 'Not really a WTF'
             : $comment_number == 4 ? 'FILE_NOT_FOUND'
             : $comment_number == 5 ? 'Brillant'
             : $comment_number == 6 ? 'Where\'s the wooden table'
             : $comment_number == 7 ? 'Needs more XML'
             :                        "This wouldn't have happened if they had used $my_favourite_language in the first place" # (default)
    ;
    
    Not necessarily less readable than cascaded ifs/elsifs, but much more compact.

    It took me a couple of minutes to see how this worked. A very fair exchange for a format which, long term, is far easier to read than nested if/else if and far more flexible than switch statements (I come from a C background). I'll be using this, in moderation.

    Kudos to ChrisF for finding a good use of the WTF comment set, too.

  • Martijn (unregistered)

    Included with PhotoShop was/is a little-known filter-"language" known as Filter Factory.

    It's very useful if you're the programmer type of graphician and I've been able to do things with it that PhotoShop cannot do itself, but that's besides the point.

    This language consisted out of upto 4 sections (for each of R, G, B and transparency), each containing upto one 1024-character line of C-like syntax. It is without doubt the most restricted language designed to be of practical use.

    This language's ONLY flow control was the ternairy operator. So basically every source-code looked like the snippet in the article, only without variables, line breaks, indenting and multiple statements.

    Oh, and by the way; it was fun to program :)

  • Anton Shafarenko (unregistered)

    Eh, every language feature can be abused. You can pry my hook ops from my cold dead fingers though.

    x = x < lo ? lo : x; y = y > hi ? hi : y; z = z < lo ? lo : z > hi ? hi : z; // Clamp z to [lo, hi]

    Is this really less clear than a bunch of if/else blocks that express the same thing? I even added a comment to the last one for anyone unfamiliar with the idiom to save them parsing time (I imagine the associativity of ?: is because whoever first came up with that operator had expressions like the above in mind).

  • (cs)

    At least it is indented properly! All that is missing are some comments.

  • foo (unregistered)

    so much badness, where to begin? It hurts to even think about it.

    WTF, elevenary? WTF, HTML embedded in Perl? WTF, scoping a scalar to namespace null and not to main? WTF, hard-code an image name? WTF, five cases with the same output?

  • foo (unregistered) in reply to Derrick Pallas

    Operators don't kill maintainability, bad programmers kill maintainability.

  • (cs)

    Management was so happy that the mod_perl version ran in four seconds instead of thirty-four that they sang the praises of the development team as they fired them.

    I love a happy ending.

  • Godai (unregistered)

    Wow, this hit close to home.

    I started writing my master's thesis on extensibility of a language and as a side along project wrote a pre-compiler for ruby which would take code that would allow what i refered to as a n-ary statement.

    The n-ary extended the trinary to mimic to work like a numeric switch statement.

    so

    (expresion that evaluates to a #)? 1-result: 2-result: 3-result...: n-result: default result;

    where if it evaluates to 1-n it does the appropriate result else the default result.

    It worked but I kept having problems trying to justify the use. (I realize there isn't much use to the n-ary. But the problem was also with the tri-nary) I kept running into the syntactic sugar arguments.

  • Aaron (unregistered)

    That looks strangely elegant. Completely unmaintainable, obviously, but elegant.

    Hey Alex - can you add a script to this forum that will automatically delete people's submissions if their captcha appears anywhere in their post?

  • Rhamphoryncus (unregistered) in reply to Anton Shafarenko
    Anton Shafarenko:
    Eh, every language feature can be abused. You can pry my hook ops from my cold dead fingers though.

    x = x < lo ? lo : x; y = y > hi ? hi : y; z = z < lo ? lo : z > hi ? hi : z; // Clamp z to [lo, hi]

    Is this really less clear than a bunch of if/else blocks that express the same thing? I even added a comment to the last one for anyone unfamiliar with the idiom to save them parsing time (I imagine the associativity of ?: is because whoever first came up with that operator had expressions like the above in mind).

    x = max(low, x)
    y = min(y, high)
    z = max(low, max(z, high))

    The third option could perhaps be improved, although in my experience it's not that important:

    z = clamp(low, z, high)

    Anyway, the point is that, for all the pieces of code that could be improved by conditional expressions, usually there's another option that beats them both.

  • (cs) in reply to anonymous workaholic
    anonymous workaholic:
    Why do people hate this little operator so much?

    That little operator has its utility, but the code cited clearly isn't an example of how it should be used. That much seems obvious.

  • Rhamphoryncus (unregistered) in reply to Godai
    Godai:
    The n-ary extended the trinary to mimic to work like a numeric switch statement.

    so

    (expresion that evaluates to a #)? 1-result: 2-result: 3-result...: n-result: default result;

    You can almost have this in python:

    [0-result, 1-result, 2-result, ... n-result][(expression that evaluates to a #)]

    The only limitation is that it doesn't provide a default. Wouldn't be that hard to add a class (or function) that adds it though.

  • Paddington Bear (unregistered)

    Where's today's WTF? I'm ready to move on...

  • Sid2K7 (unregistered)

    I like the fact that some people actually think this is as readable as if-clauses. And that they assume its "readable" because it has indentation levels.

    The whole indentation makes it misunderstandable:

    Since the questionmark is followed by the true-branch of the operation and the colon is followed by the false-branch, they should be on the same level.

    If you start reading this, at some point (maybe because a function name sounds like it returns a bool) you WILL misread

    ? isSomething()

    as

    if (isSomething())
  • anonymous (unregistered) in reply to wgh

    captcha: Penis Breath Fitting for you.

  • Jens (unregistered) in reply to Sid2K7
    Sid2K7:
    The whole indentation makes it misunderstandable:

    Since the questionmark is followed by the true-branch of the operation and the colon is followed by the false-branch, they should be on the same level.

    This is exactly how it is done in the example.

    The only thing that is wrong with the example is the indentation error (that was quite probably introduced on submission to TDWTF) and the fact that the decision tree could be compacted due to the fact that most cases actually give the same result.

    Other than that it is far more readable than anything that has been suggested here and is clearly the best way to represent a variable assignment where the value is determined by a decision tree.

    This is actually rather good code. It is very readable and easy to maintain. The use of cond ? trueValue : falseValue construct makes it very clear that you are dealing with a value assignment, where the branches should (and do) determine the value without side effects. This is not the case with an if/then/else construct.

    For all of you who are confused by this, you might want to actually take some time to learn about programming, including different paradigms such as functional programming, instead of just saying "I only know how to use goto, everything else is confusing crap".

  • David GLAUDE (unregistered) in reply to Adin
    Adin:
    Thus, if you have (a && b), both a and b must be true for the whole expression to be true. If a is true, then b is evaluated. If a is false, b is not evaluated.

    If you have (a || b), only one has to be true for the whole expression to be true. If a false, then b is evaluated. If a is true, then b is skipped.

    Of course you understand that depending on the compiler the order in wich things are evaluated may depend...

    It is even possible that in order to optimise, both a and b are evaluated simultaniously.

    If it work for you here and now (this compiler and this version)... do not rely on that.

  • Anonymous (unregistered) in reply to Rhamphoryncus
    Rhamphoryncus:
    (n-ary operator)

    You can almost have this in python:

    [0-result, 1-result, 2-result, ... n-result][(expression that evaluates to a #)]
    Despite the syntactic similarity, this is different in that it will evaluate ALL expressions given in the list, then pick one of the results. If your expressions have side effects, this is critical.
  • mugs (unregistered)

    If used properly, a string of ternary operators can actually be very useful. i.e. The book Perl Best Practices includes an example like this:

    $var =	$cond1	?	"Val1" :
    	$cond2	?	"Val2" :
    	$cond3	?	"Val3" :
    	$cond4	?	"Val4" :
    			"Val4";
    

    Everything is lined up nicely, and the meaning is clear.

Leave a comment on “Turn it up to Eleven”

Log In or post as a guest

Replying to comment #:

« Return to Article