If I want to create an infinite list of integers in Java like so:ArrayList<Integer> list = new ArrayList<Integer>();for(int i = 0;;i++){    list.add(i);}I run out of memory. My understanding is that we allocate some memory for i, list, and every time we add i to the list, we allocate more memory for it.But, by using a thunk, I can create an infinite list which will not eat all of my memory:infList(final int start){    return new InfiniteList (     start,     return new InfiniteList.LazyTail(){eval(){return infList(start+1);}}    );}(I adapted source from here). How does this work? I know I am delaying the evaluation of the expressions : start+1, start+1, start+1 ... but do I end up with a list of something like this: [start, eval(){start+1}, eval(){start+1}, eval(){start+1} ... ]Are the 'eval(){...}' object references? Do they take up space in memory? Will I eventually run out of memory with this implementation (I tried, but memory allocation was not budging)? Do I only start using memory, say, if I wanted to system.out.print integers, then they would have to be evaluated, and some memory allocated?
Java memory management (thunks/lazyness)
java;functional programming;memory
The idea behind all simple lists is the following:Make sure you can tell if you have an empty list or not.If it's not the empty list, you have 2 parts:the head of the listand the tail (rest of the list)Since Java supports closures (well, kind of), one can implement lazy lists with the following trick: Instead of having a reference directly to the tail, have a reference to an Object which is able to compute the tail. Such an Object could be a Callable<ZList>, say, if ZList is our list type. And yes, such a closure constructed with // assuming constructor ZList(int, Callable<ZList>); public Callable<ZList> nextNode(final int current) {   return new Callable<ZList> {     ZList call() {          return new ZList(current, nextNode(current+1));     }   }; }takes up some finite amount of memory. Certainly more than a singe list node, but less than many list nodes.As for the memory requirement: It is posible to go through such an infinite list, and still have constant memory usage as long as the start of the list is stored nowhere. Because, in that case, the head node you're done with can and will be garbage collected.If, however, you have the head of the infinite list somewhere (in a static variable, say) memory usage will increase as you traverse the list.Because such things are painful to write in Java, there are new JVM languages like Scala (functional/OO), Clojure (List) or Frege (Haskell like) that make it easy to have such things in the JVM.Frege may be interesting for you because a) it is non-strict (i.e. lazy) and b) it spits out java source code, hence you could study and play the java sources created by simple functional programs. 