more about lazyness

Luc Duponcheel luc.duponcheel at gmail.com
Fri Jun 22 03:13:30 PDT 2012


Hi folks,


based upon the reactions of Oleksander and François (and others)
I came up with the following idea

why not defining a class

public class Lazy<Z> {
  private Factory<Z> factory;
  private Z value;
  public Lazy(Factory<Z> factory) {
    this.factory = factory;
  }
  public Z getValue() {
    if (value == null) {
      value = factory.make();
    }
    return value;
  }
}

and define a utility method

  public static <Z> Iterator<Z> lazyIteratorToIterator(final
Lazy<Iterator<Z>> lazyIterator) {
    return new Iterator<Z>() {
      private Iterator<Z> getIterator() {
        return lazyIterator.getValue();
      }
      public boolean hasNext() {
        return getIterator().hasNext();
      }
      public Z next() {
        return getIterator().next();
      }
    };
  }

and change the fibonacci code to

final private static Function2<Integer, Integer, Iterable<Integer>> fibs =
    (z, y) -> cons(z, make(lazyIteratorToIterator(new
Lazy<Iterator<Integer>>(() -> fibs.eval(y, z + y).iterator()))));

where I use

static <T> Iterable<T> make(final Iterator<T> iterator) { /* ... */ }

from Sven's code

this works as a charm.

Maybe using a combination of my utility function(s) and the one(s) from
Sven is a bit of an overkill,
but, hey, this is experimental code using an experimental library :-)


some final remark:

Factory evaluates a closure zero or more times (by need) to produce a value
and is more of a "functional interface" than
Lazy which evaluates a closure zero or one time (by need) *and* has to keep
state (for the evaluated closure).

So, I think it does not make much sense to introduce Lazyness via a
functional interface (although there is only one method involved).
Moreover the "use-site code" would be more complex anyway.


Any comments?

Luc

-- 
   __~O
  -\ <,
(*)/ (*)

reality goes far beyond imagination


More information about the lambda-dev mailing list