2015/12/25
SICP4章 真理値のせいではまった.
(define (append x y)
(if (null? x)
y
(cons (car x)
(append (cdr x) y))))
これが動かなかったんですよ.
はじめはeval-sequenceで(first-exp exp)をevalしていなかったとかそういうのだったんですけど,
どうしても動かなくて.
debug printでも(null? x)が#fになってるのになぜかyが返ってくるんです.
eval-ifはtrue?で真偽が決まります.
(define (eval-if exp env)
(if (true? (eval (if-predicate exp) env))
(eval (if-consequent exp) env)
(eval (if-alternative exp) env)))
(define (true? x)
(not (eq? x 'false)))
(define (false? x)
(eq? x 'false))
(define (setup-environment)
(let ((initial-env
(extend-environment (primitive-procedure-names)
(primitive-procedure-objects)
the-empty-environment)))
(define-variable! 'true true initial-env)
(define-variable! 'false false initial-env)
initial-env))
散々迷ってここが原因だとわかりました.
SICPでは#tや#fじゃなくてtrue,falseになっています.
他のコードも統一するために
(define true #t)
(define false #f)
としていたのが裏目にでました.
ここで作ったdebug printで#fとなっていてもこの評価器はtrueを返しているというややこしいことになっていました.
eval-ifも間違っていない.選択子も正しくできている.
null?も問題ない.(null? x)のxはきちんと'(a b c)に束縛されている.
可能性を全部潰してやっとここに行き着きました.
全部を#tと#fに統一してやっと解決しました.
これは辛かった.
(define (true? x)
(not (eq? x '#f)))
(define (false? x)
(eq? x '#f))
(define (setup-environment)
(let ((initial-env
(extend-environment (primitive-procedure-names)
(primitive-procedure-objects)
the-empty-environment)))
(define-variable! '#t #t initial-env)
(define-variable! '#f #f initial-env)
initial-env))
超循環評価器はこういう時厳しいですね.