About CTM The following Alice ML code is derived from the examples provided in the book:
      "Concepts, Techniques, and Models of Computer Programming" by Peter Van Roy and Seif Haridi.
      http://www2.info.ucl.ac.be/people/PVR/book.html

(* CTM Chapter #04 Examples in Alice ML *)
(* syntactic sugar for solutions using promises/futures *)
open Promise
open Future
infix 3 ?=
val op?= = fulfill
val ? = future;

(* Unify functions used for examples (via chapter 2) *)
exception Unify
fun known x =
   let
      val p = promise()
   in
      fulfill(p, x); p
   end
fun unifyPromise unifyContent (p1, p2) =
   if (p1 = p2)
      then ()
      else
         case (isFulfilled p1, isFulfilled p2)
          of (false, _) => fulfill(p1, future p2)
           | (_, false) => fulfill(p2, future p1)
           | (true, true) => unifyContent(future p1, future p2)
fun unifySimple(x, y) = if x = y then () else raise Unify

(* 4.0 Declarative Concurrency *)
fun gen (i, n) if (i > n) = nil
  | gen (i, n) =
      let
         val _ = Thread.sleep(Time.fromMilliseconds(Int.toLarge 100))
      in
         i::gen(i+1, n)
      end
val xs = gen(1, 10);
inspect (map (fn x => x*x) xs);

fun gen (i, n, p) if (i > n) = ( p ?= nil; future p )
  | gen (i, n, p) =
      let
         val px = promise()
      in
         Thread.sleep(Time.fromMilliseconds(Int.toLarge 100));
         p ?= i::(future px);
         gen(i+1, n, px);
         future p
      end
val xs = promise();
spawn gen(1, 10, xs);

(* note that map will run concurrently but won't return a result until the function terminates *)
val ys = spawn map (fn x => x*x) (future xs);
inspect ys;

fun mapPromise f nil p = ( p ?= nil; future p )
  | mapPromise f (x::xs) p =
      let
         val px = promise()
      in
         p ?= (f x)::(future px);
         mapPromise f xs px;
         future p
      end;
val ys = promise();
spawn mapPromise (fn x => x*x) (future xs) ys;
inspect (future ys);

(* 4.1.3 The data-driven concurrent model - Semantics of threads *)
let
   val b = promise()
in
   spawn b ?= true;
   if (future b)
      then inspect "yes"
      else ()
end;

(* 4.1.4 The data-driven concurrent model - What is declarative concurrency *)
fun double (nil, p)   = ( p ?= nil; future p )
  | double (x::xs, p) =
      let
         val px = promise()
      in
         p ?= (2*x)::(future px);
         double(xs, px);
         future p
      end
val xs = promise()
val ys = promise()
val xr = promise();
spawn double(future xs, ys);
inspect (future ys);
xs ?= 1::2::3::(future xr);

val x = promise()
val y = promise();
unifyPromise unifySimple (x, known(1));
unifyPromise unifySimple (y, x);

val x = promise()
val y = promise();
unifyPromise unifySimple (y, x);
unifyPromise unifySimple (x, known(1));

datatype 'a foo = Foo of 'a * 'a
val y = promise()
val z = promise()
val w = promise()
val x = Foo (future y, future w);
unifyPromise unifySimple (y, z);

val y = promise()
val z = promise()
val w = promise()
val x = Foo (future z, future w);
unifyPromise unifySimple (y, z);

val x = promise()
val y = promise();
spawn unifyPromise unifySimple (x, known(1));
spawn unifyPromise unifySimple (y, known(2));
spawn unifyPromise unifySimple (x, y);
(future x = future y) handle Unify => false;

let
   datatype status = Ok | Err
   val x = promise()
   val y = promise()
   val x1 = promise()
   val y1 = promise()
   val s1 = promise()
   val s2 = promise()
   val s3 = promise()
in
   spawn ( unifyPromise unifySimple (x1, known(1)); s1 ?= Ok )
      handle Unify => s1 ?= Err;
   spawn ( unifyPromise unifySimple (y1, known(2)); s2 ?= Ok )
      handle Unify => s2 ?= Err;
   spawn ( unifyPromise unifySimple (x1, y1); s3 ?= Ok )
      handle Unify => s3 ?= Err;
   if (future s1 = Err) orelse (future s2 = Err) orelse (future s3 = Err)
      then ( x ?= 1; y ?= 1 )
      else ( x ?= future x1; y ?= future y1 )
end;

(* 4.2.1 Basic thread programming techniques - Creating threads *)
spawn
   let
      fun count n =
         if (n > 0)
            then count(n-1)
            else ()
   in
     count 1000000
   end;

val x = (spawn 10 * 10) + 100*100;

let
   val x = promise()
   val y = spawn 10*10
in
   x ?= y + 100*100
end;

(* 4.2.2 Basic thread programming techniques - Threads and the browser *)
spawn inspect 111;
inspect 222;

let
   val x1 = promise()
   val x2 = promise()
   val y1 = promise()
   val y2 = promise()
in
   spawn inspect (future x1);
   spawn inspect (future y1);
   spawn x1 ?= "all"::"roads"::(future x2);
   spawn y1 ?= "all"::"roams"::(future y2);
   spawn x2 ?= "lead"::"to"::"rome"::(future (promise()));
   spawn y2 ?= "lead"::"to"::"rhodes"::(future (promise()))
end;

(* 4.2.3 Basic thread programming techniques - Dataflow computation with threads *)

(* simple dataflow behavior *)
let
   val x0 = promise()
   val x1 = promise()
   val x2 = promise()
   val x3 = promise()
in
   spawn
      let
         val y0 = promise()
         val y1 = promise()
         val y2 = promise()
         val y3 = promise()
      in
        inspect (future y0, future y1, future y2, future y3);
        y0 ?= (future x0) + 1;
        y1 ?= (future x1) + (future y0);
        y2 ?= (future x2) + (future y1);
        y3 ?= (future x3) + (future y2);
        inspect "completed"
      end;
   inspect (future x0, future x1, future x2, future x3);
   x0 ?= 0;
   x1 ?= 1;
   x2 ?= 2;
   x3 ?= 3
end;

(* using a declarative program in a concurrent setting *)
fun forall nil f = ()
  | forall (x::xs) f = (f x; forall xs f);

let
   val xs = promise()
   val x1 = promise()
   val x2 = promise()
in
   spawn forall (future xs) inspect;
   spawn xs ?= 1::(future x1);
   spawn x1 ?= 2::3::(future x2);
   spawn x2 ?= 4::nil
end;

let
   val xs = promise()
in
   spawn forall (future xs) inspect;
   xs ?= [1,2,3,4]
end;

(* A concurrent map function *)
fun mapPromiseSpawn f nil p = ( p ?= nil; future p )
  | mapPromiseSpawn f (x::xs) p =
      let
         val px = promise()
      in
         p ?= (spawn (f x))::(future px);
         mapPromiseSpawn f xs px;
         future p
      end;

let
   val p = promise()
   val xs = promise()
   val ys = promise()
   val zs = promise()
   val f = promise()
in
   spawn mapPromiseSpawn (future f) (future xs) p;
   inspect (future p);
   xs ?= 1::2::(future ys);
   f ?= (fn x => x*x);
   ys ?= 3::(future zs);
   zs ?= nil
end;

(* A concurrent Fibonacci function *)
fun fib x if (x <= 2) = 1
  | fib x = (spawn fib (x-1)) + (fib (x-2));
inspect (fib 26);

(* Note: All Alice threads run at the same priority *)

(* 4.3.1 Streams - Basic producer/consumer *)

val xs = promise()
val xs2 = promise();
xs ?= 0::1::2::3::4::(future xs2);

val xs3 = promise();
xs2 ?= 5::6::7::(future xs3);

fun generate (n, limit, p) if (n >= limit) =
      ( p ?= nil; future p )
  | generate (n, limit, p) =
      let
         val px = promise()
      in
         p ?= n::(future px);
         generate(n+1, limit, px);
         future p
      end
fun sum (nil, a) = a
  | sum (x::xs, a) = sum(xs, a+x);

(* Note: I'm using smaller limit so as to fit in 31 bit int *)
(* Convert functions to IntInf if you want to use 150000    *)
let
   val xs = promise()
   val s = promise()
in
   spawn generate(0, 15000, xs);
   spawn s ?= sum(future xs, 0);
   inspect (future s)
end;

let
   val xs = promise()
   val s = promise()
in
   spawn generate(0, 15000, xs);
   spawn s ?= foldl (fn (x, y) => x+y) 0 (future xs);
   inspect (future s)
end;

let
   val xs = promise()
   val s1 = promise()
   val s2 = promise()
   val s3 = promise()
in
   spawn generate(0, 15000, xs);
   spawn s1 ?= sum(future xs, 0);
   spawn s2 ?= sum(future xs, 0);
   spawn s3 ?= sum(future xs, 0);
   inspect (future s1, future s2, future s3)
end;

(* 4.3.2 Streams - Transducers and pipelines *)

(* filtering a stream *)
fun filterPromise f nil p = ( p ?= nil; future p )
  | filterPromise f (x::xs) p =
      if (f x)
         then
            let
               val px = promise()
            in
               p ?= x::(future px);
               filterPromise f xs px;
               future p
            end
         else (filterPromise f xs p)

fun isOdd x = (x mod 2) <> 0;

let
   val xs = promise()
   val ys = promise()
   val s = promise()
in
   spawn generate(0, 15000, xs);
   spawn filterPromise isOdd (future xs) ys;
   spawn s ?= sum(future xs, 0);
   inspect (future s)
end;

(* Sieve of Eratosthenes *)
fun sieve (nil, p) = ( p ?= nil; future p )
  | sieve (x::xs, p) =
      let
         val ys = promise()
         val px = promise()
      in
         p ?= x::(future px);
         spawn ys ?= List.filter (fn y => (y mod x) <> 0) xs;
         sieve(future ys, px);
         future p
      end;

(* Note: Not sure it works for 100000 - takes a while *)
let
   val xs = promise()
   val ys = promise()
in
   spawn generate(2, 10000, xs);
   spawn sieve(future xs, ys);
   inspect (future ys)
end;

fun sieve (nil, m, p) = ( p ?= nil; future p )
  | sieve (x::xs, m, p) =
      let
         val ys = promise()
         val px = promise()
      in
         p ?= x::(future px);
         if (x <= m)
            then spawn ys ?= List.filter (fn y => (y mod x) <> 0) xs
            else ys ?= xs;
         sieve(future ys, m, px);
         future p
      end;

(* 4.3.3 Streams - Managing resources and improving throughput *)

(* Flow control with demand driven concurrency *)
fun dgenerate (n, nil)   = ()
  | dgenerate (n, x::xs) = ( x ?= n; dgenerate(n+1, xs) )

fun dsum (xs, a, limit) if (limit <= 0) = ( xs ?= nil; a )
  | dsum (xs, a, limit) =
      let
         val x = promise()
         val xr = promise()
      in
         xs ?= x::(future xr);
         dsum(xr, a+(future x), limit-1)
      end;

let
   val xs = promise()
   val s = promise()
in
   spawn dgenerate(0, future xs);
   spawn s ?= dsum(xs, 0, 15000);
   inspect (future s)
end;

(* Flow control with a bounded buffer *)
fun buffer (n, xs, ys) =
   let
      fun startup (n, xs) if (n = 0) = xs
        | startup (n, xs) =
            let
               val x = promise()
               val xr = promise()
            in
               xs ?= x::(future xr);
               startup(n-1, xr)
            end
      val endb = startup(n, xs)
      fun askLoop (y::ys, x::xs, endb) =
            let
               val end2 = promise()
            in
               y ?= future x;
               endb ?= promise()::(future end2);
               askLoop(ys, xs, end2)
            end
        | askLoop (_, _, _) = ()
   in
      spawn askLoop(ys, future xs, endb)
   end;

let
   val xs = promise()
   val ys = promise()
   val s = promise()
in
   spawn dgenerate(0, future xs);
   spawn buffer(4, xs, future ys);
   spawn s ?= dsum(ys, 0, 15000);
   inspect (future s)
end;

(* Flow control with thread priorities - priorities not supported by Alice *)
fun setThisPriority () = ();
let
   val xs = promise()
   val s = promise()
in
   spawn ( setThisPriority(); dgenerate(0, future xs) );
   spawn ( setThisPriority(); s ?= dsum(xs, 0, 15000) );
   inspect (future s)
end;

(* 4.3.4 Streams - Stream objects *)
fun nextState (m, x1, n, x2) = ()

fun streamObject (nil, x1, t1) = ( t1 ?= nil; future t1 )
  | streamObject (m::s2, x1, t1) =
      let
         val n = promise()
         val t2 = promise()
         val x2 = promise()
      in
         nextState(m, x1, n, x2);
         t1 ?= (future n)::(future t2);
         streamObject(s2, future x2, t2);
         future t1
      end;

let
   val s0 = promise()
   val x0 = promise()
   val t0 = promise()
in
   spawn streamObject(future s0, future x0, t0)
end;

let
   val s0 = promise()
   val t0 = promise()
   val u0 = promise()
   val v0 = promise()
in
   spawn streamObject(future s0, 0, t0);
   spawn streamObject(future t0, 0, u0);
   spawn streamObject(future u0, 0, v0)
end;

(* 4.3.5.1 Streams - Digital logic simulation - Combinatorial logic *)
fun notGate (nil, p)   = ( p ?= nil; future p )
  | notGate (x::xs, p) =
      let
         val px = promise()
      in
         p ?= (1-x)::(future px);
         notGate(xs, px);
         future p
      end

fun notG (xs, p) =
   let
      fun notLoop (nil, p)   = ( p ?= nil; future p )
        | notLoop (x::xs, p) =
            let
               val px = promise()
            in
               p ?= (1-x)::(future px);
               notLoop(xs, px);
               future p
            end
   in
      spawn notLoop(xs, p)
   end

fun gateMaker f =
   fn (xs, ys, p) =>
      let
         fun gateLoop (nil, _, p)       = ( p ?= nil; future p )
           | gateLoop (_, nil, p)       = ( p ?= nil; future p )
           | gateLoop (x::xr, y::yr, p) =
               let
                  val px = promise()
               in
                  p ?= f(x, y)::(future px);
                  gateLoop(xr, yr, px);
                  future p
               end
      in
         spawn gateLoop(xs, ys, p)
      end

val andG    = gateMaker (fn (x, y) => x*y)
val orG     = gateMaker (fn (x, y) => x+y-x*y)
val nandG   = gateMaker (fn (x, y) => 1-x*y)
val norG    = gateMaker (fn (x, y) => 1-x-y+x*y)
val xorG    = gateMaker (fn (x, y) => x+y-2*x*y)

fun fullAdder (x, y, z, c, s) =
   let
      val k = promise()
      val l = promise()
      val m = promise()
      val pc = promise()
      val ps = promise()
   in
      andG(x, y, k);
      andG(y, z, l);
      andG(x, z, m);
      orG(future l, future m, pc);
      orG(future k, future pc, c);
      xorG(x, y, ps);
      xorG(z, future ps, s);
      future s
   end;

let
   val x = [1, 1, 0, future (promise())]
   val y = [0, 1, 0, future (promise())]
   val z = [1, 1, 1, future (promise())]
   val c = promise()
   val s = promise()
in
   fullAdder(x, y, z, c, s);
   inspect ((x, y, x), (future c, future s))
end;

(* 4.3.5.2 Streams - Digital logic simulation - Sequential logic *)
fun delayG xs = 0::xs

fun latch (c, di, p) =
   let
      val d0 = promise()
      val x = promise()
      val y = promise()
      val z = promise()
      val f = promise()
   in
      p ?= future d0;
      andG(future f, c, x);
      notG(c, z);
      andG(future z, di, y);
      orG(future x, future y, d0);
      f ?= delayG(future d0);
      future d0
   end

(* 4.3.5.3 Streams - Digital logic simulation - Clocking *)

fun clock p =
   let
      fun loop b =
         let
            val px = promise()
         in
            p ?= b::future px;
            loop b;
            future p
         end
   in
      spawn (loop 1)
   end

fun clock p =
   let
      fun loop b =
         let
            val px = promise()
         in
            Thread.sleep(Time.fromMilliseconds(Int.toLarge(1000)));
            p ?= b::future px;
            loop b;
            future p
         end
   in
      spawn (loop 1)
   end

(* 4.3.5.4 Streams - Digital logic simulation - A linguistic abstraction for logic gates *)

(* Note: Not willing to tackle this at the current time *)

(* 4.4.1 Using the declarative concurrent model directly - Order-determining concurrency *)
datatype ('a, 'b, 'c) obtree = Leaf
                             | Tree of { key   : 'a,
                                         value : 'b,
                                         x     : 'c promise,
                                         y     : 'c promise,
                                         left  : ('a, 'b, 'c) obtree,
                                         right : ('a, 'b, 'c) obtree }

val scale = 30

fun depthFirst (Tree{x, y, left=Leaf, right=Leaf, ...}, level, leftLim, rootX, rightLim) =
      let
      in
         x ?= future leftLim;
         rootX ?= future x;
         rightLim ?= future x;
         spawn y ?= scale * level
      end
  | depthFirst (Tree{x, y, left, right=Leaf, ...}, level, leftLim, rootX, rightLim) =
      let
      in
         x ?= future rootX;
         spawn y ?= scale * level;
         depthFirst(left, level+1, leftLim, rootX, rightLim)
      end
  | depthFirst (Tree{x, y, left=Leaf, right, ...}, level, leftLim, rootX, rightLim) =
      let
      in
         x ?= future rootX;
         spawn y ?= scale * level;
         depthFirst(right, level+1, leftLim, rootX, rightLim)
      end
  | depthFirst (Tree{x, y, left, right, ...}, level, leftLim, rootX, rightLim) =
      let
         val lRootX = promise()
         val rRootX = promise()
         val lRightLim = promise()
         val rLeftLim = promise()
      in
         rootX ?= future x;
         spawn x ?= (future lRootX + future rRootX) div 2;
         spawn y ?= scale * level;
         spawn rLeftLim ?= (future lRightLim) + scale;
         depthFirst(left, level+1, leftLim, lRootX, lRightLim);
         depthFirst(right, level+1, rLeftLim, rRootX, rightLim)
      end
  | depthFirst (Leaf, _, _, _, _) = ();

(* 4.4.2 Using the declarative concurrent model directly - Coroutines *)
fun fspawn p =
   let
      val pid = promise()
   in
      spawn (
         pid ?= Thread.current();
         Thread.suspend(future pid);
         future p);
      future pid
   end

fun fresume id = (
   Thread.resume id;
   Thread.suspend(Thread.current()))

(* 4.4.3 Using the declarative concurrent model directly - Concurrent composition *)
fun barrier ps =
   let
      fun barrierLoop (nil, n) = n
        | barrierLoop (f::fs, n) =
            let
               val m = promise()
            in
               spawn ( f(); m ?= n );
               barrierLoop(fs, future m)
            end
      val s = promise()
   in
      spawn s ?= barrierLoop(ps, ());
      await s
   end

(* 4.5 Lazy execution *)
fun lazy f1 x = 1+x*(3+x*(3+x))
fun lazy f2 x = let val y = x*x in y*y end
fun lazy f3 x = (x+1)*(x+1)
val a = f1(10)
val b = f2(20)
val c = f3(30)
val d = a+b

(* 4.5.1 Lazy execution - The demand-driven concurrent model *)
val y = promise();
(fn a => a ?= (lazy 111 * 111)) y;
inspect (future y);
await (future y);

let
   val x = promise()
   val y = promise()
   val z = promise()
in
   spawn x ?= (lazy (fn () => 3) ());
   spawn y ?= (lazy (fn () => 4) ());
   spawn z ?= (future x) + (future y)
end;

let
   val x = promise()
   val z = promise()
in
   let
      val f = (fn () => 3) ()
      val t1 = spawn unifyPromise unifySimple (x, lazy known(f))
      val t2 = spawn unifyPromise unifySimple (x, lazy known(2))
      val t3 = spawn z ?= (future x) + 4
   in
      await t1;
      await t2;
      await t3
   end;
   inspect "Unify"
end
handle Unify => inspect "Unify Exception";

let
   val x = promise()
   val y = promise()
   val z = promise()
   val f = (fn () => 3) ()
in
   spawn unifyPromise unifySimple (x, lazy known(f));
   spawn unifyPromise unifySimple (x, y);
   spawn (if future x = future y then z ?= 10 else ());
   inspect (future x)
end;

fun lazy generate n = n::generate(n+1)
val x = generate 0;
inspect x;
inspect (hd (tl (tl x)));
fun generate n = lazy(n::generate(n+1))

(* 4.5.2 Lazy execution - Declarative computation models *)
val x = 11*11                                         (* (1)&(2)&(3) together *)

fun lazy lazyMul (a, b) = a*b
val x = lazyMul(11, 11);                              (* (1)&(2) together *)
await x;                                              (* (3) seperate *)

val x = lazy 11 * 11;                                 (* (1)&(2) together *)
await x;                                              (* (3) seperate *)

val x = promise();                                    (* (1) seperate *)
x ?= 11 * 11;                                         (* (2)&(3) together *)

val x = promise();                                    (* (1) seperate *)
spawn x ?= 11 * 11;                                   (* (2)&(3) together *)
spawn if (future x > 100) then inspect "big" else ();

val x = promise();                                    (* (1) seperate *)
x ?= (lazy 11 * 11);                                  (* (2) seperate *)
await x;                                              (* (3) seperate *)

val x = promise();                                    (* (1) seperate *)
spawn x ?= (lazy 11 * 11);                            (* (2) seperate *)
spawn await x;                                        (* (3) seperate *)

let
   val z = promise()
   fun lazy f1 x = x + future z
   fun lazy f2 y = (z ?= 1; y + future z)
in
   (* inspect (f1(1) + f2(2)) *)                      (* deadlock *)
   inspect (f2(1) + f1(2))
end;

(* 4.5.3 Lazy execution - Lazy streams *)
fun lazy generate n = n::generate(n+1)

fun sum (_, a, limit) if (limit <= 0) = a
  | sum (x::xs, a, limit) = sum(xs, a+x, limit-1)
  | sum (nil, _, _) = raise Empty;

let
   val xs = generate 0
   val s = sum(xs, 0, 15000)
in
   inspect s
end;

let
   val s1 = promise()
   val s2 = promise()
   val s3 = promise()
   val xs = generate 0
in
   s1 ?= (spawn sum(xs, 0, 15000));
   s2 ?= (spawn sum(xs, 0, 10000));
   s3 ?= (spawn sum(xs, 0, 5000))
end;

(* 4.5.4 Lazy execution - Bounded buffer *)
fun buffer1 (xin, n) =
   let
      val xend = List.drop(xin, n)
      fun lazy loop (x::xs, xend) = x::loop(xs, tl xend)
        |      loop (nil, xend)   = raise Empty
   in
      loop(xin, xend)
   end

fun buffer2 (xin, n) =
   let
      val xend = List.drop(xin, n)
      fun lazy loop (x::xs, xend) = x::loop(xs, spawn tl xend)
        |      loop (nil, xend)   = raise Empty
   in
      loop(xin, xend)
   end

fun lazy ints n =
   let
      val _ = Thread.sleep(Time.fromMilliseconds(Int.toLarge 1000))
   in
      n::ints(n+1)
   end;

let
   val xin = ints 1
   val out = buffer2(xin, 5)
in
   inspect out;
   inspect (hd out);
   inspect (tl(tl(tl(tl(tl(tl(tl(tl(tl(tl out))))))))))
end;

(* 4.5.5 Lazy execution - Reading a file lazily *)
fun readListLazy fname =
   let
      val infile = TextIO.openIn fname
      fun lazy readNext () =
         let
            val xs = explode(TextIO.inputN(infile, 100))
         in
            if (null xs)
               then TextIO.closeIn infile
               else ( readNext(); () );
            xs
         end
   in
      readNext()
   end

(* 4.5.6 Lazy execution - The Hamming problem *)
fun lazy times n []      = []
  |      times n (x::xs) = (n*x)::(times n xs)

fun lazy merge xs nil = xs
  | merge nil ys = ys
  | merge (xs as x::xr) (ys as y::yr) =
      if x < y
         then x::(merge xr ys)
         else
            if x > y
               then y::(merge xs yr)
               else x::(merge xr yr)

val h = promise();
h ?= 1 :: (merge (times 2 (future h))
                 (merge (times 3 (future h))
                        (times 5 (future h))));

inspect h;

fun touch (n, x::xs) if (n > 0) = touch(n-1, xs)
  | touch (_, _) = ();

touch(20-1, future h);

(* alternately, we could use take to accomplish the same end *)
List.take(future h, 20);

(* 4.5.7 Lazy execution - Lazy list operations *)

(* lazy append *)
fun lazy lazyAppend (nil, ys)   = ys
  |      lazyAppend (x::xs, ys) = x::lazyAppend(xs, ys)

val x = lazyAppend(explode "foo", explode "bar")

fun lazy makeLazy nil     = nil
  |      makeLazy (x::xs) = x::makeLazy xs

val x = lazyAppend(explode "foo", makeLazy(explode "bar"));

inspect (implode x);

(* lazy mapping *)
fun lazy lazyMap f nil     = nil
  |      lazyMap f (x::xs) = (f x)::(lazyMap f xs)

(* lazy integer lists *)
datatype 'a lazyfromtype = Infinite | Number of 'a
fun lazyFrom (i, j) =
   let
      fun lazy lazyFromLoop (i, j) if (i > j) = nil
        |      lazyFromLoop (i, j) = i::lazyFromLoop(i+1, j)
      fun lazy lazyFromInf i = i::lazyFromInf(i+1)
   in
      case j of
          Infinite => lazyFromInf i
        | Number x => lazyFromLoop(i, x)
   end

(* lazy flatten *)
datatype 'a nestedlist = Leaf of 'a
                       | Branch of 'a nestedlist list

fun lazyFlatten xs =
   let
      fun lazy lazyFlattenD (Branch nil, e) = e
        | lazyFlattenD (Branch ((Branch x)::xr), e) =
            lazyFlattenD(Branch x, lazyFlattenD(Branch xr, e))
        | lazyFlattenD (Branch ((Leaf   x)::xr), e) =
            x::lazyFlattenD(Branch xr, e)
        | lazyFlattenD (Leaf x, e) = x::e
   in
      lazyFlattenD(xs, [])
   end

(* lazy reverse *)
fun lazyReverse s =
   let
      fun lazy rev (nil, r) = r
        |      rev (x::xs, r) = rev(xs, x::r)
   in
      rev(s, nil)
   end

val x = lazyReverse [#"a", #"b", #"c"];
inspect x;
List.take(x, 1);

(* lazy filter *)
fun lazy lazyFilter f nil = nil
  | lazyFilter f (x::xs) =
      if (f x)
         then x::(lazyFilter f xs)
         else (lazyFilter f xs)

(* 4.5.8.1 Lazy execution - Persistent queues and algorithm design - Amortized persistent queue *)
datatype 'a queue = Queue of int * 'a list * int * 'a list

fun newQueue () = Queue(0, nil, 0, nil)

fun checkQ (q as Queue(lenf, f, lenr, r)) =
   if (lenf >= lenr)
      then q
      else Queue(lenf+lenr, lazyAppend(f, List.rev r), 0, nil)

fun insertQ (Queue(lenf, f, lenr, r), x) =
   checkQ(Queue(lenf, f, lenr+1, x::r))

fun deleteQ (q, px) =
      let
         val Queue(lenf, f, lenr, r)= checkQ(q)
      in
         px ?= hd f;
         checkQ(Queue(lenf-1, tl f, lenr, r))
      end

(* 4.5.8.2 Lazy execution - Persistent queues and algorithm design - Worst-case persistent queue *)
fun reverse r =
   let
      fun rev (nil, a)   = a
        | rev (x::xs, a) = rev(xs, x::a)
   in
      rev(r, nil)
   end

fun lazy lazyAppend (nil, b) = b
  |      lazyAppend (x::xs, b) = x::lazyAppend(xs, b)

fun lazy lazyAppRev (nil, y::nil, b)  = y::b
  |      lazyAppRev (x::xs, y::ys, b) = x::lazyAppRev(xs, ys, y::b)
  |      lazyAppRev (x::xs, nil, b)   = raise Empty

fun checkQ (q as Queue(lenf, f, lenr, r)) =
   if (lenf >= lenr)
      then q
      else Queue(lenf+lenr, lazyAppRev(f, r, nil), 0, nil)

(* 4.5.9 Lazy execution - List comprehensions *)
(* Note: Alice doesn't sport list comprehensions *)
fun eagerFrom (i, j) =
   let
      fun fromLoop (i, j) if (i > j) = nil
        | fromLoop (i, j) = i::fromLoop(i+1, j)
      fun fromInf i = i::fromInf(i+1)
   in
      case j of
          Infinite => fromInf i
        | Number x => fromLoop(i, x)
   end

val z = map (fn x =>(x, x)) (eagerFrom(1, Number 10))

val z = lazyMap (fn x =>(x, x)) (lazyFrom(1, Number 10))

val z = lazyFlatten (Branch (
            lazyMap
               (fn x => Branch (lazyMap (fn y => Leaf (x, y))
               (lazyFrom(1, Number x))))
            (lazyFrom(1, Number 10))))

fun fmap f xs = lazyFlatten(Branch (lazyMap f xs))

val z = fmap
         (fn x => Branch (lazyMap (fn y => Leaf (x, y)) (lazyFrom(1, Number x))))
         (lazyFrom(1, Number 10))

val z = lazyFilter
         (fn (x,y) => x+y <= 10)
         (fmap
            (fn x => Branch (lazyMap (fn y => Leaf (x, y)) (lazyFrom(1, Number x))))
            (lazyFrom(1, Number 10)))

val z = fmap
         (fn x => Branch (lazyMap (fn y => Leaf (x, y)) (lazyFrom(1, Number (10-x)))))
         (lazyFrom(1, Number 10))

(* 4.6.1 Soft real-time programming - Basic operations *)
fun for a b s f =
   let
      fun loopup c if (c <= b) = (f c; loopup (c+s))
        | loopup c = ()
      fun loopdown c if (c >= b) = (f c; loopdown (c+s))
        | loopdown c = ()
   in
      if (s > 0)
         then loopup a
         else
            if (s < 0)
               then loopdown a
               else ()
   end;

let
   fun ping n =
      if (n = 0)
         then inspect "ping terminated"
         else (
            Thread.sleep(Time.fromMilliseconds(Int.toLarge 500));
            inspect "ping";
            ping(n-1))
   fun pong n = (
      for 1 n 1 (fn i => ( Thread.sleep(Time.fromMilliseconds(Int.toLarge 600)); inspect "pong" ));
      inspect "pong terminated")
in
   inspect "game started";
   spawn ping 5;
   spawn pong 5
end;

functor PingPong () =
   struct
      fun ping n =
         if (n = 0)
            then inspect "ping terminated"
            else (
               Thread.sleep(Time.fromMilliseconds(Int.toLarge 500));
               inspect "ping";
               ping(n-1))
      fun pong n = (
         for 1 n 1  (fn i => ( Thread.sleep(Time.fromMilliseconds(Int.toLarge 600)); inspect "pong" ));
         inspect "pong terminated")

      fun run () =
         let
            val _ = inspect "game started"
            val t1 = spawn ping 50
            val t2 = spawn pong 50
         in
            await t1;
            await t2;
            OS.Process.exit OS.Process.success
         end

      val _ = run()
end

(* 4.6.2 Soft real-time programming - Ticking *)
fun forall nil f = ()
  | forall (x::xs) f = (f x; forall xs f)

fun newTicker p =
   let
      fun loop p =
         let
            val x = Time.now()
            val px = promise()
         in
            Thread.sleep(Time.fromMilliseconds(Int.toLarge 1000));
            p ?= x::(future px);
            loop px
         end
   in
      spawn loop p
   end;

val px = promise();
(* spawn newTicker px; *)      (* Uncomment to run *)
spawn forall (future px) (fn x => inspect x);

fun newTicker p =
   let
      fun loop (p, t) =
         let
            val x = Time.now()
            val px = promise()
         in
            Thread.sleep(Time.fromMilliseconds(Int.toLarge 900));
            if (Time.toSeconds(t) <> Time.toSeconds(x))
               then p ?= x::(future px)
               else ();
            loop(px, x)
         end
   in
      spawn loop(p, Time.now())
   end

fun newTicker p =
   let
      fun loop (p, t) =
         let
            val x = Time.now()
            val px = promise()
         in

            if (Time.toSeconds(t) > Time.toSeconds(x))
               then Thread.sleep(Time.fromMilliseconds(Int.toLarge 900))
               else
                  if (Time.toSeconds(t) > Time.toSeconds(x))
                     then Thread.sleep(Time.fromMilliseconds(Int.toLarge 1100))
                     else Thread.sleep(Time.fromMilliseconds(Int.toLarge 1000));
            p ?= x::(future px);
            loop(px, x)
         end
   in
      spawn loop(p, Time.now())
   end

(* 4.7 The Haskell language *)
fun lazy factorial 0 : int         = 1 : int
  |      factorial n if (n > 0) = n * factorial(n-1)
  |      factorial n               = raise Domain

(* 4.7.1 The Haskell language - Computation model *)
val n = 3;
(if n >= 0 then factorial else raise Domain) (factorial(factorial n));

(* 4.7.2 The Haskell language - Lazy evaluation *)
fun lazy dropWhile f nil = nil
  |      dropWhile f (x::xs) = if (f x) then dropWhile f xs else x::xs
fun lazy dropUntil f xs = dropWhile (not o f) xs

fun lazy sqrt' x =
   let
      fun lazy goodEnough guess = (abs(x - guess*guess) / x) < 0.00001
      fun lazy improve guess = (guess + x/guess) / 2.0
      val sqrtGuesses = promise()
   in
      sqrtGuesses ?= 1.0::(lazyMap improve (future sqrtGuesses));
      hd (dropUntil goodEnough (future sqrtGuesses))
   end;

(sqrt' 36.0) + 0.0;

(* 4.7.3 The Haskell language - Currying *)
val doubleList = lazyMap (fn x => 2*x);

val x = doubleList [1,2,3,4];

List.take(x, 4);

(* 4.7.4 The Haskell language - Polymorphic types *)
datatype 'a btree = Leaf
                  | Node of 'a * 'a btree * 'a btree

fun lazy bsize Leaf = 0
  |      bsize (Node((k, v), lt, rt)) = 1 + (bsize lt) + (bsize rt)

fun lazy lookup k Leaf = NONE
  |      lookup k (Node((nk, nv), lt, rt)) if (k < nk) = lookup k lt
  |      lookup k (Node((nk, nv), lt, rt)) if (k > nk) = lookup k rt
  |      lookup k (Node((nk, nv), lt, rt)) = SOME nv

(* 4.8.3.2 Limitations and Extensions of declarative programming - Nondeterminism *)
fun skip xs =
   if (isDetermined xs)
      then
         case xs of
             x::xr => skip xr
           | nil   => nil
      else xs

fun skip1 nil = nil
  | skip1 (xs as x::xr) =
      if (isDetermined xr)
         then skip1 xr
         else xs

fun displayFrame x = ()

fun display xs =
   case skip1 xs of
       x::xr => ( displayFrame x; display xr )
     | nil   => ()

(* 4.9.1 Advanced topics - The declarativwe concurrent model with exceptions *)
fun foo x = x
val x =
   lazy fn x =>
      let
         val a = promise()
         val b = promise()
      in
         a ?= foo(1);
         b ?= foo(2);
         a ?= future b;
         a
      end

val x = ( raise Promise; () ) handle Promise => ()

fun byneed2 f x =
   lazy (
      fn x =>
         let
            val y = promise()
         in
            f y;
            x ?= future y;
            x
         end
         handle exc => raise Promise)

(* 4.9.3 Advanced topics - Dataflow variables as communication channels *)
fun syncSend x m =
   let
      val sync = promise()
   in
      lazy fn x => ( x ?= future m; sync ?= (); future x);
      await sync
   end

(* 4.9.5 Advanced topics - Usefulness of dataflow variables *)
fun xfuture x = ( x = promise(); future x )




Chris Rathman / Chris.Rathman@tx.rr.com