;; lazy pairs. can be used to construct lazy lists (generators) ;; 1. uses promises instead of thunks ;; 2. a lazy list is abstract ;; i'm not using thunks, to avoid undesired effects of multiple ;; evaluations for non-functional things ;; both parts are delayed, instead of only the cdr, so lazy trees can ;; be constructed. ;; constructor needs to be syntax to properly delay evaluation of the ;; arguments. ;; i'm using the prefix '@' to indicate that a function is the lazy ;; variant of some other nown list processor. this is the closest ;; approximation i could find to something resembling 'infinity'. a ;; spiral will do fine.. (define-syntax @cons (syntax-rules () ((_ a b) (delay (cons a b))))) (define (@car lst) (car (force lst))) (define (@cdr lst) (cdr (force lst))) ;; lazy list from strict list (define (@list . lst) (if (null? lst) '() (@cons (car lst) (apply @list (cdr lst))))) ;; finite lazy list for 'for' loops (define (@countdown n) (if (zero? n) '() (@cons n (@countdown (- n 1))))) ;; create a stream from an iterated function (define (@iterated fn init) (@cons init (@iterated fn (fn init)))) ;; the natural numbers (define (@natural n) (@iterated inc n)) ;; cannot define this in terms of a @fold, since kons is syntax (define (@map fn . lazy-lists) (let rest ((lsts lazy-lists)) (@cons (apply fn (map @car lsts)) (rest (map @cdr lsts))))) ;; tranforms a lazy list into one with a running average using an ;; accumulator function. should it take more than one argument? that's ;; just convenience. it's always possible to use lists and apply.. (define (@integral fn init lst) (let ((out (fn (@car lst) init))) (@cons out (@integral fn out (@cdr lst)))))