• (cs)

    Awe?so:me;

  • bla (unregistered)

    Oh. My.

  • 10 (unregistered)

    I wonder how the guys were able to actually have this work correctly.. Most of the times such long & hard to read pieces of code are bugs' favorite nest.

  • Unomi (unregistered)

    Things people are sometimes forgetting is 'maintainability' even when the author is dead.

    In other words: try to make your code clean, but readable for any other programmer (or people with some gift of analysis).

    What if the author/maintainer gets hit by a truck? Who's gonna have the task to read his code? Is it readable? No? Rewrite it till it does.

    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.

    Question: how long does it take on average to analyse code (your own, or others if your familiar with it) and spot the place where something goes wrong? In other words, how quick can people spot something wrong/weird in the code?

    Captcha: bling (that is sooooo 2006)

    • Unomi -
  • Eric (unregistered)

    More accurately, C is the world's first portable assembler.

  • Kalle (unregistered)
    cond && amp; var_t || var_f
    what does this mean?
  • mm (unregistered) in reply to Kalle

    HTML entity gone wrong. twice an ampersand+a+m+p+semicolon

    cond && var_t || var_f

  • Plastriq (unregistered)

    That is indeed a WTF.

  • Zonkers (unregistered) in reply to Kalle
    Kalle:
    cond && amp; var_t || var_f
    what does this mean?

    I think the "& amp;" might actually be a mistake. It might be intended to not have the space in there so that would show up as just an "&" in html, which would make it look like,

    cond && var_t || var_f
  • pok (unregistered) in reply to Kalle
    Kalle:
    cond && amp; var_t || var_f
    what does this mean?

    It's two lines of code on one line. Missing a ; though. Should be

    cond && amp; var_t || var_f;

    which works out true/false and then dumps it on the floor...

  • Adin (unregistered) in reply to Kalle

    Short version: (cond && amp) is the same as: if (cond) amp; (var_t || var_f) is the same as if (!var_t) var_f;

    Long version "&&" is the logical and operator. "||" is the logical or operator. In C, logical operator have a short circuit feature, i.e. they only evaluate as far as they need to.

    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.

  • (cs)

    Wow!!! This guy must like Lisp :) but parenthesis are much more legible than '?' and ':'.

    10:
    I wonder how the guys were able to actually have this work correctly.. Most of the times such long & hard to read pieces of code are bugs' favorite nest.

    Who said it worked? I just could see that management liked it, and it was fast. No mention to bugs.

  • (cs)

    I must admit, the first second I looked at the program I found the structure rather elegant. You know, like when you learn some new language, with new paradigms, and are amazed how you could program without those nice structures. Like anonymous (lambda) functions, and such things.

    But then, that's the very same intent that leads to WTFs like this one. When the "look at me I'm creative" overcomes the "let's find a way to make it readable, maintainable, DRY and elegant and perhaps compact". At first it looks elegant and then you realize it's impossible to understand anything ; it must be damn hard to change any test without having to decrypt the whole thing again and again.

    Reminds me of bad humorists. Great performers come with new idea, so surprising you can't help but laugh. Then you have unfunny clowns that just imitate the good ones in a pathetic way. They even think exaggerating their imitation make them more funny than the original. Well, sometimes bad clowns become programmers.

  • anonymous workaholic (unregistered)

    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.

  • mikewinny (unregistered) in reply to anonymous workaholic

    i agree with the anonymous workaholic, theres nothing wrong with use of the ternary operator (in moderation). recently i found that employing ?: in C# to determine a value based on a relatively simple set of conditions, resulted in more efficient IL than a mess of if-else statements, and quite frankly a little more readable. indenting was a bit of an issue tho; i like clean code!

  • phx (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 think I'll go postal if I ever have to maintain YOUR code.

    Perfectly readable, my ass...

  • Peter da Silva (unregistered)

    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.

  • (cs) in reply to mikewinny
    mikewinny:
    i agree with the anonymous workaholic, theres nothing wrong with use of the ternary operator (in moderation).
    "In moderation" would be the keyword(s) here.

    The use of short-circuiting logical operators for flow control is quite idiomatic in Perl, but a sequence of if/elsif/.../else would have done this code a load of good in terms of readability. (That said, though, I appreciate the elegance of "open FOO or die" as much as the next Perl coder, and I've written Perl code using "?:" for flow control myself once or twice.)

    I doubt that the "if" construct would improve the performance over the "?:" variant, however, so I guess there must have been some more WTFs in that CGI script.

  • anonymous guy (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.

    Here, ladies and gentlemen, we have proof positive why this is a wtf. It is not "cleanly indented". If you actually bother to decipher the code, you will see that it is inconsistently indented. Which anonymous workaholic obviously did not do, because it was too hard. He just looked at the pretty indentations and assumed it was ok.

  • TimF (unregistered)

    ... ?: is right associative.

    e.g.:

        x = y & 1 ? c1 : 0 |
            y & 2 ? c2 : 0;

    is really

        x = ((y & 1) ? c1 : 0 | 
             y & 2) ? c2 : 0;

    not

        x = (y & 1 ? c1 : 0) |
            (y & 2 ? c2 : 0);

    Don't let that pretty formatting fool you, whitespace does not alter precedence.

  • Hiredman (unregistered)

    This is just good C programming. Anyone who doesn't agree has forgotten the wise words from An Ode to C. Whippersnappers...

    From the sacred text: use -> for a pointer a dot if its not ? : is confusing use them a lot

    For anyone who doesn't know it: http://gdl.msu.edu/~vanhoose/humor/0844.html

    =Hiredman

  • jimrandomh (unregistered)

    There are two things wrong, both of which are actually easy to fix. The first is using ?: in place of if/else, and the second is doing the ?: equivalent of

        if(...) {
        } else {
            if(...) {
            } else {
                if(...) {
                }
            }
        }
    

    rather than using "else if".

    It's a simple matter of text-editor skills to turn this into the much more reasonable looking:

    my $send_button
    
    if(!$rAuth->permits(SEND))
    	$send_button = '';
    else if($status != 1)
    	$send_button = '' #'[Mailing must be unlocked to send now]';
    else if($approved)
    {
    	if($send_now)
    		$send_button = '' #'[Mailing in Progress]';
    	else
    	{
    		$send_button = 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> ); } } else { if($send_now) $send_button = '' #'[Cancelling]'; else $send_button = '' #'[Approval Required]'; }
  • Rolf (unregistered) in reply to TimF
    TimF:
    Don't let that pretty formatting fool you, whitespace does not alter precedence.

    You're right. That makes it much harder to maintain the code.

  • HE (unregistered)

    Anyone ever looked at the code of Irssi? It's full to the brim with code like that.

  • (cs) in reply to jimrandomh
    jimrandomh:
    It's a simple matter of text-editor skills to turn this into the much more reasonable looking:
    You might like to acquire some Perl skills to go alongside those text-editor skills. Your "reasonable looking" version is not valid Perl syntax.

    Hint: braces are required after "if" and "else". That's why there's such a thing as "elsif".

  • (cs)

    "These go to eleven."

  • Anonymous Coward (unregistered)

    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.

  • (cs)

    It's quite impressive to see ways to make C++ even more obtuse than it already is. And, of course any reasonable optimizing compiler would turn this into the same thing as, say, a nicely formatted if/then/else, or maybe a switch. So presumably the goal was to a) write the most readable code, or b) impress someone (which apparently has been accomplished through being published on WTF).

    The power of the human mind to complicate otherwise simple things is truly astounding.

  • (cs)

    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.

  • Tired Coder (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.

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

  • Anonymous Coward (unregistered) in reply to Tired Coder
    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?
    It's just what you're used to.
    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.
    The same applies to arithmetic.
    2. Operator precedence isn't always immediately clear.
    The same applies to arithmetic.
    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 "?").
    I don't know anybody who really reads code left to right. With a large if/then/else block, you don't immediately know that its purpose is an assignment.
  • (cs)

    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.

  • (cs)

    ...obviously my example is bad in that you would not use conditional logic at all in this case, but you get the idea...

  • Kuba (unregistered)

    Looks like obfuscated LISP to me :)

  • Stephen Touset (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.

    ...

    The real WTF is the people who call themselves programmers can't cope with such a trivial concept.

    I agree completely. The ternary operator, even nested, can be extremely readable as long as one uses the proper indentation and formatting. It's a great replacement for a long series of if/elsif/elsif/elsif/else statements, especially if you're assigning the result to something, or if all the statements contained in the elsif are only one line.

    Random example, in Ruby:

    val =   x < y   ? y
          : x == 4  ? x
          : y == 7  ? 2
          :           -1
    
  • Stephen Touset (unregistered) in reply to ChrisF
    ChrisF:
    I beg to differ - nested ternaries would be perfectly okay in this case (even recommended in Perl Best Practices for conditional assignment)...

    Exactly. I'd intended (but forgot) to mention that Perl Best Practices actually even recommends the practice. I've started using it quite a lot in any language that supports the ternary operator. As long as it's formatted readably, it's compact and understandable.

  • Anonymous Coward (unregistered) in reply to Stephen Touset

    Yeah, Perl Best Practices recommends this, but it also recommends the tabular layout shown 2 posts up. Thus, still a WTF... it does the Right Thing (ternary ops) in the Wrong Way (nested if-else indentation, instead of elsif/tabular indentation).

  • DrYak (unregistered)

    I DO write such code, you insensitive clod...

    ...except mine happen to be correctly indented, fully commented, and do actually work.

    The ternary operator is useful when you have to assign multiple different possible values to 1 single var-name and may later need to rename the var. Specially in languages that don't support the GNU-C feature ({ ... ; return_value; })

    Preferring "if/then/else" clauses to ternary operators just for the sake of readability is like prefering "begin/end" to curly braces : it's just cosmetic without any real valid reason.

    ...of course, ternary operators, coupled with GNU-C ({ }) leads to the best abuse ever :

    void function {
     int i = 0;
          # // long series of variable declare/init;
     int where = (some_check_function()) 
       ? (gather_result_from_check() )     // get result;
       : ({ print_error("message"); exit(2); 0; )} // exit with error and skip the rest of declare/init;
          # // long series of variable declare/init;
    
     // rest of code is here. New code maintainer puts break point here and doen't understand while the debugger doesn't always trap it.
    }
    

    Captcha : Cognac - I swear I never drink some before writing my code.

  • Crash (unregistered)

    Clearly an ex-LISP programmer. That's exactly how (if ..) works in Scheme. Too bad Perl can't compile this sort of thing into anything reasonable.

  • Frank (unregistered)

    Just because you can - doesn't mean you should.

    If you don't understand a block of code in 1 minute, it's too complicated.

  • Pax Diablo (unregistered)

    Hey, what's wrong with that? I wrote a similar macro in C that returned the number of days in a given month (although it didn't get to eleven segments).

  • dww (unregistered)

    Hey, that's one of the first bits of code here I could read!

    The ternary operator in Perl can be used to good effect, especially in a one-line assignment. But not when nested, especially to this level.

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

    CAPTCHA ? burned : yes I have been, many times.

  • mangobrain (unregistered) in reply to dww
    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.
    Spoken like a true script kiddie ;)

    Ok, forgive me, that was a little harsh. On a more serious note, though, if you aren't sure a pointer has been initialised before using it, or that it is pointing to the right thing, or that a given I/O loop isn't going to overflow a buffer, then you should rethink how you've designed your code - it is clearly doing things you didn't think it would ever do, and that you possibly don't understand. As someone who programs daily in C, C++ and Perl, and has experimented with Python and the abomination that is Java, let me tell you that I prefer C to Perl (although I prefer C++ much more than either).

    Pointer arithmetic is good fun, and a useful concept that doesn't slow things down. Buffer overflows needn't be an issue if you just think before coding, and ensure that you know certain things such as whether or not a given library call will return a NULL terminated string (as opposed to an unterminated collection of bytes). Memory leaks can be a problem, and ensuring you don't have them can be tedious in a function with multiple exit points, but that's just a matter of discipline (or of using C++ instead ;) - if you aren't sure, use Valgrind, it's a lifesaver.

    Perl might be garbage collected, but it certainly isn't type safe. There's nothing to stop me passing a function an array reference instead of an array, or even a string or an integer. What's worse is that the code may not actually crash, or even output any warnings; it just won't work right. It may not even be obvious that it hasn't worked right until a long time afterwards.

    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.

  • Jdog (unregistered) in reply to mangobrain

    I've used Perl since the early '90s. My team no longer uses Perl for new development anymore because of its propensity to allow developers to create nearly unmanageable code. We are slowly migrating existing code to Python where it makes sense. When we have to rewrite old Perl code, it gets done with Python instead.

    Perl is snakeoil. I loved it when I was a fresh faced CS student; I hate it now digging though thousands of lines of ancient cruft.

    Captcha: muhahaha - the sound of perl sucking 3 hours of your life away during code maintenance...

  • Phil (unregistered) in reply to wgh

    Try coding hardware in Verilog. You see it all the time baby. .... and forget seconds. Nanoseconds is the order.

  • stnever (unregistered) in reply to mangobrain

    Just to add to the statistics, I too believe nesting ternaries is not readable (if it's not dead obvious, it shouldn't be used; even if you're skilled enough to understand it, the next developer might not be).

    if you aren't sure a pointer has been initialised before using it, or that it is pointing to the right thing, or that a given I/O loop isn't going to overflow a buffer, then you should rethink how you've designed your code...

    ...

    Pointer arithmetic is good fun, and a useful concept that doesn't slow things down. Buffer overflows needn't be an issue if you just think before coding, and ensure that you know certain things such as whether or not a given library call will return a NULL terminated string (as opposed to an unterminated collection of bytes). Memory leaks can be a problem, and ensuring you don't have them can be tedious in a function with multiple exit points, but that's just a matter of discipline (or of using C++ instead ;)

    On this topic, I prefer languages which will do the tedious work for me. I believe most programmers find it fun to solve problems by coding, but not ALWAYS the SAME problems. Good programmers already know what needs to be done -- consistent type checking (so obscure libraries can't "fool" you on the return type problem), consistent data types (byte array or null-terminated char array? just return a String!), always check buffer length (if it's "always", why shouldn't the language help by doing it by default?), test pointers before dereferencing, et cetera.

    Good programmers know and apply those concepts and grow tired. New programmers don't know and make hard-to-find mistakes (and these will take OUR time, not theirs, since we are the experts they'll call for help).

    I'd rather spend my time writing only what solves the problem, in a nice and readable way, and let the compiler add the now-agreed-upon best practices. To me, readability and ease of use outweight what little performance loss might occur (after all it won't do anything that you wouldn't do anyway). Keep it simple. DEAD simple. But no simpler.

    ...that's what I think. what about the rest of you?

    captcha: xevious. I don't know what this is, but the interesting thing is that it's not that distorted here -- an ocr script could probably identify it. Well it seems to be working so far to prevent robots, so whatever.

  • Duff (unregistered)

    I too have enough LISP experience to think that (other than actually making sure the actual nesting matches the apparent nesting) this is a perfectly fine way to do things, and to completely fail to understand how folks are saying this is not readable at a glance.

    And I'm a Python bigot -- "readable at a glance" is a value I hold near and dear. 'Yall are weenies who need to go climb up a mountain and write LISP or Scheme for a while, mmm-kay?

    Well, perfectly fine except that it makes single-stepping through the code quite a bit harder [when not using a language whose tools are built for handling this kind of thing]. And come to think of it, that's not really all that perfectly fine at all.

  • (cs) in reply to Crash
    Crash:
    Clearly an ex-LISP programmer. That's exactly how (if ..) works in Scheme. Too bad Perl can't compile this sort of thing into anything reasonable.

    Yeah, probably fresh out of college and mindful of everything that is in Abelson' & Sussman's "Structure and Interpretation of Computer Programs".

    -:)

  • mangobrain (unregistered) in reply to stnever
    I'd rather spend my time writing only what solves the problem, in a nice and readable way, and let the compiler add the now-agreed-upon best practices. To me, readability and ease of use outweight what little performance loss might occur (after all it won't do anything that you wouldn't do anyway). Keep it simple. DEAD simple. But no simpler.

    What language do you prefer then? I assume not Perl, since as I understand it that's never really "compiled" in the traditional sense, despite the name "Perl compiler".

    My degree is in Comp. Sci. not IT, performance matters for the primary app I maintain at work (although it's not strict in the real-time/embedded system sense), and I still take performance into consideration in code I write in my spare time. I'm a firm believer that whenever someone mentions "Computers used to do X in Y amount of time years ago; why are they still so slow?", the answer is too much dependence on ultra-high-level languages and layer upon layer of abstraction. Put simply: few people bother writing efficient code unless they have to, and it's slowing machines down for the rest of us :P

    How many times have you heard someone say "At my old job we used to have this script that ran in N minutes; I rewrote it and now it runs in N/100"? Why wasn't it written that way in the first place, perhaps treating the first version as a prototype? How many programs are sat on my desktop PC right now for which this type of work could be done?

    I know enough about computers and programming to know how to do my own memory management, and the less "magic" there is going on behind the scenes, the better (although assembly can be quite painful; I'd hate to go that far on a regular basis). I know what makes C a "system programming language" (and why Perl could never be one); in fact on a bad day I might argue that C++ isn't one if you use the STL (lots of memory management done for you), but I'm not writing an OS and the STL is just too darn useful ;)

    There's always an amount of picking the right tool for the job, however. Perl does have its uses. The stuff it's used for at my workplace involves a lot of string handling and isn't performance sensitive, so although it has caused me a fair amount of grief, it's probably saved a lot of time too.

  • Schol-R-LEA (unregistered) in reply to Crash
    Crash:
    Clearly an ex-LISP programmer. That's exactly how (if ..) works in Scheme. Too bad Perl can't compile this sort of thing into anything reasonable.

    Yes, except for one little detail: for selecting from several possible results, as this does, any sensible Scheme programmer would use (cond) instead.

    Or, you know, find a better abstraction which eliminates the whole selection entirely. Something that apparently didn't occur to this bozo.

    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.

    CAPTCHA:kungfu - this programmer's code-fu is weak

Leave a comment on “Turn it up to Eleven”

Log In or post as a guest

Replying to comment #:

« Return to Article