EoPL reading (20) 1.3.1 Free and Bound Variables

とりあえず仕事対応しつつ以下な試験を追加。

(test* "(free-vars '(lambda (x) (x))) should return ()"
       '()
       (free-vars '(lambda (x) (x))))
(test* "(free-vars '(lambda (x) (x 1 2 3))) should return ()"
       '()
       (free-vars '(lambda (x) (x 1 2 3))))
(test* "(free-vars '(lambda (x) ()) should return ()"
       '()
       (free-vars '(lambda (x) ())))
(test* "(free-vars '(lambda () (x)) should return ()"
       '(x)
       (free-vars '(lambda () (x))))

上記追加にて全部の分岐を通過しているはずなんですがどうなんだろ。と言いつつ以下が足らない? ということで追加。

(test* "(free-vars '(lambda () ((x) (y))) should return (x y)"
       '(x y)
       (free-vars '(lambda () ((x) (y)))))

試験にパスしません。

$ make
Testing free-vars ...                                            failed.
discrepancies found.  Errors are:
test (free-vars '(lambda () ((x) (y))) should return (x y): expects (x y) => got (y x)
$

あ、ここだ。

	  (if (pair? (car l))
	      (f (f rslt (car l)) (cdr l))

もしかして逆? あ、違うや。こっち?

	  (if (pair? (car l))
	      (f (f rslt (car l)) (cdr l))
	      (let ((ret (free-symbol (car l))))
		(f (if (and (null? ret) (symbol? (car l)))
		      (cons (car l) rslt)
		       rslt)
		   (cdr l)))))
      )

cons のあたりがクサい。簡単なのは append なんですが。最初こんなカンジで失敗。

		      (append (list (car l)) rslt)

逆にすればええの? と言いつつ以下で試験パス。あたりまえ。

		      (append rslt (list (car l)))

微妙。