If Not Else



  • Knowing how most of you love to be critical, I was wondering if you'd care to comment on this possible wtf;

    (C#, asp.net 2.0)

     

    if (HidePanel != false)

    {// do stuff}

    else

    {// do other stuff}

     

    I personally HATE this form of the code, and would prefer two things;

    1. Instead of naming a variable HidePanel, name it ShowPanel. It's hard to verbalise WHY i prefer to do it this way. I think ShowPanel seems like a more 'positive' thing. it just means that your default (if u have one) might be false instead of true.

    2. Why use '!=' and then have an else statement? Surely it's "best" to just use '==' if you are going to also use an else?!



  • That's a matter of opinion...

    I like to do sometimes...

    if (error != false) {

    show error! short code ...

    } else {

    OK, big code...

    }

     

    It depends on the code... If you have :

    if (DeleteFile != false)

    {// do stuff}

    else

    {// do other stuff}

     

    Now... is DeleteFile a "positive" thing ?

     

     



  • ok..it's clearly my brain struggling with it, god help me :( I read "if (error != false)" and I get all confused!! :)

     

    I wonder if it's just me, or if others have problems with the double, sometimes triple, negatives?

     

    as for (DeleteFile), i'd say that's a "positive" thing. ie;

    if (DontDeleteFile != false), then I'd prefer it written;

    if (DeleteFile == true).

     

    This ofc depends on if there's a ELSE. If there's no ELSE, i definately see the need for  IF NOTs.



  • !False is equivalent to True.

    Writing:

    [code]if (value != false)[/code]

    is nothing short of obfuscation.

    Just write [code]if (value == true)[/code], people

    -- better yet:

    [code]if (value)[/code]

    Keep it simple.



  • You can tell a real programmer because they/we are always confused by implied double negatives...



    Hands up those who've faltered when someone asks "are you not going out?"



    (stuff like that makes me feel sorry for people trying to learn english!)




  • @versatilia said:

    Hands up those who've faltered when someone asks "are you not going out?"


    waves

    @versatilia said:
    (stuff like that makes me feel sorry for people trying to learn english!)


    My favourite is the simple line "isn't it?" often added to just about any statement to illicit support.

    The word "isn't" is shorthand for "is not", making the expansion "is
    not it?" which is not grammatical under any circumstance, but part of
    the shothand allows the "not" portion to float to wherever it is
    intended (in this case, to produce "is it not?").

    English grammar is appalling but it's highly flexible and we can enounciate almost anything with it.




  • @Xarium said:



    English grammar is appalling but it's highly flexible and we can enounciate almost anything with it.




    You can syntax any grammar.



  • Inverse boolean logic is very much normal practice. In electronics it's the norm even, and many people wouldn't dream of using an == comparison instead of a !=.
    Used to be (and maybe still is) that a != comparison was also faster than an == comparison, rooted in the electronic gateways needed to implement both.



  • @jwenting said:

    Inverse boolean logic is very much normal practice. In electronics it's the norm even, and many people wouldn't dream of using an == comparison instead of a !=.
    Used to be (and maybe still is) that a != comparison was also faster than an == comparison, rooted in the electronic gateways needed to implement both.


    But isn't it so that with current advanced processors, the == and != of your upper-level-language translate into a slew of CPU instructions anyway, sort of negating the effect of taking the ciruitry into account when programming? Especially on Intel? :)



  • not necesarilly. Depends on the language you're programming in at the very least, as well as compilers and operating systems.
    Both will still (after preparing the registers) take only a single CPU call to resolve.

    Of course the difference of a few microseconds in execution time of that call won't matter at current, but I was talking of the history of using the syntax not the applicability to current performance profiling (which is indeed minimal).

    I find myself using both negative and positive boolean comparison depending on conditions. For some things it's just more logical to think one way or the other.
    A validation routine could for example assume the result is incorrect until proven otherwise, or assume it's correct until an error is found.



  • It's always stupid to compare a boolean to a literal boolean. The only
    times you should ever write "True" or "False" is when you assign a
    value to a variable or maybe, very maybe, when calling a function*.
    Stating conditions such as "error != False" or "HidePanel == True" is
    pure bollocks.


    It's technically legal to write:

        if(error != False)

    However, when I read it, have to do a mental reduction to

        if(error == True)


    And then to

        if(error)


    So why not write that in the first place? It's short and obvious.


    • Actually, when calling functions, it's better to use enumerations:

              DoSomething(dsKeepFile)
              DoSomething(dsDeleteFile)

      instead of
              DoSomething(True)
              DoSomething(False)


      because "True" conveys no information, but "dsKeepFile" does.



  • @dave said:

    It's not always stupid, or a WTF, to set up an if in this way. It really depends on the context of the code - it may make more sense to have the if this way around.


    The problem is that 'HidePanel' itself contains a negative. And then there's a !=. And then there's a False.

    It's heinously unclear.

    The only correct and clear way would be to invert that logic and use a ShowPanel var that you check for True.



  • @dhromed said:

    @dave said:
    It's not always stupid, or a WTF, to set up an if in this way. It really depends on the context of the code - it may make more sense to have the if this way around.


    The problem is that 'HidePanel' itself contains a negative. And then there's a !=. And then there's a False.

    It's heinously unclear.

    The only correct and clear way would be to invert that logic and use a ShowPanel var that you check for True.

    Or if you're stuck with a HidePanel var, convert "!= False" to "== True" ... and then just say "If (HidePanel)"



  • @rbriem said:

    Or if you're stuck with a HidePanel var, convert "!= False" to "== True" ... and then just say "If (HidePanel)"



    This is wat I'm sayin'.

    scratches throat



  • @Joost_ said:

    It's always stupid to compare a boolean to a literal boolean. The only times you should ever write "True" or "False" is when you assign a value to a variable or maybe, very maybe, when calling a function*. Stating conditions such as "error != False" or "HidePanel == True" is pure bollocks.

    Depends on the language...

    #define TRUE 1
    #define FALSE 2
    #define boolean int
    #define public
    

    public boolean isNotFalse(boolean something) {
    return something != FALSE;
    }
    [/pre]



  • and before you say that's contrived, I've seen code like that (which might class as a major WTF, it certainly was my reaction on seeing the something like the following:

     

    #define BEGIN {
    #define END }
    #define procedure void
    

    procedure someProcedure(int something)
    BEGIN
    int anotherInt = 1;
    //...
    END



  • @jwenting said:



    #define BEGIN {

    #define END }
    #define procedure void

    procedure someProcedure(int something)
    BEGIN
    int anotherInt = 1;
    //...
    END


    That just makes me cringe.


  • @jwenting said:



    Depends on the language...

    #define TRUE 1
    #define FALSE 2
    #define boolean int
    #define public

    public boolean isNotFalse(boolean something) {
    return something != FALSE;
    }
    [/pre]


    This is ridiculous. It's a contrived example, regardless of whether you've seen it in real life. In this case, in spite of his stupidity, the original author

    a- should've named the function IsTrue()

    b- should've written

        return something == TRUE;

        It's still stupid to compare the complement of a boolean to False.


    Let's also completely ignore the fact that

        if(TRUE && FALSE)
            printf("I'm with stupid -->\n")

    will actually print the message, so you'd need to do

        if(AndOperation(TRUE, FALSE))
          printf("I can make C do boolean stuff\n");

    This example only shows that this fool should be hit on the head with a thick C manual, not that it is sometimes good to compare a boolean value to a boolean constant. Optimizing boolean expressions is really first-year computer science and if a programmer can't do that, he's a either bad programmer or more likely not a programmer at all.





  • I have to agree.  For boolean logic, there are only two forms that should be used:


    if(hidePanel)
    and
    if(!hidePanel)

    However, PHP (which I'm a fan of personally) has some rare issues where you MUST use the type safe comparators, === and !==

    For example, some array searching functions return an integer representing the index at which a value was found, which may be the number 0, OR false if the value was not found.

    Unfortunately, 0 == false, but 0 !== false, therefore, when using these sorts of functions in an if, you must do things like:

    if(array_search($needle,$haystack) === false) {//$needle does not exist in $haystack
      not_found();
    } else { //$needle exists in $haystack, possibly at index 0
      found();
    }



  • @merreborn said:

    I have to agree.  For boolean logic, there are only two forms that should be used:


    if(hidePanel)
    and
    if(!hidePanel)

    However, PHP (which I'm a fan of personally) has some rare issues where you MUST use the type safe comparators, === and !==

    For example, some array searching functions return an integer representing the index at which a value was found, which may be the number 0, OR false if the value was not found.

    Unfortunately, 0 == false, but 0 !== false, therefore, when using these sorts of functions in an if, you must do things like:

    if(array_search($needle,$haystack) === false) {//$needle does not exist in $haystack
      not_found();
    } else { //$needle exists in $haystack, possibly at index 0
      found();
    }


    Wonderful functions are those that return two different data types. (I consider null and ambivalent data type that can be used as counterpart to Object)

    I personally feel that, while PHP5 has some nice new features, its core upgrading philosophy is "add more functions". EVERYTHING is a function. It's the most 1-dimensional language I've seen.



  • My question is, why does it matter?

    The reason the different syntaxes exist is for them to be used. Even if something is synonymous at first glance, everybody's coding styles are different.

    Personally, I think that what a variable is called is completely irrelevant - showPanel, hidePanel, isPanelShown, isPanelHidden, etc. All of them can be used, and I don't have any preference.

    On the other point, that is pretty valid, but I still can't see why people would struggle with negation.

    == true
    != false
    == !false
    != !true

    Are all perfectly valid forms... which are redundant. Unless you're coding on a lower level or are using a bad compiler, all of those would be compiled to the same exact bytecode.



  • @akrotkov said:

    The reason the different syntaxes exist is for them to be used.

    Well yes, the variable naming thing is a matter of style, and while it could be argued that something is either good style or bad style, in the end it's up to everybody for himself to decide what is good style.

    The usage of "!= !true" and "!= false" is another matter. Yes, it's syntactically valid, but this board is a living proof that not all compiling code is good code. Yes, with 5 milliseconds of thought you can figure out what "theValue != !false" actually does. But where do you draw the line? How many times do you have to read the following labyrinthine string of negations to understand what the Paranoid Android is saying?

    @Marvin said:

    "That young girl is one of the least benightedly unintelligent organic life forms it has been my profound lack of pleasure not to be able to avoid meeting."

    Not optimizing boolean logic is the same as writing "x+1+1+1+1+1" when you mean "x+5". Or "(x<0) == (x>0)" when you mean "x == 0". It's pure obfuscation, not a simple style matter.



  • @Joost_ said:

    It's pure obfuscation, not a simple style matter.



    hear, hear.



  • @Joost_ said:

    How many times do you have to read the following labyrinthine string of negations to understand what the Paranoid Android is saying?

    @Marvin said:

    "That young girl is one of the least benightedly unintelligent organic life forms it has been my profound lack of pleasure not to be able to avoid meeting."



    only once, but I had to go back an find the phrase "lack of" because I skipped over it the first time.


  • @dhromed said:

    @dave said:
    It's not always stupid, or a
    WTF, to set up an if in this way. It really depends on the context of
    the code - it may make more sense to have the if this way
    around.


    The problem is that 'HidePanel' itself contains a negative. And then there's a !=. And then there's a False.

    It's heinously unclear.

    The only correct and clear way would be to invert that logic and use a ShowPanel var that you check for True.




    Not if HidePanel was a panel that DOES the hiding.



    Now who's confused?



  • @headhigh said:

    @dhromed said:
    @dave said:
    It's not always stupid, or a
    WTF, to set up an if in this way. It really depends on the context of
    the code - it may make more sense to have the if this way
    around.


    The problem is that 'HidePanel' itself contains a negative. And then there's a !=. And then there's a False.

    It's heinously unclear.

    The only correct and clear way would be to invert that logic and use a ShowPanel var that you check for True.




    Not if HidePanel was a panel that DOES the hiding.



    Now who's confused?


    Good point.

    As to your question:

    The new guy who has to modify the code.



  • Maybe this is the reason, probably not, but maybe.

    I remember when I was in college, in one of my more bacis progamming classes (maybe COBOL, not sue) but it said that if you were going to use an If/Else (especially if you had more than one else) to put the item that will happen (or be true) the majority of the time at the top (the first if).  This way the code has to process less to get the answer.

    Again, that doesn't explain the triple negative, but it might have made sense to the person writing the code.

    Then again, it could have just been bad variable naming.

    yd



  • First it really is all about the context.



    Often when you see a double negative, or something similar its because
    the programmer added a feature to a always-visible panel, to deal with
    some freakish occurance where it must get hidden.  If they
    designed it out from the start, chances are they'd know they had a
    sometimes visible panel and know they should test for if the panel is
    visible, not if it is invisible.



    Sometimes though, you really just have to read the context.  The
    programmer is trying to write a program that deals with a logical
    conceptual flow, and they generally just name the variables based on
    how they fit in.  Its why you throw exceptions, instead of
    throwing !everythingIsFines.



    As for the != false, that is generally annoying, but still is just the
    programmer trying to think out loud in his code.  Besides, you
    never know when !false == true fails. It could also be FileNotFound





  • cursed forum software:



    clickied link



  • @Joost_ said:

    It's always stupid to compare a boolean to a literal boolean. The only
    times you should ever write "True" or "False" is when you assign a
    value to a variable or maybe, very maybe, when calling a function*.
    Stating conditions such as "error != False" or "HidePanel == True" is
    pure bollocks.


    It's technically legal to write:

        if(error != False)

    However, when I read it, have to do a mental reduction to

        if(error == True)


    And then to

        if(error)


    So why not write that in the first place? It's short and obvious.


    • Actually, when calling functions, it's better to use enumerations:

              DoSomething(dsKeepFile)
              DoSomething(dsDeleteFile)

      instead of
              DoSomething(True)
              DoSomething(False)


      because "True" conveys no information, but "dsKeepFile" does.


    That, or your language supports keywords-args and you can write doSomething(keepFile = True) ;)

    @dhromed said:
    I personally feel that, while PHP5 has some nice new features, its core upgrading philosophy is "add more functions". EVERYTHING is a function. It's the most 1-dimensional language I've seen.

    That's cause you've never used functional languages. PHP is merely the crappiest namespaceless languages.



  • In Python, which has keyword arguments, you write:

    <FONT face="Courier New" size=2>import re
    re.compile('.*', re.MULTILINE | re.IGNORECASE)</FONT>

    <FONT face="Courier New" size=2><FONT face="Times New Roman" size=3>Probably because the <FONT face="Courier New" size=2>"=True"</FONT> part of <FONT face="Courier New" size=2>"multiline=True"</FONT> still doesn't convey much information.</FONT></FONT>

    @Masklinn said:

    That's cause you've never used functional languages. PHP is merely the crappiest namespaceless languages.

    PHP is an imperative language, not a functional language.



  • @Joost_ said:

    In Python, which has keyword arguments, you write:

    import re
    re.compile('.*', re.MULTILINE | re.IGNORECASE)

    Probably because the "=True" part of "multiline=True" still doesn't convey much information.

    How about "because these informations are flags for the regular expressions parser (which is written in C), are used in more or less any and all RE parsers, would require useless additional Python (or C using Python objects) parsing and translation if implemented via kwdargs and would be an order of magnitude more verbose to boot"?

    Additionaly, the argument here is a meaningful name provided by the RE library, which is completely a different case than the one I quoted in which you had to create a boolean variable or enumeration or whatever you want that you'd have created yourself, while the meaningful name already exists in the first place.

    Behold the declaration of your function:

    def doSomething(keepFile):
        # do whatever you want

    See, the name "keepFile" already exists because it was generated when you wrote the function, you may ignore it, create a boolean value and not use the keyword argument, but what's the point? You'll only end up with a more verbose code with no gain at all (unless your keepFile argument is used for a dozen different function of course).

    @Joost_ said:
    @Masklinn said:
    That's cause you've never used functional languages. PHP is merely the crappiest namespaceless languages.

    PHP is an imperative language, not a functional language.

    Your point? I never said that PHP was functional (hell, I didn't even hint that it could be functional), I was answering to the "PHP is the most 1-dimensional language [because] everything is a function" part.

    My point was that... well... in functional languages, everything is a function too (unless everything is data, Lisp style) and yet they don't suck therefore "everything is a function" isn't an argument to compute the suckage level of a language.



  • "everything is a function" isn't an argument to compute the suckage level of a language.


    Oh. NOW I get it.

    It seems a habit of many people to make a statement without the actual point.

    I'm sure the functional languages you have in mind don't suck.

    My criticism was mostly directed at the organisation of the language PHP. I prefer it if an operation that applies to a certain datatype is a method of the prototype:

    Array.shift()
    vs
    array_shift(array)


  • Excusez!

    array_shift($theArray);

    :)



  • I agree. You get into double-, tripple-, quadruple negatives!
    Try reading the code out loud.   Is it clear?


    1.
    if(HidePanel != false) { do stuff; } else { do other stuff; }
    "If hide panel does not equal false, then do stuff, else do other stuff."

    2.
    if(HidePanel) { do stuff; } else { do other stuff; }
    "If hide panel, then do stuff, else do other stuff."

    3.
    if(ShowPanel) { do stuff; } else { do other stuff; }
    "If show panel, then do stuff, else do other stuff."


    To me, (2) and (3) are the same. The only difference would be whichever is the more "interesting" state, show or hide.



  • @yellowdog said:

    I remember when I was in college, in one of my more bacis progamming classes (maybe COBOL, not sue) but it said that if you were going to use an If/Else (especially if you had more than one else) to put the item that will happen (or be true) the majority of the time at the top (the first if).  This way the code has to process less to get the answer.




    This is not quite correct. First of all, both a compiler or an interpreter still has to parse the whole thing.

    This:
    <code>
    if(HidePanel) {
      // do stuff
    } else {
     // do other stuff
    }
    </code>

    compiles to something like this:

    <code>
    load HidePanel from memory
    test (jump to :else if false)   
    //do stuff
    jump to :end
    :else
    //do other stuff
    :end
    </code>

    What you are thinking of might be this situation:

    <code>
    if( conditionA && conditionB && condition C)
    {
       ...
    }
    </code>

    In this case, if conditionA is "false", then it won't test any of the others, since by definition of && the entire expression will certainly be "false".  Therefore, if conditionA and conditionB are expected to be "true" most of the time, but conditionC changes often; or if conditionC is expected to be "false" most of the time; then conditionC ought to be first, to avoid having to evaluate the conditions which are expected to be usually "true" anyway.



  • @dhromed said:

    !False is equivalent to True.

    Writing:

    [code]if (value != false)[/code]

    is nothing short of obfuscation.

    Just write [code]if (value == true)[/code], people




      YOW!  BAD BUG!



      You just fell down the gap between logical not which operates in
    a two valued boolean scheme and not-equal comparison operator, which
    operates on the full range of integers.



      False is always zero.  But ANY non-zero value is true, in
    if ... else terms.  So it's a terrible mistake to write "If (value
    == true)", because that will only match values that are precisely equal
    to whatever value true is defined to be (usually 1).



      So because False has only one value and all other values are
    true, it makes sense to compare to false: anything that's exactly the
    same is false, anything else is true.



      But if you compare to True, sure, anything exactly the same is
    true, but anything that doesn't match could be either true OR false!



    @dhromed said:

    -- better yet:

    [code]if (value)[/code]




      Yes, it's better, but only because it's /not the same thing/ as
    "if (value == True)" at all, but matches on the full set of true
    values!



       cheers,

           DaveK






  • @DaveK said:


    [i]boolean context 101 in a nutshell[/i]


    Yes.

    I know all that.



  • Wow Dave, your language doesn't do proper boolean conversions?  *phear*

    Frankly, I'm glad I don't work with most of the people who've posted on this.  I guess thinking like a turing machine takes some real training and experience; something you just don't get with a degree in Java and a couple of months writing VB code that doesn't do any real work.

    If you can't handle negative boolean equations, then you ought to re-evaluate not continuing as a programmer.



  • @Corwinoid said:

    Wow Dave, your language doesn't do proper boolean conversions?  phear

    Frankly, I'm glad I don't work with most of the people who've posted on this.  I guess thinking like a turing machine takes some real training and experience; something you just don't get with a degree in Java and a couple of months writing VB code that doesn't do any real work.

    If you can't handle negative boolean equations, then you ought to re-evaluate not continuing as a programmer.

    Sure, not being not totally unambiguous is not not unneccessary at all, after all, we don't not program only not for computers, but not also not for humans. That's why I always don't not name my variables a1, a11, a111, a1111. I can't not handle that. The compiler doesn't not care not about it. So what isn't not the problem? If you'd not not have paid any attention to the thread so far, you'd have noticed it's not not not about being or not being able to handle double negatives, but not not about the necessity and desirability of them. Now go back to obfuscating your code, tough guy.



  • Another peeve of mine is that you've got a variable there that's a
    verb.  I try very hard to have all my variables have names that
    are nouns, and reserve verbs for method names....


    if(panelIsHidden == true)
    {
    // do the hidden-panel stuff
    }
    else
    {
    // do the visible-panel stuff
    }

    I'm not a big fan of the " == true" but use it to meet in-house coding standards that date back to the sixties.



  • Personaly I'm a fan of XoK's suggestion.

    I code my comparisons to work in the affermative in variable names, and in comparisons where possible. It does help readability, however, to invert the 'if ... else ...' in cases where you have a three lines of error handling and a 20 line body if the error handling is placed in the 'if' section instead of the 'else' section. This way you don't get a random else block floating down near the bottom, by which time people skimming through the code may associate it by accident with the rest of the 'if' code, or they have forgotten what context the else was for and now have to hunt up through the code to find the associated condition.



  • I totally understand, what you are meaning. When it comes to those specifications I always name it "positive", because I want to produce something showing/working.
    Same with some validation-variables, they are all called StatementValid and not StatementFailed.

    regards,
    comrad



  • In C++ I like it this way:

    [code]
    if (bCondition)
    {
          // some incredible hyperoptimized stuff
    }
    else
    {
          // foo
    }
    [/code]
    ...because it simply reads how it works.



  • I think DaveK nailed what lots of you are failing to see.  Some
    languages don't have built in boolean types, therefore (test != FALSE)
    and (test == TRUE) are not guaranteed to be the same thing.



    (For example, if you're working on C++ code that was either written
    before the native boolean was included in the language, or is a C
    conversion, you will likely be using, as I am, #define BOOL int,
    #define FALSE 0, #define TRUE 1.  In this case if you are going to
    actually compare against boolean literals, rather than doing if(test)
    or if (!test), it's only safe to compare with FALSE).



Log in to reply