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 twiceTo 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 memorization4.30
displayis a primitive function, so Ben is right.- with original version,
(p1 1) = (1,2)and(p2 1) = 1while 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.