3

regarding to SICP 3.5

my own implementation is as following

(define (delay exp) (lambda () exp))

(define (force delayed-obj)
  (delayed-obj))

(define (cons-stream a b) (cons a (delay b)))

(define (stream-car stream) (car stream))


(define (stream-cdr stream) (force (cdr stream)))

(define (take n stream) 
  (if (= n 0)
      (print "0")
      (begin (take (- n 1) (stream-cdr stream))
             (print n))))

(define (make-stream-enum-interval low high)
  (if (> low high)
      '()
      (begin (print low) (cons-stream low (make-stream-enum-interval (+ low 1) high)))))

actually I found it's not really delayed. when I execute (define range-10-to-100 (make-stream-enum-interval 10 100)). I expect to see only 10 is print in the console. while it's 10.....100

is there anything wrong with my code? Or, if print 10...100 is necessary, then we can say the structure is (cons 10 (delay cons 11 (delay cons 12 (delay ....100))) if so, then we need more memory?

user3754786
  • 57
  • 1
  • 6

1 Answers1

9

Scheme uses eager evaluation. That means that all arguments to a function call are evaluated before the function is entered. Thus, since your delay was a function, expressions passed to delay get evaluated first.

To get around this, make delay a macro, as does anything that uses it (like cons-stream). Here's a reformulation of your delay and cons-stream as macros:

(define-syntax delay
  (syntax-rules ()
    ((_ exp) (lambda () exp))))

(define-syntax cons-stream
  (syntax-rules ()
    ((_ a b) (cons a (delay b)))))
C. K. Young
  • 219,335
  • 46
  • 382
  • 435