2015/12/31

SICP 問題 4.23

本文中のanalyze-sequenceと問題文のanalyze-sequenceの比較.
リーダーマクロを使って実行する.
本文のanalyze-sequence

(define (analyze-sequence exps)
  (define (sequentially proc1 proc2)
    #?=(lambda (env)
         (proc1 env)
         (proc2 env)))
  (define (loop first-proc rest-procs)
    #?=(if (null? rest-procs)
           first-proc
           (loop (sequentially first-proc (car rest-procs))
                 (cdr rest-procs))))
  (let ((procs (map analyze exps)))
    (if (null? procs)
        (error "Empty sequence: ANALYZE")
        #?=(loop (car procs) (cdr procs)))))

Alyssa P.Hacker版

(define (analyze-sequence exps)
  (define (execute-sequence procs env)
    #?=(cond ((null? (cdr procs)) ((car procs) env))
          (else ((car procs) env)
                (execute-sequence (cdr procs) env))))
  (let ((procs (map analyze exps)))
    (if (null? procs)
        (error "Empty sequence -- ANALYZE"))
    #?=(lambda (env) (execute-sequence procs env))))

(analyze-sequcence '(+ 1 1))を実行した結果
本文版

gosh> (analyze-sequence '((+ 1 1)))
#?="(standard input)":3192:(loop (car procs) (cdr procs))
#?="(standard input)":3185:(if (null? rest-procs) first-proc (loop (sequentially first-p ...
#?-    #<closure (analyze-application analyze-application)>
#?-    #<closure (analyze-application analyze-application)>
#<closure (analyze-application analyze-application)>

Alyssa版 

gosh> (analyze-sequence '((+ 1 1)))
#?="(standard input)":3215:(lambda (env) (execute-sequence procs env))
#?-    #<closure (analyze-sequence analyze-sequence)>
#<closure (analyze-sequence analyze-sequence)>

本文版は(解析された (+ 1 1))を返す. Alyssa版は
(lambda (env) (execute-sequence (解析された (+ 1 1) env))を返す.     
次に(analyze-sequence '((+ 1 1) (+ 2 2)))を実行する.

本文版

gosh> (analyze-sequence '((+ 1 1) (+ 2 2)))
#?="(standard input)":3258:(loop (car procs) (cdr procs))
#?="(standard input)":3251:(if (null? rest-procs) first-proc (loop (sequentially first-p ...
#?="(standard input)":3247:(lambda (env) (proc1 env) (proc2 env))
#?-    #<closure ((analyze-sequence loop) sequentially)>
#?="(standard input)":3251:(if (null? rest-procs) first-proc (loop (sequentially first-p ...
#?-    #<closure ((analyze-sequence loop) sequentially)>
#?-    #<closure ((analyze-sequence loop) sequentially)>
#?-    #<closure ((analyze-sequence loop) sequentially)>
#<closure ((analyze-sequence loop) sequentially)>

Alyssa版

gosh> (analyze-sequence '((+ 1 1) (+ 2 2)))
#?="(standard input)":3269:(lambda (env) (execute-sequence procs env))
#?-    #<closure (analyze-sequence analyze-sequence)>
#<closure (analyze-sequence analyze-sequence)>

本文版は

(lambda (env) ((解析された (+ 1 1)) env) ((解析された (+ 2 2)) env))

を返す.
 
Alyssa版は

(execute-sequence ((解析された (+ 1 1)) (解析された (+ 2 2))) env)

を返す.
 
本文版は並びが解析されenvを受け取って評価するlambdaが返される. Alyssa版では並びが解析されていない.execute-sequenceが解析の外で並びを表している.
解析と評価を分けるという趣旨に反するのでこれではいけない.


© 2022 wat-aro