Lecture 017 - Future

(* 15-210 Parallel and Sequential Data Structures and Algorithms *)
(* Lecture 25, Fall 2022 *)
(* Dec 5, 2022 *)
(* Live-coded in lecture *)

signature FUTURE =
sig

    type 'a t  (* abstract *)
    val future : (unit -> 'a) -> 'a t
    val touch : 'a t -> 'a

end

structure FutureVal :> FUTURE =
struct

type 'a t = 'a
fun future f = f ()
fun touch p = p

end (* structure FutureVal *)

structure FutureName :> FUTURE =
struct

type 'a t = unit -> 'a
fun future f = f
fun touch p = p ()

end (* structure FutureName *)

structure FutureNeed :> FUTURE =
struct

datatype 'a result = VAL of 'a | SUSP of unit -> 'a

type 'a t = ('a result) ref

fun future f = ref (SUSP f)
fun touch p = case !p of
    VAL v => v
  | SUSP f => let val v = f ()
                  val () = p := VAL v
              in v end

end (* structure FutureNeed *)

structure Fut = FutureNeed

datatype 'a stream = Nil | Cons of 'a * ('a stream) Fut.t

(* producer/consumer *)
fun producer 0 = Nil
  | producer n = Cons (n, Fut.future (fn () => producer (n-1)))

fun consumer sum Nil = sum
  | consumer sum (Cons (n, p)) = consumer (sum+n) (Fut.touch p)

(* val ex1 = consumer 0 (producer 3) *)

val ex1 = let val p = Fut.future (fn () => producer 3)
          in consumer 0 (Fut.touch p) end

datatype bit = B0 | B1

fun neg B0 = B1
  | neg B1 = B0

fun fromList nil = Nil
  | fromList (b::bs) = Cons(b, Fut.future (fn () => fromList bs))

fun negate Nil = Nil
  | negate (Cons(b, p)) = Cons (neg b, Fut.future (fn () => negate (Fut.touch p)))

fun toList Nil = nil
  | toList (Cons(b, p)) = b::toList (Fut.touch p)

val ex2 = toList (negate (fromList [B0,B1,B1,B0,B0]))

Table of Content