SICP問題4.23

一ヶ月ぶり。
二つの版の違いは既に本文および問題中に書かれている。
本文版の方は

これらの実行手続きを組み合わせ、環境を引数としてとり、個々の実行手続きを環境を引数として順に呼び出す一個の実行手続きを作る

という動作なのに対し、Alyssa版の方は

実際は、並びの個々の式は、解析されるが、並び自身は解析されない。

という動作となっている。

以下の要領でリーダーマクロをつけて実行してみる。
本文版

(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))))

引数が1つの場合の場合の実行結果。以下の要領で実行。

(analyze-sequence '((+ 1 1)))

本文版

#?="(stdin)":147:(loop (car procs) (cdr procs))
#?="(stdin)":140:(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版

#?="(stdin)":162:(lambda (env) (execute-sequence procs env))
#?-    #<closure (analyze-sequence analyze-sequence)>
#<closure (analyze-sequence analyze-sequence)>

本文版の方は

(解析された(+ 1 1))

を返す。
Alyssa版の方は

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

を返す。

引数が2つの場合の場合の実行結果。以下の要領で実行。

(analyze-sequence '((+ 1 1) (+ 1 2)))

本文版

#?="(stdin)":147:(loop (car procs) (cdr procs))
#?="(stdin)":140:(if (null? rest-procs) first-proc (loop (sequentially first-p ...
#?="(stdin)":138:(lambda (env) (proc1 env) (proc2 env))
#?-    #<closure (analyze-sequence sequentially sequentially)>
#?="(stdin)":140:(if (null? rest-procs) first-proc (loop (sequentially first-p ...
#?-    #<closure (analyze-sequence sequentially sequentially)>
#?-    #<closure (analyze-sequence sequentially sequentially)>
#?-    #<closure (analyze-sequence sequentially sequentially)>
#<closure (analyze-sequence sequentially sequentially)>

Alyssa版

#?="(stdin)":162:(lambda (env) (execute-sequence procs env))
#?-    #<closure (analyze-sequence analyze-sequence)>
#<closure (analyze-sequence analyze-sequence)>

本文版の方は

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

を返す。
Alyssa版の方は

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

を返す。
Alyssa版の方は問題文にあるとおりexecute-sequenceつまり並び自身が解析されていない。この節では解析と評価の分離を目的としていたため、これだと良くない。