EoPL reading (23) 1.3.1 Free and Bound Variables
エントリを改めます。以下な試験を追加したところ
(test-section "ut") (test* "(occurs-free? 'y 'y) should return #t" #t (occurs-free? 'y 'y)) (test* "(occurs-free? 'x 'y) should return #f" #f (occurs-free? 'x 'y)) (test* "(occurs-free? 'x '(lambda (x) ())) should return #f" #f (occurs-free? 'x '(lambda (x) ()))) (test* "(occurs-free? 'x '(lambda (x) x)) should return #t" #t (occurs-free? 'x '(lambda (x) x))) (test* "(occurs-free? 'x '(lambda (x) y)) should return #f" #f (occurs-free? 'x '(lambda (x) y)))
結果が微妙。
<ut>--------------------------------------------------------------------------- test (occurs-free? 'y 'y) should return #t, expects #t ==> ok test (occurs-free? 'x 'y) should return #f, expects #f ==> ok test (occurs-free? 'x '(lambda (x) ())) should return #f, expects #f ==> ok test (occurs-free? 'x '(lambda (x) x)) should return #t, expects #t ==> ERROR: GOT #f test (occurs-free? 'x '(lambda (x) y)) should return #f, expects #f ==> ok
あら、free だから #f で良いのか、てーコトは最後のが #t なのが微妙? あるいは 3 番目もか。そうか lambda 式の引数に var と同じシンボルがあったらダウトですね。
使われてなくても定義があれば occurs free ではないのか。で、以下を追加。
(test* "(occurs-free? 'x '(lambda (y) y)) should return #f" #f (occurs-free? 'x '(lambda (y) y))) (test* "(occurs-free? 'x '(lambda (y) x)) should return #t" #t (occurs-free? 'x '(lambda (y) x)))
あと、失敗してた試験は #f が戻ること、という試験に書き換えてます。書いた試験を日本語に直してみると
- (occurs-free? 'y 'y) は #t を戻すべき
- (occurs-free? 'x 'y) は #t を戻すべき
- (occurs-free? 'x '(lambda (x) ())) は #f を戻すべき
- (occurs-free? 'x '(lambda (x) x)) は #f を戻すべき
- (occurs-free? 'x '(lambda (x) y)) は #f を戻すべき
- (occurs-free? 'x '(lambda (y) y)) は #t を戻すべき
- (occurs-free? 'x '(lambda (y) x)) は #t を戻すべき
よく考えたら最初の_occurs free_の定義は面白い。ってかなんで最後の二つは上手く動くんでしょうか。
なるほど、上記のソレが関係してるのか。結局 lambda の body にて var が使われてないとダメなんだ。かつ引数に var が出現しなければ、という事ッスか。else な試験ってコトで以下を追加。
(test* "(occurs-free? 'x '(lambda (f) (lambda (x) (f x)))) should return #f" #f (occurs-free? 'x '(lambda (f) (lambda (x) (f x))))) (test* "(occurs-free? 'f '(lambda (f) (lambda (x) (f x)))) should return #f" #f (occurs-free? 'f '(lambda (f) (lambda (x) (f x))))) (test* "(occurs-free? 'y '(lambda (f) (lambda (x) (f x)))) should return #f" #f (occurs-free? 'y '(lambda (f) (lambda (x) (f x))))) (test* "(occurs-free? 'y '(lambda (f) (lambda (x) (y x)))) should return #t" #t (occurs-free? 'y '(lambda (f) (lambda (x) (y x)))))
定義を見るに
- lambda 式の引数はシンボル単発のみ許容
- lambda 式の body はシンボル一発又は要素が二つのリストのみ許容
という形なのか。
occurs bound については
明日にします。reading gauche 方面に去ります。余力があれば kernel 方面も。