• iggy (unregistered)

    why don't we use the operator and combine with real functionality.

    Pseudo:

    Today.day.startswith('S') ? while ( do something) : for (::) {do something);

    so depending on the day we either use a while or a for loop... simple as that

  • (nodebb)

    It's funny, because in good languages you will get a warning that the result of the expression was not assigned to anything :-) And yes, I think this is also a shortcoming of C/C+ where this was also possible traditionally without a warning.

  • Darren (unregistered)

    I'm not a fan of the ternary, I find the syntax requires a bit too much effort to read. While the second example isn't great, I find it easier to read. Although, it'd just be easier and more legible to throw it in a quick 'IF' statement instead - it'll all compile down to the same underlying code anyhow, so why not make it easier for the reader to parse?

  • Jaloopa (unregistered)
    switch (arr.length)
    {
        case 0:
            val = 0;
        default:
            val = arr[0].id
    }
    
  • FTB (unregistered)

    I always put brackets around the condition, it lets you see there's something going on:

    ie.

    let val = (arr.length>0)? arr[0].id : 0;

    instead of

    let val = arr.length>0?arr[0].id:0;

  • (nodebb)

    There's nothing inherently wrong with the ternary operator. It's just the kind of thing that gets abused.

    This line is self contradictory. "It gets abused" is most definitely something wrong with it, except that it can also be said of almost any part of any programming language. It's just easier with ternaries. (And that is truly something wrong with it.)

    It's amazing how converting a ternary from an expression which evaluates to a value into a statement which changes program state makes it feel so much grosser.

    In pretty much all C-ish languages, assignment is an expression, not a statement. (Small exception for idiots who declare their class-specific operator =(...) methods as returning void.) It's just an expression with a side-effect.

    Yes, I agree, x = 5; is a statement, but it is a statement in the same way that x+5; and x; and 5; are statements.

  • (nodebb) in reply to Darren

    more legible

    Key point: more legible by humans. The compiler doesn't care.

    And this goes back to what I've said before on this site: 90% of what programmers do is communicating with other human beings. Those other human beings might be managers, salesmen, technical writers, and so on, but above all, it is the programmers' colleagues.

    Um. Including the programmers themselves, six months (or twelve years!) later...

  • (nodebb)

    Basically they're using the ternary operator as a shorthand for if/else...

  • Sauron (unregistered)

    The language itself is abusive if it allows the use of statements as expressions in the first place. More concerningly, any sane dev tasked with implementing a parser for such a language should reasonably print the language specs and shove them up the ass of whoever designed the language, because that's the kind of shit for which the syntax analysis code is bound to be a complete WTF.

    In fact, many programming languages are a WTF. Try writing a JavaScript parser for example. Seriously, grab the specs, and try writing one. You'll understand the true meaning of M̸̛̝͕̝̭̂̆̀̈́͋̊̕͝A̴̡͈̫̓̾͒̋D̴̛͓̘̜̰̱̪͑̅̑͌̂̀͠N̵̨̼̜̩̣͇̮̪̫̗̦̭͔͊̃́̽̎́̍̓ͅͅĘ̸̰̘͍͕̙̘̺͔̫̲̎̽͊͐̕͘S̷̳̟͋̾̈́̀̐͂̍̌̏̽̄̓̆̚͝S̸͔͎̬͓͇̻̮͓̩̪͊͐̋̇͒͂̚ͅ.

  • LZ79LRU (unregistered)

    Just because something gets frequently used in ways we dislike does not mean it is bad. No matter what hateful banhappy pundits like Dijxtra would want us to believe.

    In truth, any tool can be abused. And thus they all will be. That is just human nature. Indeed, the more a tool is abused the more valuable it is. For use and thus abuse of a tool is proof of its power and utility.

    An axe can be used to chop wood to warm your children or to chop children to warm your heart. But all either proves is that it's a good, sharp axe.

  • see sharp (unregistered)

    And in a very similar vein nothing other than coding practice stops a C# programmer from building side-effects into property getter.

  • Argle (unregistered)

    Playing Devil's advocate here: is this bad style, or is the programmer displaying a better-than-average understanding of expression side-effects?

  • (nodebb) in reply to Darren

    I've taken to always formatting ternaries similar to match statements:

    x = condition
        ? 1
        : 2;
    

    Hopefully that formats correctly...

    Addendum 2024-08-08 10:05: It formatted correctly, woohoo?

    Addendum 2024-08-08 10:05: *woohoo! -_-

  • Joe (unregistered) in reply to Argle

    Why not both? To me, the cleverest code I've come across is also by far the hardest for humans to read and understand.

  • ajgelado (unregistered)

    Both examples in the article are wrong. They depend on optimizations in modern compilers.

    AFAIK the C standard doesn't (or at least didn't several years ago) tell that the unused expression should not be evaluated, and clearly specifies that in those cases the order of evaluation is undefined (the second expression can be evaluated before the first one).

    In the first example, you end up accessing a[0].id even when the array is empty. But even worse, in the second one, on top of that, you may end assigning null to the variable and then overwriting it with the value read from a[0].id, even if the array is empty.

  • StackV (unregistered) in reply to ajgelado

    No, the conditional operator has always been defined to short-circuit by the C standards. It must only evaluate the appropriate branch:

    The first operand is evaluated; there is a sequence point between its evaluation and the evaluation of the second or third operand (whichever is evaluated). The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated), converted to the type described below.

  • MRAB (unregistered) in reply to Jaloopa

    "case 0" will fall through to the default because there's no "break".

  • Canthros (unregistered)

    If you're really clever, you (ab)use the ternary operator to swap out the left-hand-side of your assignment.

  • (nodebb)

    Abuse comes in many flavors of all languages. I think some of it is a misunderstanding by the programmer of the capabilities of the language and any functions that might be available in built-in and additional libraries, but a lot is just stupidity. We also need to define what "abuse" means, because "abusing statements" can be, assuming id[] is defined, changing:

    for (int x=0; x<=10; x++) { id[x]=x; }

    to:

    id[1]=1; id[2]=2; ... id[10]=10;

    There may not be readability issues here, but certainly by today's definition, this is "abuse of statements" in its own right. This is another case of:

    statement works ? use ternary in an unconventional but functional way : find another way to get famous on TDWTF

  • Loren Pechtel (unregistered)

    My first reaction: That compiles?! My second reaction: That shouldn't be allowed to compile! (I believe in warning = error. The pickier the compiler the fewer bugs there will be to hunt.)

    I agree with tom103 that they're using it as an if..else but I wouldn't even call it a shortcut. Fewer characters but far less readable. And I generally agree with konnichimade on formatting, but I'll do a single line if both cases are trivial or one case is just the default.

    A useful thread, though--I never knew the unused branch could execute.

  • Scragar (unregistered) in reply to Bananafish

    Your two statements are slightly different in meaning because the second doesn't set index 0.

    This is also why I'm a fan of having functions for this. No one gets confused or worries about the performance of:

    id = range(10)
    

    Everyone just knows this will set id to the numbers 0 to 10 in order, but it also greatly reduces the room for error by writing new code to do something so simple.

  • Duke of New York (unregistered)

    Ah, the sweet wails of mediocre programmers who believe that a programming language should always come down to their preconceptions. In the 70s–80s you would have grumbled, as so many did, about "x = x + 1".

  • Duke of New York (unregistered) in reply to Argle

    Absent further context, there is no benefit to repeating the assignment in this expression, nor to using a conditional expression rather than an if statement given that it is repeated

    To the broader point, C and derivatives have features that, when you know how to use them, make it easier to write the code that you need. As Kernighan made clear in his "Tutorial Reference on B", these features were not mistakes. Those who avoid them are handicapping themselves and have no business complaining that the language holds them back.

  • Sauron (unregistered) in reply to LZ79LRU

    How many kids have you chopped?

  • John (unregistered)

    I don't have this book anymore, but I'm sure that in "The Elements of Programming Style" one of the rules is "Write clearly, don't be too clever".

  • (nodebb) in reply to Jaloopa
    var first = arr switch
    {
        [var x, ..] => x.id,
        _ => 0,
    }
    
  • Abigail (unregistered)

    I guess I'm the only one who has written things like:

    (condition ? var1 : var2) = value;
    
  • (nodebb) in reply to ajgelado

    I don't think this is true. In the expression/statement

    arr.length > 0 ? tempVariable = arr[0].id : tempVariable = null;
    

    this is an expression whose value is thrown away. The standard says that the ternary operator will evalute the 1st expression and then evaluate EITHER the 2nd expression OR the 3rd one (caps mine). So it will evaluate

    arr.length > 0
    

    and then EITHER

    tempVariable = arr[0].id

    OR

    tempVariable = null;

    There's no UB in that. Not much sanity admittedly, but no UB

    PS I happen to like the perl postfix conditionals. It can make some things much easier to read, as it can matches more closely what you'd say in english ("turn the light on unless it's daytime" for instance)

  • Steve (unregistered) in reply to Steve_The_Cynic

    "Um. Including the programmers themselves, six months (or twelve years!) later..."

    Try 20 years later. Don't ask...

  • LZ79LRU (unregistered) in reply to Sauron

    More than I would have wished but less than I wish I had.

  • (nodebb) in reply to Scragar

    Your two statements are slightly different in meaning because the second doesn't set index 0.

    Admittedly, I forgot index 0. That's my error; I meant to include it. But I don't think that sidetracks my point.

    id = range(10)

    Perhaps the right way to do it? But again, this wouldn't allow "abuse of statements", and people do what they do because it's what they know. On another note, we had a web developer who would do things like this in javascript, where html is a text string that will become the content on the page:

    var TOTAL = parent.pay_rate * pay_period_hours; html += 'parent.pay_rate * pay_period_hours';

    So, he made a statement, then he made another statement, and in the end he said, "IDC if you can read it or follow it or even understand it, but at least you'll talk about me for awhile after I'm gone."

  • markm (unregistered)

    Ternary expressions can be formatted to be easily readable, but usually - including the examples in the original post - they are formatted in a way that reminds me of Obfuscated c contests. (Youngsters look that up, and understand why you should not write obfuscated software. It develops a skill without real-world uses, at the risk of interfering with the style you should be learning for any real software.)

    I'll accept a difficult to read ternary for the purpose of delivering one value that depends on a conditional to a larger expression, since doing that with if-else may become even muddier. But IMHO, to use the ternary in a one-line format as an "if - else", throwing away the resulting value, is obfuscated c.

  • allstarbjj (unregistered)

    "Intriguing title! 'Tern on the Flames' sounds like it has a unique and captivating story or concept. I’m excited to learn more about what this is all about and what inspired it. Thanks for sharing—looking forward to diving into it!"

  • (nodebb)

    For fans and haters of the ternary operator, may I recommend the conditional calculation operators in Tutor, a language used back in the 70s and early 80s for educational computing.

    It had a series of conditional forms for various operations. For instance:

    calcs EXPRESSION , VAR⇐ value if expression is negative, value if expression=0, value if expression=1, ...

    (that fancy assignment arrow was one character on a dedicated key, IIRC)

    For example, the following computes N-5*y (note multiplication is implied for adjacent values) and sets the "bin" value to 37 if the result is negative, to 5.2 if the result is zero, to y-cubed plus 2 (note exponentiation is indicted by superscripts in the program text) if the result is 1, no change if the result is 2 (nothing between commas means keep original value) and 2÷N otherwise (grade-school division operator was also on its own dedicated key).

    calcs N-5y , bin⇐37 , 5.2 , y³+2 , , 2÷N

    "calcc" was worse as each option was its own assignment statement possibly to different variables.

    https://codex.retro1.org/plato:tutor:conditional_calc_commands

  • (nodebb)

    While I still dislike the order if the expressions, I increasingly come to like the use of keywords for the ternary operator in Python... Makes it much easier to see.

    And actually, in this case, even the "the cond else" order if the expression improves readability I guess: Common default case first, then the expressions relating to "what if not".

  • javascripter (unregistered)

    easy

    let val = arr[0]?.id ?? 0;
    

Leave a comment on “Tern on the Flames”

Log In or post as a guest

Replying to comment #:

« Return to Article