----------------------------------------------------------------------
-- This sample shows a simple usage of the lazy extesnion, by
-- implementing lazy streams and using them to generate the stream of
-- primes through a variant of Eratosthenes' sieve.
--
-- It also uses the ternary choice operator [c ? x, y], equivalent
-- to C and C++'s "c?x:y".
--
-- [map(f,s)] lazily maps function [f] on a stream [s]
--
-- [filter(p,s)] lazily filters out elements of stream [s] for which 
-- predicate [p] returns false or nil.
--
-- [take(n,s)] returns the [n] first elements of stream [s] in a table.
--
-- [ints] is the stream of natural integers
--
-- [primes] is the stream of all prime numbers, computed thanks to
-- auxiliary function [f]. 
----------------------------------------------------------------------

-{ extension "lazy" }
-{ extension "ternary" }

map    = |f,x| x ? %{ hd=f(x.hd), tl=map(f,x.tl) }
filter = |p,x| x ? p(x.hd) ? %{ hd=x.hd, tl=filter(p, x.tl) }, filter(p, x.tl)
take   = |n,s| n<=0 ? { }, { s.hd, unpack(take(n-1, s.tl)) }
ints   = %{ hd=1; tl=map (|x| x+1, ints) }

f = |seq| %{ hd=seq.hd; tl=f(filter (|x| x%seq.hd~=0, seq.tl)) }
primes = f (ints.tl)

table.print(take (100, primes))