;; ------------------------------------------------------------------- ;; Exploring the idea of an infinite list in Racket (Session 23) ;; ------------------------------------------------------------------- #lang racket ;; ------------------------------------------------------------------- ;; Many infinite lists can be generated from single values. ;; ;; My idea is to represent such lists as a Racket *pair*: ;; - a *value* (the first member of the list) ;; - a *function* (how to generate the next member of the list) ;; ;; This allows us to defer creating values after the first ;; until the user requests them. ;; ;; first can return the value at the front of a pair. ;; rest has to return... a new pair! ;; ;; (Remember: a list is a pair whose cdr is a list.) ;; ------------------------------------------------------------------- (define infinite-list cons) (define first car) (define (rest inf-list) (let ((previous-value (car inf-list)) (generate-next (cdr inf-list))) (let ((next-value (generate-next previous-value))) (cons next-value generate-next)))) ;; ------------------------------------------------------------------- ;; some examples of infinite lists in this style ;; ------------------------------------------------------------------- (define integers ; Notice how this matches the BNF (infinite-list 0 add1)) ; definition for the integers! (define evens (infinite-list 0 (lambda (n) (+ n 2)))) (define squares (infinite-list 1 (lambda (previous) (let ((n (+ (sqrt previous) 1))) (* n n))))) ;; ------------------------------------------------------------------- ;; I used this handy utility in class to compose 'rest' as many times ;; as I wanted, in order to show that an infinite list is infinite -- ;; or at least long enough to exhaust my garbage collector. :-) ;; ------------------------------------------------------------------- (define (compose* f n) (if (zero? n) (lambda (x) x) (lambda (x) (f ((compose* f (sub1 n)) x))))) (define (skip n) (compose* rest n)) ;; ------------------------------------------------------------------- ;; Another way to show that infinite lists are arbitrarily long: take. ;; ------------------------------------------------------------------- ;; a simple take function ;; (define (take n lst) ;; (if (or (zero? n) (null? lst)) ;; '() ;; (cons (first lst) ;; (take (sub1 n) (rest lst))))) ;; ------------------------------------------------------------------- ;; a way to create a take function using specific first and rest fxns (define (take-using first rest) ; This function receives as arguments the list accessors ; to use in 'take' ... (letrec ((take (lambda (n lst) (if (or (zero? n) (null? lst)) '() (cons (first lst) (take (sub1 n) (rest lst))))))) ; ... and returns a 'take' function that uses them. take)) ;; (define take (take-using car cdr)) ; original take ;; (take 5 '(1 2 3 4 5 6 7 8 9 10)) ;; (define take (take-using first rest)) ; infinite take ;; (take 10 integers) ;; (take 15 evens) ;; (take 20 squares) ;; (take 500 squares) ;; (take 10 ((skip 1278714) evens)) ;; -------------------------------------------------------------------