Notes and incomplete work.
-rw-r--r-- 1 tonyg staff 3935 Aug 11 2009 boot.tng-modules
-rw-r--r-- 1 tonyg staff 454 Aug 9 2009 calc.tng
-rw-r--r-- 1 tonyg staff 1214 Apr 16 18:18 clojure-sequences-20100416.txt
-rw-r--r-- 1 tonyg staff 2265 Feb 24 13:20 monadic-book.tng
-rw-r--r-- 1 tonyg staff 290 Dec 29 19:37 things-to-consider.txt
Subject: Clojure's sequences and nil punning
Time-stamp: <2010-04-16 17:25:01 tonyg>
From: tonyg
http://clojure.org/lazy
namespace s = "http://eighty-twenty.org/etng/r1/ns/stream#";
define s:foldr stream knil kons ->
stream .s:case {
.s:empty -> knil;
.s:next(head, tail) -> kons(head, s:foldr tail knil kons);
};
define s:map stream fn -> s:foldr stream s:empty {elt, acc -> s:cons(fn(elt), acc)};
Expand through `s:foldr`, and we get
define s:map stream fn ->
stream .s:case {
.s:empty -> s:empty;
.s:next(head, tail) -> s:cons(fn(head), s:map tail fn);
};
Delay:
define nothing = { .case v -> v .nothing };
define just x = { .case v -> v .just x };
define delay v ->
-- Carefully written to avoid holding onto v for too long.
-- Needs let rec cell = etc. to avoid the initial cell.set!
let cell = ref ();
do cell.set { let forced = v ();
do cell.set { forced };
forced };
{ msg -> cell.get () msg };
Lazy map:
define s:lazymap stream fn ->
delay {stream .s:case {
.s:empty -> s:empty;
.s:next(head, tail) = s:cons(delay {fn(head)}, delay {s:map tail fn});
}};