sicp-4-2-1
Posted on 2015-03-11 19:20:01 +0900 in SICP
4.25
(define (unless condition usual-value exceptional-value)
(if condition exceptional-value usual-value))
(define (factorial n)
(unless (= n 1)
(* n (factorial (- n 1)))
1))
In applicative-order, factorial
will enter an infinite loop, as
the exceptional-value
is evaluated regardless the condition
.
While in normal-order, the condition
is judged before exceptional-value
is evaluated.
4.26
(define (unless? exp) (tagged-list? exp 'unless))
(define (unless-clauses exp) (cdr exp))
(define (unless-condition clauses) (car clauses))
(define (unless-usual-value clauses) (cadr clauses))
(define (unless-exceptional-value clauses) (caddr clauses))
(define (unless->if exp)
(expand-unless-clauses (unless-clauses exp)))
(define (expand-unless-clauses clauses)
(make-if (unless-condition clauses)
(unless-exceptional-value clauses)
(unless-usual-value clauses)))
It would fail if unless
is passed as parameter, as there is no such
procedure.
4.27
(define count 0)
(define (id x)
(set! count (+ count 1))
x)
(define w (id (id 10)))
;;; L-Eval input:
count
;;; L-Eval value:
1
;;; L-Eval input:
w
;;; L-Eval value:
10
;;; L-Eval input:
count
;;; L-Eval value:
2
(define w (id (id 10)))
will cause the outer id
being force, (id 10)
is not evaluated and being returned as a thunk.
The evaluation of w
forces the inner id
being forced.
4.28
I think it would cause trouble if the operator
is a thunk instead of actual procedure.
In order to make the operator
be a thunk, the easiest way is to pass the procedure as a parameter.
such as:
(define (g x) (+ x 1))
(define (f g x) (g x))
(f g 10)
4.29
;;; L-Eval input:
(square (id 10))
;;; L-Eval value:
100
;;; L-Eval input:
count
;;; L-Eval value:
1 ; with memorization, (id 10) is called once.
2 ; without memorization, (id 10) is called twice
To test the efficiency, simillar to the 4.24
problem.
(eval '(define (factorial n)
(if (= n 1)
1
(* (factorial (- n 1)) n))) the-global-environment)
(let ((t0 0) (t1 0))
(define (loop i n)
(eval '(factorial 1234) the-global-environment)
(if (< i n)
(loop (+ i 1) n)))
(set! t0 (runtime))
(loop 0 1)
(set! t1 (runtime))
(- t1 t0))
;9.864471 second without memorization
;0.027408 second with memorization
4.30
display
is a primitive function, so Ben is right.- with original version,
(p1 1) = (1,2)
and(p2 1) = 1
while in Cy’s version, both of them would be(1, 2)
.
(define (p2 x)
(define (p e)
e
x)
(p (set! x (cons x '(2)))))
(set! x (cons x '(2)))
is passed in as a thunk parameter e
of the internal p
procedure in the
original version and is not forced as it is not passed to a primitive procedure.
- Obviously.
- I prefer the text’s. As lazy evalution is better not involved with side effects.