Guaging Knowledge via the Ternary Operator



  • Many if-else statements can simply be modified to use the ternary operator, but many programmers are either unfamiliar with it or unwilling to use it. I try to use it where ever possible and I find you can guage a coder's skill based on their using it. But that measurement went out the window the other day:

     x = (logic statement) ? true : false;

    Multiple times throughout their code, and the occasional:

      x = (logic statement) ? false : true;

     

     


  • Discourse touched me in a no-no place

    @kraagenskul said:

    and I find you can guage a coder's skill based on their not using it wherever and whenever possible.
    FTFY. HTH. HAND.



  • @PJH said:

    @kraagenskul said:
    and I find you can guage a coder's skill based on their not using it wherever and whenever possible.
    FTFY. HTH. HAND.
     

     

    There's nothing inherently wrong with the ternary operator. Just don't be a moron and:

    a) nest it, or

    b) use it in combination with complicated expressions that obscure the location of the ? and :

     There's nothing wrong with, e.g.

    std::cout << "Good morning " << ((gender == Male) ? "Sir" : "Ma'am") << std::endl;



  •  Gauging Literacy via Correct Spelling of "Gauging"



  • @Tyler said:

     There's nothing wrong with, e.g.

    std::cout << "Good morning " << ((gender == Male) ? "Sir" : "Ma'am") << std::endl;

    What about this?

    @derula said:

    y==0 ?(x==0 ? nil : 3((x<=>0)-1)):(y<=>0)(3-(x<=>0)*(x.abs<y.abs ? 1 : 2))



  • I don't mean using it anywhere, I use it when it will always be a simple assignment and makes it clearer.

     And yes, I cannot spell guage, necassary, or oppisite. I need to sit down and spell them out a hundred times until I get them down pat. 


  • Discourse touched me in a no-no place

    @Tyler said:

    std::cout << "Good morning " << ((gender == Male) ? "Sir" : "Ma'am") << std::endl;
    I do, however have issues with things like:

    		syslog(LOG_NOTICE, "WebRelay %s:%d Relay: %s Input: %s Reboot: %s",
    			inet_ntoa(sin->sin_addr.s_addr), ntohs(sin->sin_port),         
    			relay  == 0 ? "on" : "off",                                    
    			input  == 1 ? "on" : "off",                                    
    			reboot == 0 ? "Auto Reboot off" :                              
    			reboot == 1 ? "Pinging" :                                      
    			reboot == 2 ? "Waiting for response" :                         
    			reboot == 3 ? "Rebooting" :                                    
    			reboot == 4 ? "Waiting for reboot" :                           
    				      "Unknown"                                            
    			);


  • @kraagenskul said:

    Many if-else statements can simply be modified to use the ternary operator, but many programmers are either unfamiliar with it or unwilling to use it. I try to use it where ever possible and I find you can guage a coder's skill based on their using it. But that measurement went out the window the other day:

     x = (logic statement) ? true : false;

    Multiple times throughout their code, and the occasional:

      x = (logic statement) ? false : true;

    In case this is C and <font face="courier new,courier">true</font> and <font face="courier new,courier">false</font> are macros, it makes sense. But I assume it isn't C we're talking about.

    @PJH said:

    I do, however have issues with things like:

    		syslog(LOG_NOTICE, "WebRelay %s:%d Relay: %s Input: %s Reboot: %s",
    inet_ntoa(sin->sin_addr.s_addr), ntohs(sin->sin_port),
    relay == 0 ? "on" : "off",
    input == 1 ? "on" : "off",
    reboot == 0 ? "Auto Reboot off" :
    reboot == 1 ? "Pinging" :
    reboot == 2 ? "Waiting for response" :
    reboot == 3 ? "Rebooting" :
    reboot == 4 ? "Waiting for reboot" :
    "Unknown"
    );
    Why? Sure, you could assign some char* variables and use them instead in the syslog call, but it's not that bad.


  • @kraagenskul said:

    I don't mean using it anywhere, I use it when it will always be a simple assignment and makes it clearer.

     And yes, I cannot spell guage, necassary, or oppisite. I need to sit down and spell them out a hundred times until I get them down pat. 

     

    Whenever you have advice that sums to, "don't use it unless you're really careful," you're better off just not using it at all. If someone thinks it's ok to use it (for example, they see one you checked in), you *know* they'll abuse it the first chance they get.

    I've seen enough unreadable disasters stemming from this that I'm firmly in the "never use it" group.



  • There are cases where chaining ternaries is reasonable, but the syslog code there would be clearer and more maintainable if the strings were extracted into constant arrays: something like (quick hack, may be buggy)

    const char* on_off[2] = { "on", "off" };
    const char* status[6] = { "Auto Reboot off",
    "Pinging",
    "Waiting for response",
    "Rebooting",
    "Waiting for reboot",
    "Unknown" };
    const char* get_status(int reboot) {
    return reboot < 6 ? status[reboot] : status[5];
    }
    syslog(LOG_NOTICE, "WebRelay %s:%d Relay: %s Input: %s Reboot: %s",
    inet_ntoa(sin->sin_addr.s_addr), ntohs(sin->sin_port),
    on_off[relay], on_off[!input], get_status(reboot));


  • @blakeyrat said:

    Whenever you have advice that sums to, "don't use it unless you're really careful," you're better off just not using it at all.

    What do you recommend instead of rm? You have to be careful to not sudo rm -Rf /, therefore you're better off not using rm at all.

    There is nothing inherently wrong with the ternary comparison operator. It's quite useful for printing bitfields readably (printf("%s", (foo & 0x01)? "bit is set" : "bit is not set");) "Others might abuse it" isn't a good reason not to use something yourself, if *you* know how to use it properly.


    I actually quite like that inline switch expression shown above, it's pretty clear what it does and is less code than if (foo) printf("stuff"); else if (morefoo) printf("more stuff"); etc.



  • @scgtrp said:

    What do you recommend instead of rm? You have to be careful to not sudo rm -Rf /, therefore you're better off not using rm at all.
     

    I recommend making use of a GUI which contains a safety mechanism known as a "Recycle Bin" (or "Trash Can" if you prefer.) These revolutionary ideas have been around now for over twenty years, and I think it's high time we adopted them.

    I'm sure that lowers my 1337ness in your eyes, but I'd rather be less 1337 than accidentally delete files.

    @scgtrp said:

    "Others might abuse it" isn't a good reason not to use something yourself, if *you* know how to use it properly.

    If you're writing software for your own personal use that nobody else will ever see, then sure: go ahead and knock yourself out. But you don't need me to tell you that.

    The problem comes when you're working on a team, and the guy who maybe isn't as sharp as you are gets wind of this, that's when it turns into a disaster. Sure, *you* know how to use it properly, but what happens when *you* leave the company? What happens when *you* passes the module off to somebody else to maintain?

    Best to avoid.



  • @Tyler said:

    @PJH said:

    @kraagenskul said:
    and I find you can guage a coder's skill based on their not using it wherever and whenever possible.
    FTFY. HTH. HAND.
     

     

    There's nothing inherently wrong with the ternary operator. Just don't be a moron and:

    a) nest it

     

    Yeah... I've recently had to deal with far too much of the following:

    [code]nresetDN = (divSel==3'b000)?((div2N[9:0]==10'h000)?1'b0:1'b1):(divSel==3'b001)?((div2N[10:0]==11'h000)?1'b0:1'b1):(divSel==3'b010)?((div2N[11:0]==12'h000)?1'b0:1'b1):(divSel==3'b011)?((div2N[13:0]==14'h0000)?1'b0:1'b1):(divSel==3'b100)?((div2N[14:0]==15'h0000)?1'b0:1'b1):(divSel==3'b101 )?((div2N[15:0]==16'h0000)?1'b0:1'b1):(divSel==3'b110 )?((div2N[19:0]==20'h00000)?1'b0:1'b1):1'b0;[/code]

     Just a single case statement and/or some well-applied white space would solve so many problems. 

    I'd give the (now gone from the company) programmer applause for writing one of the most unreadable lines of code I've seen in quite a while, though.



  • @blakeyrat said:

    Sure, *you* know how to use it properly, but what happens when *you* leave the company?

    No longer my problem, it's the company's fault for hiring such retarded developers and now they can deal with the problems they created by hiring that guy who has "15 years of experience in C#". Writing sane code isn't such a hard concept to grasp. If you can't read it back 5 seconds after you wrote it and know exactly what it does, it's not sane.

    // This is sane.

    std::cout << "Good morning " << ((gender == Male) ? "Sir" : "Ma'am") << std::endl;

    // This is not sane.

    nresetDN =
    (divSel==3'b000)?((div2N[9:0]==10'h000)?1'b0:1'b1):(divSel==3'b001)?((div2N[10:0]==11'h000)?1'b0:1'b1):(divSel==3'b010)?((div2N[11:0]==12'h000)?1'b0:1'b1):(divSel==3'b011)?((div2N[13:0]==14'h0000)?1'b0:1'b1):(divSel==3'b100)?((div2N[14:0]==15'h0000)?1'b0:1'b1):(divSel==3'b101
    )?((div2N[15:0]==16'h0000)?1'b0:1'b1):(divSel==3'b110
    )?((div2N[19:0]==20'h00000)?1'b0:1'b1):1'b0;


    The stupidity of other people is not an excuse to avoid using your own intelligence.



  • Suppose you have this:

    int x = 12345;
    bool b = x;
    

    The MSVC compiler will bitch about "possible performance problem" because it needs to clamp the expression to a 0/1 boolean value. You'd think that explicitly casting to bool would quiet the warning. Nope, the compiler is a bastard. But wrapping the thing like this shuts up the stupid warning:

    int x = 12345;
    bool b = x ? true : false;
    

    Not a WTF.



  • @scgtrp said:


    The stupidity of other people is not an excuse to avoid using your own intelligence.

     

    Do you care more about having bug-free software, or proving you're smarter than your co-workers?



  • @smxlong said:

    Suppose you have this:

    int x = 12345;
    bool b = x;
    

    The MSVC compiler will bitch about "possible performance problem" because it needs to clamp the expression to a 0/1 boolean value. You'd think that explicitly casting to bool would quiet the warning. Nope, the compiler is a bastard. But wrapping the thing like this shuts up the stupid warning:

    int x = 12345;
    bool b = x ? true : false;
    

    Not a WTF.

    Wouldn't

    bool b = x != 0;

    be easier?



  • @smxlong said:

    Suppose you have this:

    int x = 12345;
    bool b = x;
    

    The MSVC compiler will bitch about "possible performance problem" because it needs to clamp the expression to a 0/1 boolean value.

    Wouldn't using a compiler that's not only smart enough to notice the issue but also smart enough to auto-correct it be a better idea?

    It's like some people think there's only one company that makes compilers...



  • @PJH said:

    @kraagenskul said:
    and I find you can guage a coder's skill based on their not using it wherever and whenever possible.
    FTFY. HTH. HAND.
     

     

    /agree

    Most of the time when I have to deal with other programer's code, where they use this style of a conditional, I have to break it out to a IF-THEN-ELSE  or SWITCH construct in order to add features/error checking/bug fixes/whatever. It is just simplier to write it "long form" first, then to redo it later, IMO. But reall this is a STYLE issue, not a SKILL issue.

     

     



  • @tgape said:

    @smxlong said:
    Suppose you have this:

    int x = 12345;
    bool b = x;
    

    The MSVC compiler will bitch about "possible performance problem" because it needs to clamp the expression to a 0/1 boolean value.

    Wouldn't using a compiler that's not only smart enough to notice the issue but also smart enough to auto-correct it be a better idea?

    It's like some people think there's only one company that makes compilers...

    There is no "issue." There is nothing wrong with the code as-is. The compiler is just trying to be helpful by warning that it's not as simple as a truncating cast -- it actually needs to check if the value is non-zero, and if so, make it equal to 1.

    Switching production compilers because of a warning like that is letting the tail wag the dog. If the product is compiled with compiler XYZ, and development policy is to squash all warnings, then you end up with things like this. I suppose you could have used a #pragma to turn off the warning, but why do that when you can get rid of it by portable coding?



  • ( thought I'd posted this, but it doesn't seem to have showed up.  apologies if a dup.)

    @North Bus said:

    Yeah... I've recently had to deal with far too much of the following:

    <font face="Lucida Console" size="2">nresetDN = (divSel==3'b000)?((div2N[9:0]==10'h000)?1'b0:1'b1):(divSel==3'b001)?((div2N[10:0]==11'h000)?1'b0:1'b1):(divSel==3'b010)?((div2N[11:0]==12'h000)?1'b0:1'b1):(divSel==3'b011)?((div2N[13:0]==14'h0000)?1'b0:1'b1):(divSel==3'b100)?((div2N[14:0]==15'h0000)?1'b0:1'b1):(divSel==3'b101 )?((div2N[15:0]==16'h0000)?1'b0:1'b1):(divSel==3'b110 )?((div2N[19:0]==20'h00000)?1'b0:1'b1):1'b0;</font>

     Just a single case statement and/or some well-applied white space would solve so many problems. 

    I'd give the (now gone from the company) programmer applause for writing one of the most unreadable lines of code I've seen in quite a while, though.

    No, that's alright.  Coding standards don't apply in VHDL/Verilog, because it's written by hardware engineers! 




  • @DaveK said:

    @North Bus said:

    Yeah... I've recently had to deal with far too much of the following:

    <font face="Lucida Console" size="2">nresetDN = (divSel==3'b000)?((div2N[9:0]==10'h000)?1'b0:1'b1):(divSel==3'b001)?((div2N[10:0]==11'h000)?1'b0:1'b1):(divSel==3'b010)?((div2N[11:0]==12'h000)?1'b0:1'b1):(divSel==3'b011)?((div2N[13:0]==14'h0000)?1'b0:1'b1):(divSel==3'b100)?((div2N[14:0]==15'h0000)?1'b0:1'b1):(divSel==3'b101 )?((div2N[15:0]==16'h0000)?1'b0:1'b1):(divSel==3'b110 )?((div2N[19:0]==20'h00000)?1'b0:1'b1):1'b0;</font>

     Just a single case statement and/or some well-applied white space would solve so many problems. 

    I'd give the (now gone from the company) programmer applause for writing one of the most unreadable lines of code I've seen in quite a while, though.

    No, that's alright.  Coding standards don't apply in VHDL/Verilog, because it's written by hardware engineers!

    Indeed... though I bridge the gap between the two.  I am a hardware engineer with enough software experience to code decently [I hope], so I've been assigned the (quite interesting) job of coding new and updating old simulations.  As a result, I muck through piles of this all the time.


  • @smxlong said:

    @tgape said:
    @smxlong said:
    Suppose you have this:
    int x = 12345;
    bool b = x;
    
    The MSVC compiler will bitch about "possible performance problem" because it needs to clamp the expression to a 0/1 boolean value.

    Wouldn't using a compiler that's not only smart enough to notice the issue but also smart enough to auto-correct it be a better idea?

    It's like some people think there's only one company that makes compilers...

    There is no "issue." There is nothing wrong with the code as-is. The compiler is just trying to be helpful by warning that it's not as simple as a truncating cast -- it actually needs to check if the value is non-zero, and if so, make it equal to 1. Switching production compilers because of a warning like that is letting the tail wag the dog. If the product is compiled with compiler XYZ, and development policy is to squash all warnings, then you end up with things like this. I suppose you could have used a #pragma to turn off the warning, but why do that when you can get rid of it by portable coding?

    I'm pretty sure that although it is acceptable to cast an integer to a boolean, it is probably not the best way to go.  Narrowing a value from billions of possibilies to one of two usually means performing some type of logic.  Hiding the logic in a type cast is bound to backfire some day.  The code seems to be asking for an answer to the question "why is b false when x is zero?".  This almost smells like the seeds of some TDWTF front page story where somebody made a list of constants for various levels of "truthiness".



  • @North Bus said:

    @DaveK said:

    @North Bus said:

    Yeah... I've recently had to deal with far too much of the following:

    <font face="Lucida Console" size="2">nresetDN = (divSel==3'b000)?((div2N[9:0]==10'h000)?1'b0:1'b1):(divSel==3'b001)?((div2N[10:0]==11'h000)?1'b0:1'b1):(divSel==3'b010)?((div2N[11:0]==12'h000)?1'b0:1'b1):(divSel==3'b011)?((div2N[13:0]==14'h0000)?1'b0:1'b1):(divSel==3'b100)?((div2N[14:0]==15'h0000)?1'b0:1'b1):(divSel==3'b101 )?((div2N[15:0]==16'h0000)?1'b0:1'b1):(divSel==3'b110 )?((div2N[19:0]==20'h00000)?1'b0:1'b1):1'b0;</font>

     Just a single case statement and/or some well-applied white space would solve so many problems. 

    I'd give the (now gone from the company) programmer applause for writing one of the most unreadable lines of code I've seen in quite a while, though.

    No, that's alright.  Coding standards don't apply in VHDL/Verilog, because it's written by hardware engineers!

    Indeed... though I bridge the gap between the two.  I am a hardware engineer with enough software experience to code decently
    You're in a good position.  Your colleagues need to learn the importance of good coding practices - revision control, coding standards, structured coding - and you're in just the right place to show them by example.  This stuff is all new to hardware guys, so they're mostly a few years behind where software has gotten to (a lot of vhdl reads like 70s C code), but a lot of them know the problem is there and are looking to learn better ways of dealing with the increasing amounts of code they're having to write.




  • @smxlong said:

    @tgape said:
    @smxlong said:
    Suppose you have this:

    int x = 12345;
    bool b = x;
    

    The MSVC compiler will bitch about "possible performance problem" because it needs to clamp the expression to a 0/1 boolean value.

    Wouldn't using a compiler that's not only smart enough to notice the issue but also smart enough to auto-correct it be a better idea?

    It's like some people think there's only one company that makes compilers...

    There is no "issue." There is nothing wrong with the code as-is. The compiler is just trying to be helpful by warning that it's not as simple as a truncating cast -- it actually needs to check if the value is non-zero, and if so, make it equal to 1.

    If it is claiming that it's a "possible performance problem", I see one of two alternatives:

    1. Microsoft has decided to embrace the embedded market far more than I ever thought possible.
    2. The MSVC is possibly more broken than I can imagine.

    Given the track record of the company, I'd guess the latter.  Note: there's a machine code instruction which branches on an int being zero.  I'm pretty sure there's another that can do a one cycle compare with zero.  The performance impact of inserting a single trivial machine code instruction is generally negligible.  Furthermore, if you have an integer, and you want to use it in a logic operation, I'm pretty certain that you need to use at least one machine code instruction to do it - so you are talking about the performance difference of two trivial instructions.  It doesn't seem like a lot of room for improvement to me.

    Having thought about it a bit more, I suspect it's simply a matter that the compiler doesn't recognize that 'int' is one of its base types, and thus trivially converts to a boolean.  Instead, it's considering that it might be a custom object, which could have a very complicated conversion to boolean.

    However, even in that situation, whether you use the variable in a boolean expression directly or you convert it to a boolean first still would probably make no difference in performance, so long as it was just used once.  Using the complex object in the boolean expression is what you want to avoid, not the conversion to a boolean.  If your complex object would be used in boolean context multiple times in the program between changing values, you'd certainly want to assign it to a boolean to save the cost of doing that conversion repeatedly.

    So no matter how I consider it, it seems that the MSVC warning is either warning of an underlying compiler issue, or it's indicating that it was developed by people whose ideas about how programming should work would lead to underlying compiler issues.  Either way, I want to avoid using it.

    Disclaimer: I've already been avoiding the use of the MSVC compiler, as it wasn't made for the systems for which I do development.  I am therefore entirely relying on the above post for knowledge of this compiler's behavior.



  • @Iago said:

    There are cases where chaining ternaries is reasonable, but the syslog code there would be clearer and more maintainable if the strings were extracted into constant arrays: something like (quick hack, may be buggy)

    const char* on_off[2] = { "on", "off" };
    const char* status[6] = { "Auto Reboot off",
    "Pinging",
    "Waiting for response",
    "Rebooting",
    "Waiting for reboot",
    "Unknown" };
    const char* get_status(int reboot) {
    return reboot < 6 ? status[reboot] : status[5];
    }
    syslog(LOG_NOTICE, "WebRelay %s:%d Relay: %s Input: %s Reboot: %s",
    inet_ntoa(sin->sin_addr.s_addr), ntohs(sin->sin_port),
    on_off[relay], on_off[!input], get_status(reboot));
    This is close to what I was talking about, but not quite. I was thinking more about:@Zecc's mind said:
    const char* statuses[6] = { "Auto Reboot off",
    "Pinging",
    "Waiting for response",
    "Rebooting",
    "Waiting for reboot",
    "Unknown" };
     
    const char    *log_addr   = inet_ntoa(sin->sin_addr.s_addr);
    unsigned short log_port   = ntohs(sin->sin_port);
    const char    *log_relay  = (relay == 0) ? "on" : "off";
    const char    *log_input  = (input == 1) ? "on" : "off"; 
    const char    *log_status = (reboot < 6) ? statuses[reboot] : statuses[5];
    syslog(LOG_NOTICE, "WebRelay %s:%d Relay: %s Input: %s Reboot: %s",
    log_addr, log_port, log_relay, log_input, log_status);

    But I guess this is a bit verbose, for a simple syslog call.

     

    @blakeyrat said:

    @scgtrp said:
    The stupidity of other people is not an excuse to avoid using your own intelligence.

    Do you care more about having bug-free software, or proving you're smarter than your co-workers?
    I care more about not lowering the bar below the waistline.

    You can't possibly expect a programmer who can't grok a simple ternary operator to write bug-free software.



  • @derula said:

    y==0 ?(x==0 ? nil : 3*((x<=>0)-1)):(y<=>0)*(3-(x<=>0)*(x.abs<y.abs ? 1 : 2))

    What the heck is a "<=>" operator? "x is less than, equal to or greater than 0"?



  • @smxlong said:

    Suppose you have this:

    int x = 12345;
    bool b = x;
    

    The MSVC compiler will bitch about "possible performance problem" because it needs to clamp the expression to a 0/1 boolean value. You'd think that explicitly casting to bool would quiet the warning. Nope, the compiler is a bastard. But wrapping the thing like this shuts up the stupid warning:

    int x = 12345;
    bool b = x ? true : false;
    

    Not a WTF.

    That should really trigger the warning too IMO. It's still having to cast an int to a bool for the ternary operator.



  • Also, apparently the following works:

    (condition ? var1 : var2) = var3;



  • @Anonymouse said:

    @derula said:

    y==0 ?(x==0 ? nil : 3*((x<=>0)-1)):(y<=>0)*(3-(x<=>0)*(x.abs<y.abs ? 1 : 2))

    What the heck is a "<=>" operator? "x is less than, equal to or greater than 0"?

    I couldn't get much info about it, but I suspect this is Ruby and that operator basically means "values are comparable".
    So if <font face="courier new,courier">x</font> is <font face="courier new,courier">NaN</font>, <font face="courier new,courier">x <=> 0</font> is false (or rather, <font face="courier new,courier">nil</font>).

    In other words, yes it is exactly what you said.


  • It returns -1 if the left value is smaller, 1 if the right value is smaller and zero if they are equal.



  • @Zecc said:

    I couldn't get much info about it, but I suspect this is Ruby and that operator basically means "values are comparable".
    So if <font face="courier new,courier">x</font> is <font face="courier new,courier">NaN</font>, <font face="courier new,courier">x <=> 0</font> is false (or rather, <font face="courier new,courier">nil</font>).
    It's the spaceship operator, and it does what holli says:

    @holli said:

    It returns -1 if the left value is smaller, 1 if the right value is smaller and zero if they are equal.



  • @Zecc said:

    You can't possibly expect a programmer who can't grok a simple ternary operator to write bug-free software.
     

    Well, first of all, you can't expect a programmer who uses the word "grok" in casual conversation to do anything except sit in the basement and watch Star Trek.

    Secondly, writing bug-free software has pretty much nothing to do with your knowledge of the language. Especially since this operator is completely extraneous-- there's literally nothing it can do that if(){}else{} can't. So right off the bat, there's a strike against it. Plus, it's relatively obscure, and I can guarantee there's entire teams of programmers writing bug-free software right now that have never heard of it.

    So anyway, we're talking about an operator that's entirely extraneous, that is prone to abuse, and that not every programmer is taught. That right there is enough for me to bin it.

    In fact, from my experience, the opposite is true: people who are real experts at a language LOVE to use its obscure and confusing features, and they love to pile up abstraction on top of abstraction, so they can show off their big bulging brain. In that case, I'd much rather have the less knowledgeable programmer working on my project, because even if he has more bugs, they'll be easier to fix. Plus, I can hire less experienced programmers to work on the project in the future instead of having to place "intimate knowledge of really obscure language feature X" in my job placements.

    The assumption that language knowledge has *anything* to do with the bugginess of produced software... I need some evidence there. I'm not going to take that one on faith, my experience says it's wrong, my gut-check says it sounds wrong. I'm sure products like Lotus Notes were written by some very smart people.

    But as an exercise, let's say you're right: maybe any programmer smart enough to really get the ternary operator won't write buggy software. Fine, but two points:

    1) Any programmer smart enough to understand the ternary operator also knows how to use a fucking if() statement.

    2) The customer of your code is the next person who touches the code. You have no guarantee that that person will understand the ternary operator to the same degree you do, and if this person thinks they're "ok" to use (after all, there's already some in there!) he might be a hundred times more prone to write an unreadable mess than you are.

    The key to using C/C++ effectively, since they're so huge and complicated, is to know what terrible language features to bin.



  •  Wow, that was rambling. Sorry haven't had my coffee yet.


  • Discourse touched me in a no-no place

    @blakeyrat said:

    In fact, from my experience, the opposite is true: people who think they are real experts at a language LOVE to use its obscure and confusing features, and they love to pile up abstraction on top of abstraction, so they can show off their big bulging brain.
    FTFY. Real experts should have realised long ago that obfuscation isn't conducive to debugging your own code, let alone others', 6 months after it's been written.



  • @blakeyrat said:

    I've seen enough unreadable disasters stemming from this that I'm firmly in the "never use it" group.

    If you read this site regularly, you've probably seen unreadable disasters stemming from pretty much every feature of every language (or rather, from from bad coders using them.) Why not put all of programming into the "never use it" category?


  • @scgtrp said:

    The stupidity of other people is not an excuse to avoid using your own intelligence.
     

     

    I'm with you on this one.  A reasonably-used ternary operator is just as easy to read as an if/else.  I'm not going to deny myself the use of a handy tool based on the chance that some idiot will see, misinterpret and abuse said tool.  I never learned about the ternary operator in school; the first time I saw it, I did the obvious thing (to me at least) and found an experienced dev to explain.

    I ran into something similar here at my current job.  Management tried to tell us that we're forbidden to use the #if DEBUG preprocessor directive under any circumstances because one of our asshat TFS admins likes to compile code in debug mode and deploy it to production.

     



  • @blakeyrat said:

    @Zecc said:

    You can't possibly expect a programmer who can't grok a simple ternary operator to write bug-free software.
     

    Well, first of all, you can't expect a programmer who uses the word "grok" in casual conversation to do anything except sit in the basement and watch Star Trek.

    That's harsh! I thought the word was relatively known in this line of busines, and I only used it because I thought "get" (with quotes included) wouldn't be strong enough.

    @blakeyrat said:

    Secondly, writing bug-free software has pretty much nothing to do with your knowledge of the language. Especially since this operator is completely extraneous-- there's literally nothing it can do that if(){}else{} can't. So right off the bat, there's a strike against it. Plus, it's relatively obscure, and I can guarantee there's entire teams of programmers writing bug-free software right now that have never heard of it.

    So anyway, we're talking about an operator that's entirely extraneous, that is prone to abuse, and that not every programmer is taught. That right there is enough for me to bin it.

    Fine. You're right about all this.

    But I don't agree with the "obscure" and "prone to abuse" parts in what it relates to the ternary operator. The if-else is as much prone to abuse, I think.

    @blakeyrat said:

    In fact, from my experience, the opposite is true: people who are real experts at a language LOVE to use its obscure and confusing features, and they love to pile up abstraction on top of abstraction, so they can show off their big bulging brain. In that case, I'd much rather have the less knowledgeable programmer working on my project, because even if he has more bugs, they'll be easier to fix. Plus, I can hire less experienced programmers to work on the project in the future instead of having to place "intimate knowledge of really obscure language feature X" in my job placements.
    Again, your reasoning is sound. But again, I don't really think the ?: operator is that obscure.

    @blakeyrat said:

    The assumption that language knowledge has *anything* to do with the bugginess of produced software... I need some evidence there. I'm not going to take that one on faith, my experience says it's wrong, my gut-check says it sounds wrong. I'm sure products like Lotus Notes were written by some very smart people.

    But as an exercise, let's say you're right: maybe any programmer smart enough to really get the ternary operator won't write buggy software. Fine, but two points:

    1) Any programmer smart enough to understand the ternary operator also knows how to use a fucking if() statement.

    2) The customer of your code is the next person who touches the code. You have no guarantee that that person will understand the ternary operator to the same degree you do, and if this person thinks they're "ok" to use (after all, there's already some in there!) he might be a hundred times more prone to write an unreadable mess than you are.

    The key to using C/C++ effectively, since they're so huge and complicated, is to know what terrible language features to bin.

    I didn't say a programmer intelligent enough to get the ternary operator won't write buggy software. You' ve put words in my mouth. That's totally unhygienic and disgusting.

    What I said was: a programmer intelligent enough to write bug-free software will get the ternary operator (it's so simple!); a programmer who isn't intelligent enough to get the ternary operator won't be intelligent enough to write bug-free software.

    @blakeyrat said:

    Wow, that was rambling. Sorry haven't had my coffee yet.
    Oh, well that makes everything okay again(*). Wanna go watch Star Trek in my basement?

    (*) I'm not being ironic. I understand the concept of "being uncaffeinated".

     

    But do you really dislike the ?: operator that much? What's your take on boolean shortcut evaluation?



  •  Sorry about the triple post.  Yay for my first hands-on experience with a CS WTF.



  • @Smitty said:

     Sorry about the triple post.  Yay for my first hands-on experience with a CS WTF.

    Just to add to the fun, this post doesn't show up in your post history (yet?).



  • @blakeyrat said:

    uncaffeinated rambling
    Mental note: when posting a long, well structured, proofread post, always back it up somewhere else, just in case the server decides to blow up.

    But basically:

     

    - Your reasoning is sound and I agree with parts of it, including about the smart-asses who write obscure code to show of. But I disagree when you say that the ?-operator is obscure and more abuse-prone than if-else.

     

    - I never said «  "gets ?:"   =>  "writes bug-free software"  ».

      I said, or at least meant, «  "writes bug-free software"   =>  "intelligent enough"   =>  "gets ?:"  »

      or equivalently  «  not "gets ?:"   =>  not "intelligent enough"   =>  not "writes bug-free software"  »

     

    - I understand the concept of "writing under influence of lack of coffee" and therefore am not offended by it.



  • Oh great, so it did post, but just gave out an error instead.



  • @Zecc said:

    Mental note: when posting a long, well structured, proofread post, always back it up somewhere else, just in case the server decides to blow up.

     

    Yah, I always type in a JamesPad window instead of into the browser, the problem is that that copy wasn't any more legible and I had to catch a bus so I didn't have time to really got through and edit it. I think what happened is I added a paragraph in the middle without revising the following paragraph... but anyway, the gist is there.

    @Zecc said:

    But I disagree when you say that the ?-operator is obscure

    I wasn't taught it in school. And I've only seen it in production use in terrible spaghetti code, which doesn't help its reputation as far as I'm concerned.

    @Zecc said:

    and more abuse-prone than if-else.

    Well, if nothing else, your code editor's auto-format knows how to cope with if-else.

    Either way, we'll just have to agree to disagree. But I've never seen a buggy program that was written with crystal clarity and simplicity, and I've never seen a solid program that wasn't. KISS.



  • @Zecc said:

    That's harsh! I thought the word was relatively known in this line of busines, and I only used it because I thought "get" (with quotes included) wouldn't be strong enough.
     

    It is known, but that's not the point. The point is you use that word instead of a word everybody knows as a way of sounding smarter than everybody else. I'm not a fan of that. Much like the ternary operator, you're using a word that's entirely redundant, yet not as well-known.

    Also, that book sucked shit. I'll never understand why that's considered Heinlein's best work.

    @Zecc said:

    What I said was: a programmer intelligent
    enough to write bug-free software will get the ternary operator (it's so simple!); a programmer who isn't intelligent enough to get the ternary operator won't be intelligent enough to write bug-free software.

    I still say there's absolutely no link between "intelligence" (no matter how you measure that) and "bugginess." I'd need evidence to back this up.

    I hope I'm not putting words in your mouth, if that's not what you mean. But we might have to agree to disagree on this point.

    @Zecc said:

    But do you really dislike the ?: operator that much? What's your take on boolean shortcut evaluation?

    I'm ok with that, only assuming that the items that are short-circuited don't have any side-effects. That is, I'm ok with that, assuming that if you wrote it as a series of if() statements, the program wouldn't change. If that makes sense.



  • @Thief^ said:

    @smxlong said:

    Suppose you have this:

    int x = 12345;
    bool b = x;
    

    The MSVC compiler will bitch about "possible performance problem" because it needs to clamp the expression to a 0/1 boolean value. You'd think that explicitly casting to bool would quiet the warning. Nope, the compiler is a bastard. But wrapping the thing like this shuts up the stupid warning:

    int x = 12345;
    bool b = x ? true : false;
    

    Not a WTF.

    That should really trigger the warning too IMO. It's still having to cast an int to a bool for the ternary operator.

    No, because the value is simply being evaluated in a boolean context, not stored into a bool. Only when the true/false gets jammed into an actual variable of bool type does the compiler need to normalize all non-zero values to 1. And of course, the reason for that is so that bool-bool comparisons become (in)equalities instead of more complicated checks. The presumption is that conversions to bool are much rarer than comparisons between bool.

    I'm not saying it's not a stupid warning, I'm only saying that I've done this exact same thing myself to quiet the warning.



  •  

    @blakeyrat said:

    In fact, from my experience, the opposite is true: people who are real experts at a language LOVE to use its obscure and confusing features,

    People who are real experts love to write code that meets requirements and is easy to maintain.  For example, a C++ expert may spend ten minutes writing ten lines of code using the STL, while a mediocre C++ programmer would spend four hours writing and debugging 100 lines of nested loops. The experts produce a 20,000 line application which can be easily maintained by a couple of experts.  The mediocre programmers produce a 200,000 line program which can be barely kept alive by 10 mediocre programmers.  Each expert will want to be paid twice as much as the mediocre guys, but it's still 60% cheaper to hire the experts.

    It's like the difference between calculus and algebra.  No one complains because integral signs are not immediately understandable to the average eighth grader.  But strangely, they complain when the meaning of a line of code is not immediately obvious to the weakest programmer on the team.  


  • @blakeyrat said:

    Plus, I can hire less experienced programmers to work on the project in the future instead of having to place "intimate knowledge of really obscure language feature X" in my job placements.

    Sorry, but the ternary operator is not a "really obscure language feature" for anyone who's spent more than 5 minutes writing C/C++/C# code and isn't a friggin' idiot.

    But as an exercise, let's say you're right: maybe any programmer smart enough to really get the ternary operator won't write buggy software.

    He didn't say that any programmer smart enough to "really get" the ternary operator won't write buggy software.  He said that any programmer dumb enough to be unable to understand said operator would have no chance of writing bug-free software.  You'd think that a self-proclaimed senior programmer would have better logic skills.  Let me spell it out for you:  "!a => !b" != "a => b".  Did you get all that, or was I using too many obscure math symbols?




  • Who took a dump in your cornflakes this morning? Relax buddy.

    @Aaron said:

    Sorry, but the ternary operator is not a "really obscure language feature" for anyone who's spent more than 5 minutes writing C/C++/C# code and isn't a friggin' idiot.

    I don't know what software industry you work for, but the one I'm in has a ton of friggin' idiots in it. If you have two equivalent options, and one is easier for friggin' idiots, you should use that one. Otherwise, the next friggin' idiot who gets a hold of your code (and it will happen sooner or later) is going to shit all over it trying to use the more advanced constructs you're comfortable with, but they are not.

    Programming is only about "writing code" if you only care about writing code. If you care about creating good, stable products, usable products, writing code is the least of it. What amazes me most is how many programmers that simply do not get that.

    Did you get all that?



  •  BTW, the ternary operator is also in Javascript of all places.



  • @blakeyrat said:

     BTW, the ternary operator is also in Javascript of all places.
    This makes me laugh for reasons I don't entirely understand.


Log in to reply