• (cs)

    Absolutely not a WTF.
    get() not throwing an exception is a bug, but that's probably a non-issue, since only WTF-code would ever try to call it when size() returns 0.

  • Reverend (unregistered) in reply to ennuija

    Write only memory does serve a function.... It leaks.

  • (cs) in reply to mike_d
    Anonymous:

    ah..just like the good old write-only memory:  http://ganssle.com/misc/wom1.jpg


    'FINO' Asynchronous Memory

    :D
  • (cs) in reply to dhromed
    <font>public</font> EmptyList()
    {

    }


    Astounding!

    What we have here is a more profound absence of information than null or undefined.

    This changes the way I see the kosmos.
  • Athas (unregistered) in reply to trollable
    trollable:
    Empty list in Lisp:  ( ) Sorry, I can not make it unreadable.

    I'll give it a try:

    `(,@())

  • (cs) in reply to dmitriy
    dmitriy:
    This is not too bad, except for two problems. One, pointed out already, si that you can add elements to this list. The other is the get() method. If the caller tries to call any methods on the "Object" returned, their application will crash because of dereferencing a null.


    No, that's perfectly OK. Even a "regular" list can contain null entries which will be returned when calling get() with the appropriate index. Returning null values is quite normal in Java, e.g. the API hashtable class does it to indicate that there is not entry for that key.

    Most people have no problem with that, some think it's horrible and will go to great lengths to eliminate all possibility of a null value ever being passed anywhere in their code - quite futile, if you ask me.
  • (cs) in reply to Xepol
    Xepol:
    For all it does, it might as well be a null pointer.  I am somewhat suprised to find that java has a system object that clones this one.  Why exactly would you want to create a list object that basically acts like a huge black hole???  For just keeping a pointer active, an actual list with no elements would seem to make about as much sense, except that you could actually add data to it instead of getting an abstraction exception popup.


    If you have a lot of pointers you need to fill with empty lists, using the API class (which has no fields) will save a LOT of memory compared with using empty "actual lists" (which contain an array of default size 10 to store the contents). You can use the same object everywhere, but then you may have to create your own infrastructure to access it from different places (i.e. a Singleton), while the API class already has that for your. And if you add something to it accidentally, the added element will pop up everywhere you used the singleton, which is a lot worse than getting an exception.
  • Asd (unregistered) in reply to brazzy

    This is not much of a WTF IMO. Buggy get but possibly for a reason. Not using Collections.EMPTY_LIST but again there could be a reason

    > Then I searched for where it was used and got even more mystified.... they kept creating new instances of EmptyList all over the place, storing it and then converting them back to null before exiting the method it was used in!

    Converting them back to null?? No offense but I get the impression of a newcomer to Java getting confused by something that is rare outside Java, C# etc. but not that strange when you are used to it. Obviously creating new EmptyLists is not great but presumably they are passing these lists to some methods.
    A similar case is found when generating xml: when you have no attributes for an element you use EmptyAttributes.

    And an empty list that silently drops added objects can be very useful.

  • nick-less (unregistered) in reply to richleick

    Good one.  But at least they coded the brackets so you can actually read the code.  I mean honestly, isn't this:

    public function myFunction()
    {
       if(something)
       {
          doSomething()
       }
       else
       {
          doSomethingElse()
       }
    }

    A LOT better than

    public function myFunction() {

       if(something)   {

          doSomething()

       }  else   {

          doSomethingElse()

       }

    }



    No it isn't, and btw emacs is better....

  • Cowboy Bob (unregistered) in reply to nick-less
    Anonymous:

    Good one.  But at least they coded the brackets so you can actually read the code.  I mean honestly, isn't this:

    public function myFunction()
    {
       if(something)
       {
          doSomething()
       }
       else
       {
          doSomethingElse()
       }
    }

    A LOT better than

    public function myFunction() {

       if(something)   {

          doSomething()

       }  else   {

          doSomethingElse()

       }

    }



    No it isn't, and btw emacs is better....


    Yes it is. I'm a Java developer and it's the only part of the Sun coding standards I refuse to follow.

    And it's vi for me ;-)

  • (cs) in reply to nick-less
    Anonymous:

    Good one.  But at least they coded the brackets so you can actually read the code.  I mean honestly, isn't this:

    public function myFunction()
    {
       if(something)
       {
          doSomething()
       }
       else
       {
          doSomethingElse()
       }
    }

    A LOT better than

    public function myFunction() {

       if(something)   {

          doSomething()

       }  else   {

          doSomethingElse()

       }

    }



    No it isn't, and btw emacs is better....
    Emacs blows, TECO is the ultimate editor. Emacs is nothing more than a bunch of TECO macros anyway

  • (cs) in reply to ennuija

    ennuija:
    Write-only memory is as useful as a function that returns void...

    Actually, a function that returns void is quite useful -- it's called a procedure.

  • Someone (unregistered) in reply to somebody

    '() is the quoted constant (), which is equivalent to NIL (the symbol), which is roughly equivalent to null in Java.   Since ()/NIL are self-evaluating, the quote is unnecessary.

    The (Common) Lisp that would correspond to that Python snippet would be:

    (let (x)
      (push 1 x)
      (print x))

  • (cs) in reply to Kreiger

    Anonymous:
    The only WTF here is that the get(int) method does not honor the List contract by not throwing IndexOutOfBoundsException.
    This may not be a problem if it is only used in code which checks the size first. Otherwise it's just a bug.

    Collections.EMPTY_LIST should have been used instead.

    An empty list can be quite useful as is evidenced by the existence of Collections.EMPTY_LIST.

    This is a non-WTF if there ever was one.

    You recognized the "WTF" of not returning an exception but rather happily returning NULL if I ask for the list element #1934495 of an "empty" list, but then you say it's not a WTF?

  • (cs) in reply to moobar

    Anonymous:
    I don't see any WTF with this class.  Having an EmptyList class that can be instantiated, as opposed to using the static EMPTY_LIST, has several useful purposes.  The person who posted this WTF clearly doesn't understand this.

    Perhaps the only really incorrect part of this code is that you can add items to the list but not retrieve or remove them (ie, memory leak until the object is destroyed).  But clearly only an idiot would actually try doing that (in which case the WTF would be the person using the class, not the class itself).

    Creating an "EmptyList" class is like creating a "FourElementList" class.  It's incorporating a possible *attribute*  of an instance of a flexible, generic class into a new classes name, which makes absolutely no sense whatsoever. 

    Do you think you it's OK to have an "EmployeeNamedJeff" class or a "IntegerValueOf12" class as well?

  • (cs) in reply to masklinn
    masklinn:
    Emacs blows, TECO is the ultimate editor. Emacs is nothing more than a bunch of TECO macros anyway


    ed(1) is the standard text editor. Diverge from the standard at your peril.
  • (cs) in reply to mjonhanson
    masklinn:
    trollable:
    mjonhanson:
    If you want to start a flame war, you need to do it properly by giving an example of why Perl or VB or Lisp or Smalltalk or Brainf**k, etc. is better than Java, preferrably with completely unreadable code on a single line.

    Empty list in Lisp:    ( ) 
    Sorry, I can not make it unreadable. Lots of advantage: constant, small, shareable, not exceptions, ...

    Empty list in python: list() (alternate syntax: []).

    Ditto for the thoughness of making that unreadable.


    Haha!  Brainf**k can do an empty list with no characters at all!  And you can return NULL with a single character code:

    .

    Why mess with OO when Turing complete is all you need? :)
  • (cs) in reply to Athas
    Anonymous:
    trollable:
    Empty list in Lisp:  ( ) Sorry, I can not make it unreadable.

    I'll give it a try:

    `(,@())



    Yes, now we're getting the hang of it!

  • (cs) in reply to Xargon
    Xargon:
    masklinn:
    trollable:
    mjonhanson:
    If you want to start a flame war, you need to do it properly by giving an example of why Perl or VB or Lisp or Smalltalk or Brainf**k, etc. is better than Java, preferrably with completely unreadable code on a single line.

    Empty list in Lisp:    ( ) 
    Sorry, I can not make it unreadable. Lots of advantage: constant, small, shareable, not exceptions, ...

    Empty list in python: list() (alternate syntax: []).

    Ditto for the thoughness of making that unreadable.


    Haha!  Brainf**k can do an empty list with no characters at all!  And you can return NULL with a single character code:

    .

    Why mess with OO when Turing complete is all you need? :)


    That's a very good point, te he.
  • (cs)

    Maybe it's just an implementation of this:
    http://www.google.pl/search?q=null+object+design+pattern

  • (cs) in reply to crazyfrog

    you guys all missed the point... you have to remember that "truth is how you define it" [:)]

  • Kooch (unregistered) in reply to kipthegreat

    Different ways of creating an unmodifiable empty List without coding up an entire class:

    Collections.EMPTY_LIST;
    Collections.emptyList();
    Collections.unmodifiableList(new Vector());

    And similarly for for Maps and Sets. Clearly there is no reason to ever create a class called EmptyList in java. This example is defenetly a WTF.

    One of my pet-peeves is Java programmers that have no idea whats in the collections framework. I had a coworker once brag about how he implemented an awsome sorting algorithm for Sets. I asked him why he didn't just use a SortedSet, and he just stared at me then walked away.

  • (cs) in reply to Kooch
    Anonymous:
    Different ways of creating an unmodifiable empty List without coding up an entire class:

    Collections.EMPTY_LIST;
    Collections.emptyList();
    Collections.unmodifiableList(new Vector());

    And similarly for for Maps and Sets. Clearly there is no reason to ever create a class called EmptyList in java. This example is defenetly a WTF.

    One of my pet-peeves is Java programmers that have no idea whats in the collections framework. I had a coworker once brag about how he implemented an awsome sorting algorithm for Sets. I asked him why he didn't just use a SortedSet, and he just stared at me then walked away.


    Wheels get re-invented all the time, sometimes even for a reason, and in such a simple case like that it's arguably faster to implement it than to check the docs if this wheel has already been invented.
  • (cs) in reply to Jeff S
    Jeff S:

    Creating an "EmptyList" class is like creating a "FourElementList" class.  It's incorporating a possible *attribute*  of an instance of a flexible, generic class into a new classes name, which makes absolutely no sense whatsoever. 

    Do you think you it's OK to have an "EmployeeNamedJeff" class or a "IntegerValueOf12" class as well?



    Subclasses with immutable attributes make sense, especially if they are faster and consume less memory than the flexible, generic class.
  • (cs) in reply to JohnO
    JohnO:

    ennuija:
    Write-only memory is as useful as a function that returns void...

    Actually, a function that returns void is quite useful -- it's called a procedure.



    Exactly. Write-only memory is also useful.
    Imagine that the memory is not read by you, but by the hardware or operating system.
  • lewy14 (unregistered) in reply to Rick

    I'm really quite convinced that the extended for loop does not use the size() method anywhere - as evidenced by my having written classes and wrapers which work properly with the for loop and do not implement the size() method at all.

    The only requirement for the for loop is that the class implements am accessable non-static method with this signature:

    public Iterable<E> iterator();

    Y'all wanna wtf? I got yer wtf riight here: a wrapper which allows iterating through the set bits in a BitSet

        public static Iterable<Integer> onesIn(final BitSet bs) {
            return new Iterable<Integer>() {
                public Iterator<Integer> iterator() {
                    final int first = bs.nextSetBit(0);
                    return new Iterator<Integer>() {
                        int i = first;
                        public boolean hasNext() {
                            return i >= 0;
                        }
                        public Integer next() {
                            int ret = i;
                            i = bs.nextSetBit(i + 1);
                            return ret;
                        }
                        public void remove() {
                            throw new UnsupportedOperationException();
                        }
                    };
                }
            };
        }

    Looks totally effed until you see how it's used:

    import static com.foo.support.Util.onesIn;
    ...

    BitSet bs = new BitSet();
    ...
    for (int i : onesIn(bs)) {
        System.out.println("bit " + i + "is set");
    }

    I call it the "irritator" idiom, as a play on iterator, and the fact that many will likely find it irritating. A bit wasteful (iterators, autoboxing) but pretty in usage, which is sometimes the right tradeoff.

    Hmm. Looks like I probably got yer flamewar right here, too.

  • lewy14 (unregistered) in reply to Rick
    Rick:
    Anonymous:
    Rick:
    Trivia question:

    What does Java 1.5 do with the new extended for loop if the size() method doesn't return the correct size of the collection?

    The extended for loop uses a java.util.Iterator, not size info.



    That is what I had thought. Apparently the hidden Iterator uses the size() method.


    My (OT) post immediately above was in response to this (OT) post.

  • Kooch (unregistered) in reply to ammoQ
    ammoQ:

    Wheels get re-invented all the time, sometimes even for a reason, and in such a simple case like that it's arguably faster to implement it than to check the docs if this wheel has already been invented.


    Wow.

    I'm glad that sometimes you have a reason for reinventing the wheel. But being to lazy to check docs (especially ones as well written as the standard java API docs) is hardly a valid reason.
  • (cs) in reply to Kooch
    Anonymous:
    ammoQ:

    Wheels get re-invented all the time, sometimes even for a reason, and in such a simple case like that it's arguably faster to implement it than to check the docs if this wheel has already been invented.


    Wow.

    I'm glad that sometimes you have a reason for reinventing the wheel. But being to lazy to check docs (especially ones as well written as the standard java API docs) is hardly a valid reason.


    Actually there is no EmptyList class in the Java API docs, so one must be rather lucky to find EMPTY_LIST. But in first place one has to expect EMPTY_LIST to exist.
    And yes, there are sometimes reasons for knowingly reinventing the wheel. Some existings wheels just don't exactly fit, are too weakly specified, too universal or too complicated to use.
  • (cs) in reply to ammoQ

    ammoQ:

    Actually there is no EmptyList class in the Java API docs, so one must be rather lucky to find EMPTY_LIST. But in first place one has to expect EMPTY_LIST to exist.
    And yes, there are sometimes reasons for knowingly reinventing the wheel. Some existings wheels just don't exactly fit, are too weakly specified, too universal or too complicated to use.

    You're right, Collections.EMPTY_LIST is easy enough to miss entirely. And its true that reinventing the wheel is sometimes appropriate. Sorry about the harshness of my previous post.

  • moobar (unregistered) in reply to Jeff S
    Jeff S:

    Anonymous:
    I don't see any WTF with this class.  Having an EmptyList class that can be instantiated, as opposed to using the static EMPTY_LIST, has several useful purposes.  The person who posted this WTF clearly doesn't understand this.

    Perhaps the only really incorrect part of this code is that you can add items to the list but not retrieve or remove them (ie, memory leak until the object is destroyed).  But clearly only an idiot would actually try doing that (in which case the WTF would be the person using the class, not the class itself).

    Creating an "EmptyList" class is like creating a "FourElementList" class.  It's incorporating a possible *attribute*  of an instance of a flexible, generic class into a new classes name, which makes absolutely no sense whatsoever. 

    Do you think you it's OK to have an "EmployeeNamedJeff" class or a "IntegerValueOf12" class as well?



    Yes, this is a perfectly acceptable use of a class. 

    The examples you give aren't comparable.  They are naive examples showing classes which do exactly the same as an existing generic class.  EmptyList is different.  It guarantee emptiness, which a generic list can't do.  This can be useful in situations where you have generic methods operating on lists and you need to make sure some lists that get passed in remain empty (due to them having met some previous pre-condition).


  • (cs) in reply to lewy14
    Anonymous:
    I'm really quite convinced that the extended for loop does not use the size() method anywhere - as evidenced by my having written classes and wrapers which work properly with the for loop and do not implement the size() method at all.

    The only requirement for the for loop is that the class implements am accessable non-static method with this signature:

    public Iterable<e> iterator();</e>


    True, but how will that iterator keep track of where in the list it is? In some cases, it's possible to do that without using size(), e.g. in a linked list. But the default implementation of iterator() in AbstractList, which the WTF code uses, does indeed call size() in its hasNext() implementation.

  • (cs) in reply to ammoQ
    ammoQ:
    Anonymous:
    Different ways of creating an unmodifiable empty List without coding up an entire class:

    Collections.EMPTY_LIST;
    Collections.emptyList();
    Collections.unmodifiableList(new Vector());

    And similarly for for Maps and Sets. Clearly there is no reason to ever create a class called EmptyList in java. This example is defenetly a WTF.

    One of my pet-peeves is Java programmers that have no idea whats in the collections framework. I had a coworker once brag about how he implemented an awsome sorting algorithm for Sets. I asked him why he didn't just use a SortedSet, and he just stared at me then walked away.


    Wheels get re-invented all the time, sometimes even for a reason, and in such a simple case like that it's arguably faster to implement it than to check the docs if this wheel has already been invented.


    I agree there's a slim chance that the developer wrote this class rather than used one from the collections library for a reason, but in that case (since it's clearly non-obvious to everyone here), it should have been accompanied by a big fat comment, ideally in the class javadoc. I can't help but agree with the original poster - reimplementing existing part of the core Java API just causes confusion, since it's rarely obvious whether it was deliberate or accidental, and bloats the project source unnecessarily.

    As for the speed argument, it's also faster to name all variables a, b, c, etc.; but that doesn't mean one should do it.  IMHO, far too much code is written these days with speed rather than correctness foremost in the developers mind, and if one isn't very careful, a small amount of speed now is gained at the expense of a whole lot of speed later (when the code is being maintained).

    Just my 2p ;)

  • (cs) in reply to Rick
    Rick:
    Anonymous:
    Rick:
    Trivia question:

    What does Java 1.5 do with the new extended for loop if the size() method doesn't return the correct size of the collection?

    The extended for loop uses a java.util.Iterator, not size info.



    That is what I had thought. Apparently the hidden Iterator uses the size() method.

    Depends on the collection.

    Note also that the API doc says that Collection.size() doesn't necessarily tell you the number of elements it contains.

    OT, the captcha for anonymous submission is a broken link.

  • (cs) in reply to ennuija

    I will not refer to Java, since I'm not a Java programmer...

    A function that returns void, same to say that it is a function that does not return values...

    If you refer that in a language that has "Pointers" to access memory. A function that returns void can mean a null pointer which can be usefull, for instances, to define an undefined pointer or object.

    Now imagine your empty void function, it does have an memory address, right?... I can see it as usefull for a callback, code injection...

    ennuija:
    Write-only memory is as useful as a function that returns void...

  • (cs) in reply to ennuija
    ennuija:
    Write-only memory is as useful as a function that returns void...


    <grin> so, like a display function that pumps boilerplate to stdout then? or a sleep function?
  • (cs) in reply to taryn
    taryn:
    ennuija:
    Write-only memory is as useful as a function that returns void...


    <grin> so, like a display function that pumps boilerplate to stdout then? or a sleep function?


    Strictly speaking, there is no such thing as a function that returns void.  <grin>  Users of many languages use the term function to describe what really should be called procedures.  A true function always returns a value solely dependent upon the value(s) of the parameters and does not depend upon or modify the state of the system in any way.
    </grin>
  • (cs) in reply to RevMike
    A true function always returns a value solely dependent upon the value(s) of the parameters and does not depend upon or modify the state of the system in any way.

    True!
    <pun intended>

    In fact, GCC C has special attributes for functions of this type.

    A function declared with __attribute__ ((pure)) must return a result that only depends on parameters passed and non-volatile global variables (and is ensured not to change the value of any globals).
    A function declared with __attribute__ ((const)) is what is described by RevMike as a "true function" -- it cannot even read global variables.

    Functions like these are far less useful in procedural languages like C.

    I should also mention that Pascal (and probably other languages with a Pascal-like syntax) made the distinction between procedures and functions, although the distinction was based purely on whether it returned a value.

Leave a comment on “My List Is Emptier Than Your List”

Log In or post as a guest

Replying to comment #:

« Return to Article