/** This *is* the lazy evaluator a.k.a. graph reducer.
 *
 * Entire Haskell programs are represented as graphs of Thunks.
 * Since a Thunk can represent a computation, which can in turn create more of the graph,
 * conceptually, graphs can be infinite, because these computations are run transparently 
 * and automatically. It is therefore possible to define a graph without thinking about
 * how large it is, as only a little bit of it will ever be represented in memory at once.
 */
public class Thunk<A> {
  /** Returns the value this Thunk wraps. */
  public final A eval() {
    if (value != null) return value;
    else { value = computation.compute(null); return value; }
  }

  /** Make a Thunk with a lazily executed computation in it. */
  public Thunk(Computation<A> computation) {
    this.computation = computation;
  }
  /** Make a Thunk with an already computed value in it. */
  public Thunk(A value)            {
    // FP *never* uses null pointers as real values, so we can safely use
    // nulls inside our low-level, (hopefully) hidden plumbing.
    assert(value != null);

    this.value = value;
  }

  /** Convenience/readability alias for new Thunk<A>(value) */
  public static <A> Thunk<A> ready(            A  x) { return new Thunk<A>(x); }
  /** Convenience/readability alias for new Thunk<A>(computation) */
  public static <A> Thunk<A> lazy (Computation<A> x) { return new Thunk<A>(x); }

  private             A  value       = null;
  private Computation<A> computation = null;

  /** a helper interface for Thunk.lazy that should not be used directly */
  public static interface Computation<A> { A compute(Void v); }
}

@@ -596,16 +596,24 @@
 != null)
+ %7B%0A     
  return 
@@ -626,15 +626,23 @@
 %0A   
+ %7D
  else %7B
+%0A     
  val
@@ -672,16 +672,22 @@
 e(null);
+%0A     
  return 
@@ -692,16 +692,20 @@
 n value;
+%0A   
  %7D%0A  %7D%0A%0A
@@ -733,102 +733,339 @@
 th a
- lazily executed computation in it. */%0A  public Thunk(Computation%3CA%3E computation) %7B%0A    this.c
+n already computed value in it. */%0A  public static %3CA%3E Thunk%3CA%3E ready(            A  x) %7B return new Thunk%3CA%3E(x); %7D%0A  /** Make a Thunk with a lazily executed computation in it. */%0A  public static %3CA%3E Thunk%3CA%3E lazy (Computation%3CA%3E x) %7B return new Thunk%3CA%3E(x); %7D%0A%0A  ///%0A%0A  private                   A  value = null;%0A  private final C
 ompu
@@ -1070,18 +1070,19 @@
 putation
- =
+%3CA%3E
  computa
@@ -1091,80 +1091,104 @@
 on;%0A
-  %7D%0A  /** Make a Thunk with an already computed value in it. */%0A  public
+%0A  private Thunk(Computation%3CA%3E computation) %7B%0A    this.computation = computation;%0A  %7D%0A  private
  Thu
@@ -1408,395 +1408,38 @@
 ;%0A  
-%7D%0A%0A  /** Convenience/readability alias for new Thunk%3CA%3E(value) */%0A  public static %3CA%3E Thunk%3CA%3E ready(            A  x) %7B return new Thunk%3CA%3E(x); %7D%0A  /** Convenience/readability alias for new Thunk%3CA%3E(computation) */%0A  public static %3CA%3E Thunk%3CA%3E lazy (Computation%3CA%3E x) %7B return new Thunk%3CA%3E(x); %7D%0A%0A  private             A  value       = null;%0A  private Computation%3CA%3E computation = null;
+  this.computation = null;%0A  %7D
 %0A%0A  

refactor Thunk a little bit