55 lines
1.7 KiB
Racket
55 lines
1.7 KiB
Racket
;; Lisp code that can be evaluated by the lazy evaluator to implement
|
|
;; lazy lists
|
|
|
|
#lang sicp
|
|
|
|
(#%provide lazy-lists-program)
|
|
|
|
(define lazy-lists-program
|
|
'(
|
|
;; The cons procedure needs to be created once at interpreter
|
|
;; start up. This ensures that it captures only the initial
|
|
;; environment. Then when it is called, that environment is
|
|
;; extended to bind its parameters to the inputs.
|
|
;; Specifically, it doesn't capture the whole environment at
|
|
;; the call site of cons. The latter is what happens if we
|
|
;; create the procedure at the call site. This leads to
|
|
;; excessive memory use.
|
|
;; lazy-lambda-pair produces a specially tagged procedure that is
|
|
;; recognised as a lazy pair by the evaluator but is otherwise
|
|
;; just a normal procedure.
|
|
(define cons
|
|
(lambda (x y)
|
|
(lazy-pair-lambda (m) (m x y))))
|
|
|
|
(define (car z)
|
|
(z (lambda (p q) p)))
|
|
|
|
(define (cdr z)
|
|
(z (lambda (p q) q)))
|
|
|
|
(define (list-ref items n)
|
|
(if (= n 0) (car items)
|
|
(list-ref (cdr items)
|
|
(- n 1))))
|
|
|
|
(define (map proc items)
|
|
(if (null? items) '()
|
|
(cons (proc (car items))
|
|
(map proc (cdr items)))))
|
|
|
|
(define (scale-list items factor)
|
|
(map (lambda (x) (* x factor)) items))
|
|
|
|
(define (add-lists list1 list2)
|
|
(cond ((null? list1) (car list2))
|
|
((null? list2) (car list1))
|
|
(else
|
|
(cons (+ (car list1) (car list2))
|
|
(add-lists (cdr list1)
|
|
(cdr list2))))))
|
|
|
|
(define ones (cons 1 ones))
|
|
|
|
(define integers (cons 1 (add-lists ones integers)))))
|