The following is an excerpt from the SICP book, Section 4.2.3 Streams as Lazy Lists:
With lazy evaluation, streams and lists can be identical, so there is no need for special forms or for separate list and stream operations. All we need to do is to arrange matters so that
cons
is non-strict. One way to accomplish this is to extend the lazy evaluator to allow for non-strict primitives, and to implementcons
as one of these. An easier way is to recall (section 2.1.3) that there is no fundamental need to implementcons
as a primitive at all. Instead, we can represent pairs as procedures:(define (cons x y) (lambda (m) (m x y))) (define (car z) (z (lambda (p q) p))) (define (cdr z) (z (lambda (p q) q)))
Question: I don't see how the above definition of cons
achieves lazy or non-strict behavior. For example, the following call to cons
,
(define (foo) '(1 2 3))
(define bar (cons 'a (foo)))
does result in the invocation of foo
at the point cons
is called, which is a non-lazy or strict behavior.
So, how would we write a lazy or non-strict version of cons
that is also not a special form.
delay
andcons-stream
- the authors say - had to be necessarily used. This made it sound as if the authors are trying to get rid of special forms OUTSIDE of the evaluator in the current section 4.2.3. – Harry