SICP 読み (141) 4.1.2 式の表現

問題 4.4

む。これ難しいぞ。

(cond ((and? exp) (eval-and exp env))
      ((or? exp) (eval-or exp env)))

な形を取るのが前提とすると、どうすりゃ良いのか。
と思ったんですが一番 easy な解としては以下か。

(define (eval-and exp env)
  (define (eval-and-iter predicates env)
    (if (true? (eval (car predicates) env))
	(if (null? (cdr predicates))
	    true
	    (eval-and-iter (cdr predicates) env))
	false))
  (eval-and-iter (cdr exp) env))

戻すのは quote した方が良いのかなぁ。上記をビンゴとしたら or は以下か。って今さら問題読んだら上記はダウトじゃん。

(define (eval-and exp env)
  (define (eval-and-iter predicates env)
    (let ((ret (eval (car predicates) env)))
      (if (true? ret)
	  (if (null? (cdr predicates))
	      ret
	      (eval-and-iter (cdr predicates) env))
	  false)))
  (eval-and-iter (cdr exp) env))

これじゃ駄目だな。ちなみに gauche な評価は以下。

gosh> (and)
#t
gosh> (and '())
()
gosh> (and (+ 1 1))
2
gosh> (and (+ 1 1) (+ 1 2))
3
gosh> (and (+ 1 1) #f)
#f
gosh> 

false? って聞かないと駄目みたい。ならこうか。

(define (eval-and exp env)
  (define (eval-and-iter predicates env)
    (let ((ret (eval (car predicates) env)))
      (if (false? ret)
	  false
	  (if (null? (cdr predicates))
	      ret
	      (eval-and-iter (cdr predicates) env)))))
  (eval-end-iter (cdr exp) env))

む、これって一発目はどうなるのかな。面倒見ないとイカンのであれば以下??

(define (eval-and exp env)
  (define (eval-and-iter predicates env)
    (let ((ret (eval (car predicates) env)))
      (if (false? ret)
	  false
	  (if (null? (cdr predicates))
	      ret
	      (eval-and-iter (cdr predicates) env)))))
  (if (null? (cdr exp))
      true
      (eval-and-iter (cdr exp) env)))

これビンゴで or は以下で OK かなあ (面倒になってきてたり

(define (eval-or exp env)
  (define (eval-or-iter predicates env)
    (let ((ret (eval (car predicates) env)))
      (if (true? ret)
	  ret
	  (if (null? (cdr predicates))
	      false
	      (eval-or-iter (cdr predicates) env)))))
  (if (null? (cdr exp))
      false
      (eval-or-iter (cdr exp) env)))

で、この and とか or を導出された式として評価って一体。(つづく

つづき

これは if にせざるを得ないよなぁ。(本当か
例えば

(and (= x 1) (= y 2) (= z 3))

なら

(let ((x1 (= x 1)))
  (if (not x1)
      false
      (let ((x2 (= y 2)))
	(if (not x2)
	    false
	    (let ((x3 (= z 3)))
	      (if (not x3)
		  false
		  x3))))))

な if を作れば良い。ってなんか面倒だなぁ。
一瞬、and と or の別解がありそうに思ったんですが、違うのか。

あるいは or な場合だと

(or (= x 1) (= y 2) (= z 3))

(let ((x1 (= x 1)))
  (if x1
      x1
      (let ((x2 (= y 2)))
	(if x2
	    x2
	    (let ((x3 (= z 3)))
	      (if x3
		  x3
		  false))))))

なの??

ってーか_導出された式として評価する方法_って何だ。(を

さらにつづき

手続きを書かんと駄目みたい?ここまで分かってりゃ、という話もあるな。次 (EoPL) があるようなんで、もう少しがしがし進めたいんですがどうなるか。