What is this "Boolean logic" of which you speak?



  • Recently, an e-mail went out to all the programmers in my department quoting this:

    if ((x != null && y != null && !x.equalsTo(y)) || (x == null && y != null) || (y == null && x != null)) {

    And asking if it could be reduced to this:

    if (x == null || y == null || !x.equalsTo(y)) {

    I wasn't surprised to learn where the first statement came from. The guy responsible left behind a huge steaming pile of WTF when he left for a better-paying job a year ago. But the one asking is a senior programmer, one of the best in the department.

    If you'll excuse me, I'm going to go cry in the corner now.



  • As far as I can tell it works in all cases except when y and x are both NULL, which is easily fixed by adding a "!(NULL == x && NULL == y) &&". Cases tested (by hand):

    • NULL == x && NULL == y
    • NULL == x && 1 == y
    • 1 == x && NULL == y
    • 1 == x && 1 == y
    • 1 == x && 2 == y


  • Oh well at least they didn't use operator overloading!



  • It looks suspiciously like a strange way of writing [code]x != y[/code] , now the questions left are, is [code]!x.equalsTo(y)[/code] different from [code]x != y[/code] ? And in what cases will null make the sky fall down?



  •  Well, as x and y are objects and the .eqalsTo() method is called on these objects, it's important to check that they are not null, unless you can be sure that they aren't.

     Also, x!=y merely checks that x and y are different instances, however they may still have the same value, so x!=y might not be enough.

     

     I'm still not sure where the WTF is exactly, but maybe that's because I'm almost falling asleep. Is it because the expression is overly complicated and can be expressed in simpler terms? Or is it the senior developer's question about a simplification which doesn't handle all cases correctly?



  • Arguably TRWTF is an environment where you can't write this more simply.


    I agree that the senior programmer not getting it is sad. I'm not sure the original line counts as a WTF because it really is hard to rewrite. It just needs a comment like "//null-safe !equals" at the top.



    Shorter but almost as confusing:

    if(x == null ? y != null : !x.equalsTo(y)) {



  • @Juifeng said:

    Also, x!=y merely checks that x and y are different instances, however they may still have the same value, so x!=y might not be enough.

    Don't worry! Those genius Java designers have thought of everything!
    HashMap h = new HashMap();
    h.put(x, 1);
    if (!h.containsKey(y)) {


  • @Faxmachinen said:

    Don't worry! Those genius Java designers have thought of everything!
    HashMap h = new HashMap();
    h.put(x, 1);
    if (!h.containsKey(y)) {

    This uses y.equals(x), not y.equals[b]To/b.



  • Which begs the question: In what way is equalsTo() different?

    Never mind.



  • @Nu Kua said:

    Recently, an e-mail went out to all the programmers in my department quoting this:

    if ((x != null && y != null && !x.equalsTo(y)) || (x == null && y != null) || (y == null && x != null)) {

    And asking if it could be reduced to this:

    if (x == null || y == null || !x.equalsTo(y)) {

    I wasn't surprised to learn where the first statement came from. The guy responsible left behind a huge steaming pile of WTF when he left for a better-paying job a year ago. But the one asking is a senior programmer, one of the best in the department.

    If you'll excuse me, I'm going to go cry in the corner now.

     

    No it can't be reduced to what was suggested, as [ x = null, y = null ] fails the original, but will pass the suggested reduced form.

    The only cases that are supposed to fail is when x and y are both null, or when x is equal to y.

    To replicate this in a simpler form, how about:

    if (!(x != null && y != null && x.equalsTo(y)) && x != y) {

    This is assuming that in whatever language this is (null == null) is true.

    Something more in line with the suggested reduction I think would be:

     if (((x == null || y == null) && x != y) || !x.equalsTo(y)) {



  •  I would be replying "why reduce it?".

    What's wrong with the first line of code? Does it not do the job it is supposed to do? 



  • @havokk said:

    What's wrong with the first line of code? Does it not do the job it is supposed to do?

    It's job is twofold; one is to instruct the compiler, and the other is to instruct the maintainer.



  • @Faxmachinen said:

    [the job of code] is twofold; one is to instruct the compiler, and the other is to instruct the maintainer.
     

    Ooh, I like that. That's a good sentiment.

     It's a nice complement to my own "the only thing that can happen to code after it's written is maintenance".


Log in to reply