Is IsNothing() really a wtf in theory?



  • PRIVATE FUNCTION IsNothing(Obj)
      IF Obj Is Nothing THEN
        IsNothing = TRUE
      ELSE
        IsNothing = FALSE
      END IF
    END FUNCTION

    I would love to hear some theories on why this code is such a wtf.  Let's ignore the exact implementation of it as isn't this just a way of making code more readable.  I guess a better example would be writing your own IsNumeric(sting) in C# as it would be more readable, imho, than writing your numeric check from scratchfor every IF statement.
    I'd really like to hear why some people think this is bad practice?
    Also I'd like to point out that in theory IsNothing() could be improved for something more efficient, as in C# it's been proven (sorry I dont ahve a link) that there are more efficient ways to compare equality than simply doing "if (a == b)", by refactoring "Is Nothing" into a function (preferably in a higher level language such as Java or .Net) one could use overloads and create highly optimized functions depending on the data sent.  Please note I'm not really suggestion you write a function to reproduce every action within your coding language, but I feel in many cases it is good code.
     



  • @travisowens said:

    I would love to hear some theories on why this code is such a wtf.

    I don't know.... because you spend time reinventing the wheel instead of writing useful code? Or because you're cluttering your application with perfectly useless functions?

    Tell me, why exactly do you think

         isNothing(x)


    reads better than

        x is Nothing

    @travisowens said:

    I guess a better example would be writing your own IsNumeric(sting) in C# as it would be more readable, imho, than writing your numeric check from scratchfor every IF statement.

    Eh? C#  actually lacks such a function? WTF!!!

    @travisowens said:

    Also I'd like to point out that in theory IsNothing() could be improved for something more efficient, as in C# it's been proven (sorry I dont ahve a link) that there are more efficient ways to compare equality than simply doing "if (a == b)", by refactoring "Is Nothing" into a function (preferably in a higher level language such as Java or .Net) one could use overloads and create highly optimized functions depending on the data sent.



    That's the crappiest thing I've heard recently. If it's true, then we should definitely move back to C++ and forget this whole Java/C# shit, because it's starting to sound like doing assembly-like work in a high-level language. Geez, I think the guys who made these languages missed a lot of classes on data abstraction.

    P.S. I'm sorry if this sounds like trolling, but I really don't have much theory to support my opinion. It's a matter of common sense.



  • I don't think anyone's suggesting that .. err.. functions aren't a good
    thing, and in that regard you're right - encapsulating repeated code in
    a function is a Good Thing. But more for situations where you're going
    to repeatedly check, for example, whether a given string is of an
    appropriate length and doesn't contain any 'illegal' characters, or
    whether a particular user id is valid or so on...



    But IsNothing(Obj) ? Why not isGreaterThan( int i, int j ) or
    printALineToSystemOut(String s) ? There's no point in wrapping up code
    in a function which is a 1-liner in the language itself - I mean, what
    have you achieved? And also, you allow for the opportunity of some
    slack-jawed drooling numnut to fsck the whole thing up and create an
    implementation of isNull() that returns true in all sorts of crazy
    situations (as seen in a WTF not too long ago)....



    As for there being a more efficient way of ascertaining equality than
    "( a == b )" I can't imagine what you mean - it seems a pretty
    efficient
    way to me. And I'm not sure I'd feel comfortable 'optimizing' an
    equality check... there's a guy where I work who just constantly bangs
    on about optimization and it drives me nuts. Next christmas party I'll
    get him drunk and tattoo
    "Premature optimization is the
    root of all evil" across the back of his hands...




  • @murphyman said:

    wrapping up code
    in a function which is a 1-liner in the language itself - what
    have you achieved?




    That about sums it up.



    If a function contains a single IF and returns an explicit TRUE or
    FALSE, one should notice that something has been non-optimised.



    I have been guilty of writing an IsTrue() function.

    The function is now dead.



  • Well I think writing a global/static IsNothing()/isNull() function is a
    WTF, no matter if it is done in one line or as in the example with a
    few more. The appropiate language constructs 'x Is Nothing/x == null'
    do exactly the same and are just as readable.



    However, writing a method similar to this IsNothing function could be
    sensible, even though the most abstract implementation just contains a
    single statement. An example from my current project:



    I wrote a class that can have different states, but also knows a state
    where no valid state is available, I called this the "null state". In
    order to check for this I wrote a method like this:



    boolean isInNullState() {

        return state == null;

    }



    Almost the same as the IsNothing function we discuss here. Later on in
    development I realized, that the state field should never be null, but
    instead it point to a special state-instance that handle calls for the
    null state (by throwing an Exception). Now if I had not previously
    defined the isInNullState() method and instead used 'state == null'
    directly, I would have had to change multiple classes, and probably
    missed several references. Instead all I had to do was this:



    boolean isInNullState() {

        return state == NULL_STATE;

    }



    So concluding I think writing such functions that just wrap a single
    language construct is a WTF if it is done only for readability, but it
    is not a WTF, if it is done for OO-related design decisions, e.g.
    encapsulation.



    cu



  • @felix said:

    @travisowens said:
    Also I'd like to point out that in theory
    IsNothing() could be improved for something more efficient, as in C#
    it's been proven (sorry I dont ahve a link) that there are more
    efficient ways to compare equality than simply doing "if (a == b)", by
    refactoring "Is Nothing" into a function (preferably in a higher level
    language such as Java or .Net) one could use overloads and create
    highly optimized functions depending on the data sent.




    That's the crappiest thing I've heard recently. If it's true, then we
    should definitely move back to C++ and forget this whole Java/C# shit,
    because it's starting to sound like doing assembly-like work in a
    high-level language. Geez, I think the guys who made these languages
    missed a lot of classes on data abstraction.






    I think you missed something (I don't know C#, so I'll talk about Java only, but AFAIK it is similar on C#):



    Identity and equality are not the same. In Java 'a == b' is an identity
    check, that will only be true if a and b reference the very same
    (=identical) instance of a class. Equality checking is done with
    'a.equals(b)' and there is a basic implementation provided by the root
    class Object that will just do an 'a == b'. However more often than not
    a developer will overwrite this equals method, such that actually
    fields are compared to each other, hence equality between a and b
    usually means, that a and b are instances of the same class and their
    fields have the equal values.



    Now if a given abstract class does overwrite equals(), but then a
    Factory (or Flyweight) pattern is used provide identical instances for
    specific field values, then this concrete subclass could again
    overwrite the equals method and again introduce equality is identity.
    In such a case the concrete subclass' implementation of equals would in
    fact be faster than the one from the abstract class. And the inlining
    done by the JIT compiler would in fact replace it with a single CPU
    instruction wherever possible.



    However, I think those cases are rare, usually 'equals()' will be much
    slower than '==' but keep in mind, that it does check for equality, not
    for identity, so this is to be expected.



    cu




  • Trust a Java-boy to add another layer of needless complexity err.. I mean abstraction, yes definitely abstraction.



    No - I'm only joking, and good points and good posts. You are indeed
    right, there are many case when you would want a 'language 1-liner'
    encapsulated in an object - when requirements change, or you need to
    refactor, or just business simply fail to take their ritalin and shred
    their spec to pieces - you'll be glad you did. Your code is an obvious
    example where you benefitted from encapsulating the check for null. But
    this IsNothing function just clearly isn't anything like that. It's a
    WTF.



    As for your post regarding equality and identity, I don't think anyone
    was falling for that old trap (at least, I really hope they weren't) -
    I think what felix was getting cranky about was the sentence:



    > by
    refactoring "Is Nothing" into a function (preferably in a higher

    > level
    language such as Java or .Net) one could use overloads and

    > create
    highly optimized functions depending on the data sent




    I mean, WTF does that sentence even mean? (sorry travis).



  • @murphyman said:

    I think what felix was getting cranky about was the sentence:



    > by
    refactoring "Is Nothing" into a function (preferably in a higher

    > level
    language such as Java or .Net) one could use overloads and

    > create
    highly optimized functions depending on the data sent




    I mean, WTF does that sentence even mean? (sorry travis).




    Maybe it was so clear for me only, because I am not a native English speaker? ;)



    However, this sentence is total nonsense with regard to a unoptimizable
    null check. Which is why I did choose to talk about an "optimized"
    equals method.



    cu



  • @eagle said:

    Identity and equality are not the same. In Java 'a == b' is an identity
    check, that will only be true if a and b reference the very same
    (=identical) instance of a class. Equality checking is done with
    'a.equals(b)' and there is a basic implementation provided by the root
    class Object that will just do an 'a == b'. However more often than not
    a developer will overwrite this equals method, such that actually
    fields are compared to each other, hence equality between a and b
    usually means, that a and b are instances of the same class and their
    fields have the equal values.




    I know that, and I think it's the biggest WTF in the Java language.
    Other languages have much saner solutions, like different operators
    (=== vs. ==) or, in C++, address comparison vs. value comparison. But
    then again, sane languages either allow for operator overloading or
    make it unnecessary (don't argue here, this topic needs its own thread).



    And ya, I didn't understand that funny sentence.




  • Actually, IsNothing(obj) is a member of the Microsoft.VisualBasic.Information namespace in VB.NET...

    Drak



  • @felix said:

    Other languages have much saner solutions, like different operators
    (=== vs. ==) ...




    Please, don't talk about sane solutions and refer to PHP's ==/=== operators in the same sentence.



    PHP is (in my opinion! No discussion please!) a huge WTF itself, and those operators are one of the biggest reasons for this.



    cu



  • @travisowens said:

    Also I'd like to point out that in theory
    IsNothing() could be improved for something more efficient, as in C#
    it's been proven (sorry I dont ahve a link) that there are more
    efficient ways to compare equality than simply doing "if (a == b)", by
    refactoring "Is Nothing" into a function (preferably in a higher level
    language such as Java or .Net) one could use overloads and create
    highly optimized functions depending on the data sent.


    Premature optimization is the root of all evil.  This should only
    be done in specific cases where it is clearly understood that equality
    functions are a bottleneck (highly
    unlikely).  Code such as this should be the exception, not the
    rule, so an IsNothing function which does not contain these dubious
    optimizations has no reason to exist.



    Don't break standards to give yourself consistency when optimizing. A
    system should use "If Obj Is Nothing" in all cases except the optimized
    case, in which case it should be "If IsOptimizedNothing(Obj)" is
    appropriate.



  • Doh, that last line should read:



    A
    system should use "If Obj Is Nothing" in all cases except the optimized
    case, in which case "If IsOptimizedNothing(Obj)" is
    appropriate.



  • @Chris F said:

    Doh, that last line should read:



    A
    system should use "If Obj Is Nothing" in all cases except the optimized
    case, in which case "If IsOptimizedNothing(Obj)" is
    appropriate.





    So, what exactly is the difference between a (normal) nothing and an
    optimized nothing? Is there anything you can remove from nothing in
    order to optimize it? Or is there something about an optimized nothing,
    that I don't understand?



    SCNR (vanishing into complete nothingness, a.k.a. nirvana)



  • @eagle said:

    So, what exactly is the difference between a (normal) nothing and an
    optimized nothing? Is there anything you can remove from nothing in
    order to optimize it? Or is there something about an optimized nothing,
    that I don't understand?


    Like I said, this particular optimization is "highly unlikely" and "dubious".  I am fighting a more general battle.



  • @travisowens said:

    PRIVATE FUNCTION IsNothing(Obj)
    IF Obj Is Nothing THEN
    IsNothing = TRUE
    ELSE
    IsNothing = FALSE
    END IF
    END FUNCTION




    This is... horrible idea.



    What do you gain from writing this method? Do you hate the syntax of
    "if (myObject is nothing) ..." ? I think it's a WTF because you're
    wrapping functionality that exists as a readible one-liner. As
    mentioned, someone could come in and really mess with what IsNothing()
    does, which makes it decievingly ambigious with the "is nothing"
    built-in comparison. If the compiler wasn't smart, you'd also be
    de-optimizing your code. You call IsNothing(), it checks the variable
    and returns the output, then your code must check the output. If you
    left it alone with the normal "is nothing", it would simply check the
    variable and be done with it there.



    With methods like this, you might as well have the other stuff we've seen on the boards like IsTrue() and IsFalse().






  • @travisowens said:

    Also I'd like to point out that in theory IsNothing() could be improved for something more efficient, as in C# it's been proven (sorry I dont ahve a link) that there are more efficient ways to compare equality than simply doing "if (a == b)", by refactoring "Is Nothing" into a function (preferably in a higher level language such as Java or .Net) one could use overloads and create highly optimized functions depending on the data sent.

    Before I explain what I poorly typed, first let me say somp people posting here couldn't look past the actual code and read the concept behind it.  I shouldn't have used the IsNothing() function from yesterday's post because I do realize it is a WTF. 

    C# has no IsNumeric() or IsNumber(), that's something VBers (and VB.Net) coders are use to, but imho a function such as that is 100% more readable than me throwing 50 RegExs into my code.  I should have rewritten the function above as a IsNumeric().

    Now back to what I meant to say, hopefully I can be more clear (please note I would have rewritten the post but as we all know, TheDailyWTF doesn't let us edit posts... WTF!)

    IsNumeric() is a great example, imho, why you want to abstract a simple check out of your IF code and into a function returning a boolean.  I like to play with benchmarks from time to time and compare (or read articles) comparing the basics of a language.  Let's say you wrote your app and when you wanted to know if a string could be a number, you Try/Catch a casting/convert of a string to an int.  Well obviously a Try/Catch is extremely slow compared to other methods such as simply running a RegEx on the string.  If you had done this Try/Catch in your code 50 times, there's a fair amount of monkey work ahead to improve all that code.  But if you had written a simple IsNumeric() function you only have to optimize in 1 place.

    I retract the mention of overloading, I'm too lazy right now to explain what I really meant and it wasn't that important.



  • @travisowens said:

    IsNumeric() is a great example, imho, why you
    want to abstract a simple check out of your IF code and into a function
    returning a boolean.


    Abstracting a non-built-in logical operation behind a function is
    certainly not a WTF, and I would even recommend you do so.  That
    is just basic functional abstraction talking.  Even if they're
    one-liners, it is very useful to give them a symbolic name that clearly
    defines what the code is doing.  My data layer utility class, for
    example, has several such functions for escaping strings, retrieving
    alternate values if if the passed value is DBNull.Value (like SQL
    Server's IsNull function), etc.  Similarly, other classes can have
    quick one-line queries encoded into properties to keep code readable.



  • @Chris F said:

    Even if they're
    one-liners, it is very useful to give them a symbolic name that clearly
    defines what the code is doing.




    Man, at least one of us is missing the point. What's the f***ing
    difference between "x is Nothing" and "isNothing(x)", except that
    you've added an extra function call? Do you expect to change/extend the
    semantics of this particular test in the future?




  • @felix said:

    Man, at least one of us is missing the point.




    Yes, and it isn't Chris F.



    cu



  • @felix said:

    What's the f***ing difference between "x is Nothing" and "isNothing(x)", except that you've added an extra function call? Do you expect to change/extend the semantics of this particular test in the future?

    This is why I previously stated I shouldn't have used the IsNothing() code to ask my question. You are correct, I can't fathom any reason why anybody would ever need to change the inner workings of IsNothing().

    <SATIRE><satire>unless you were going to write some amazing assembly code that could perferm your Nothing/Null check faster than the language's native checking.</satire></SATIRE>



  • @felix said:



    I know that, and I think it's the biggest WTF in the Java language.
    Other languages have much saner solutions, like different operators
    (=== vs. ==) or, in C++, address comparison vs. value comparison.




    What's "saner" about that? Where is there even a difference except
    a syntactical/cosmetical one? Actually it's exactly the choice between
    address comparison and value comparison, except that it offers a
    standard way to do the latter, which as far as I can tell does not
    exist in C++.



    @felix said:


     But
    then again, sane languages either allow for operator overloading or
    make it unnecessary




    Operator overloading is never neccessary. It is purely syntactical
    sugar for calling specific methods. It can make code in areas where the
    operators are well-defined and widely known (basically the tiny subset
    of numerics where ASCII symbols are sufficent as operators)  more
    readable, and make code in all other areas much, much less readable,
    especially due to implicit operator precedence.




  • @felix said:

    Other languages have much saner solutions, like different operators
    (=== vs. ==) or, in C++, address comparison vs. value comparison. But
    then again, sane languages either allow for operator overloading or
    make it unnecessary (don't argue here, this topic needs its own thread).




    Oh, it is so much more fun to argue it here.



    Java compromises a lot of theory at the alter of pragmatism. 
    These compromises were made on the basis of real world experience with
    C++ and Smalltalk.



    Things like "operator overloading", "multiple inheritence", "everything
    is an object" look great in a Ph.D. thesis but in the real world
    introduce more problems than they solve. And, dammit, '==' vs. '===' is
    a recipe for disaster.  Why would anyone do that when we have
    enough trouble with '=' vs '=='?  Getting rid of real pointers has
    also been a great.  Garbage collection has really helped avoid
    lots of errors that plague applications written in other
    languages.  Hot spot compiling and generational garbage collection
    has brought the speed up to where there is no longer even a speed
    benefit to C++.



    The compromises were pretty good, and java has been successful because
    of it.  It's even been successful enough that MS copied it. 
    I wonder what the next language will be, but I'm pretty sure it will
    make code easier to read, not harder.



    Regrds,

    Mike



  • Value equality is perfectly standardized in C++. Just use ==. If the
    object doesn't support a sane concept of equality, then the code won't
    compile.

    Reference equality is more complex, because you can overload & to
    do weird things, forcing you into very weird syntax. But if you have a
    wrapper, the test looks like (boost::addressof(obj1) ==
    boost::addressof(obj2)).



    In Java, it's pretty much the same, except that reference equality is easier to do than value equality, which is bad.

    Value equality is the equals method. You can compare anything and
    everything with it, and if the implementation is stupid, you'll get an
    exception. Objects that don't have a sane concept of equality fall back
    to reference equality. Whether this is an improvement over the C++ way
    is debateable.

    Reference equality is ==. Except if the object in question is a
    primitive, not a reference, in which case that's value equality.
    Reference equality between primitives is not possible.



    In other words, Java has a little inconsistency where C++ has none.



    Now, it's been some time since I did C#, so the next block might not be exactly correct.

    C# uses the Equals method for value equality. Unlike with Java, this
    even works with primitives, simply because C# doesn't really have
    primitives. It has value objects.

    Reference equality is == in general, but this is not guaranteed,
    because you can overload == to perform a different action, hopefully
    value equivalence. Since this overrides the default == behaviour, you
    need to explicitely cast to Object to guarantee using reference
    equality, so the universal reference equality test is (((Object)obj1)
    == ((Object)obj2)). However, due to value objects being boxed in such a
    case, you still aren't guaranteed that you're really comparing the real
    addresses, and I think there is a possibility of this comparison
    failing in debug mode and succeeding in release, or similar unexpected
    effects.





    PHP, unlike the three above, is a dynamically and weakly typed
    language, and got its OO features as an afterthough, indeed leading to
    various WTFs. But I like it despite that.

    First, you have to differ between PHP 4 and 5.

    In PHP 4, there is no concept of reference equality. PHP4 only has the
    concept of weak equality or equivalence, the == operator, and strong
    equality or just equality, the === operator. Weak equality accepts
    different values as equal, as long as they would be equivalent after a
    typecast. Strong equality requires the values to be of the same type.
    Comparing objects in PHP4 just uses element-wise comparison using the
    operator supplied (so if you do obj1 == obj2, it does element-wise
    comparison with ==; if you say obj1 === obj2, it uses ===.)

    In PHP 5, this has changed. Now objects are handled by reference, not
    by value. This means that while == is still element-wise comparison,
    the === operator now checks reference equality. For all other types,
    the behaviour is unchanged.

    This actually makes sense in a weird way, but you have to accept a
    rather twisted view of the programming model to see the sense in it.



  • No, not if it's written like this.

    Ruby allows for this specific kind of optimization:

    class Object
        def isNothing()
            return false
        end
    end
    

    class NilClass
    def isNothing()
    return true
    end
    end

    p nil.isNothing() # true
    p 42.isNothing() # false
    p [][0].isNothing() # true

    Not that anyone would need it in this case, given that Ruby already includes a method "nil?()" on every object, like if item.nil?() ... end. Of course, == nil does the same.



  • > Value equality is perfectly standardized in C++. Just use ==. If the
    > object doesn't support a sane concept of equality, then the code won't
    > compile.
    > Reference equality is more complex, because you can overload & to
    > do weird things, forcing you into very weird syntax. 
    

    Code doing this belongs here. Nowhere else.

      SomeClass *c = new SomeClass(...);
      // ...
      c == &*c
    

    is one of these invariantes you just don't break.

    Without looking at Boost, I think I can guess it does reinterpret_cast<void *>(arg). Am I right?


Log in to reply