UP | HOME

Lazy Sequences

Lazy sequences through closures. Based on extempore_lang.xtm.

;; this leaks memory :(
(bind-type seq <i64,seq*>)

(bind-func cons:[seq*,i64,seq*]*
  (lambda (a:i64 s:seq*)
    (let ((new_s:seq* (halloc))) ; should this be halloc?
      (tset! new_s 0 a)
      (tset! new_s 1 s)
      new_s)))

(bind-func print-seq:[i64,seq*]*
  (lambda (a:seq*)
    (if (= null (cast a i8*))
        (begin
          (printf "x\ndone\n")
          1)
        (begin
          (printf "%d > " (tref a 0))
          (print-seq (tref a 1))))))

(bind-func test-seq
  (lambda ()
    (print-seq (cons 1 (cons 6 (cast null seq*))))))

($ (test-seq))

(bind-type lazy-seq <i64,[lazy-seq*]*>)

(bind-func car:[i64,lazy-seq*]*
  (lambda (s:lazy-seq*)
    (tref s 0)))

(bind-func cdr:[lazy-seq*,lazy-seq*]*
  (lambda (s:lazy-seq*)
    ((tref s 1)))) ; note the double parens for call

(bind-func repeat:[lazy-seq*,i64]*
  (lambda (e:i64)
    (let ((s:lazy-seq* (alloc)))
      (tset! s 0 e)
      (tset! s 1 (lambda () (repeat e)))
      s)))

(bind-func take:[seq*,i64,lazy-seq*]*
  (lambda (n:i64 ls:lazy-seq*)
    (let ((first:i64 (car ls))
          (rest:lazy-seq* (cdr ls)))
      (if (or (= null (cast rest i8*))
              (= n 1))
          (cons first (cast null seq*))
          (cons first (take (- n 1) rest))))))

($ (print-seq (take 10 (repeat 5))))