EoPL 読んでた記録の確認とその記録 (6)

今週は再び台風も接近しつつある中、色々と大変らしいのですが、昨晩同様気分転換に EoPL なナニでもごもごしようと思ってます。

とりあえず

Ex.1.19 から着手。free-vars とか bound-vars を書け、とのこと。occurs-free? とか occurs-bound? の試験も書いてはみたいですが時間無いんで別途。
いずれも変数を数えあげるナニを上手にでっち上げれば何とかなりそげなのですが、どうするか。ちなみに現状の occurs-{free, bound}? は

  • lambda の引数は一つ
  • application なリストの要素は二つ
  • lambda の中に lambda がある事は想定外

つうか基本リストになってるから順に数えあげて不要なソレはスルーすりゃ良いのか。あと、前提としてリテラルは範疇外って事にします。また、重複分は数えあげた後に filter だな。
で、一部パクリで enum と filter なソレができた。

(use srfi-1)

(define enum-filter-vars
  (lambda (exp)
    (delete-duplicates (flatten (enum-vars exp)))))

(define enum-vars
  (lambda (exp)
    (cond
     ((null? exp) '())
     ((symbol? exp) exp)
     ((eqv? (car exp) 'lambda)
      (enum-vars (cddr exp)))
     (else
      (cons (enum-vars (car exp))
	    (enum-vars (cdr exp)))))))

(define (flatten xs)
  (if (pair? xs)
      (append-map flatten xs)
      (list xs)))

あまり自分で考えないあたりが微妙な所以なのだろうな。試験は以下。

(use gauche.test)
(add-load-path ".")
(load "enum-vars")

(test-start "enum-vars")
(test-section "enum-filter-vars")
(test* "application"
       '(a)
       (enum-filter-vars '((lambda (a) a) a)))

(test-section "enum-vars")
(test* "null"
       '()
       (enum-vars '()))
(test* "symbol"
       '(a)
       (enum-vars '(a)))
(test* "lambda exp"
       '(a)
       (enum-vars '(lambda (a) a)))
(test* "application"
       '((a) b)
       (enum-vars '((lambda (a) a) b)))

(test-end)

少ないですがヤッツケ対応ってことでご容赦頂ければとorz
あとは出てきたシンボルなリストと元のリストを使って occurs-{free, bound}? してその結果が #f でなかったもののリストが戻れば良いのか。

継続

そろそろ時間切れなので。
free-vars および bound-vars ができたら、これを abstract-syntax で書きなさい、というのが Ex.2.8 になります。これ、symbol-exp か、って条件で filter すれば良いだけになるはずなので、とても簡単になるはず。
もう少し時間があるのでもごもごするかもしれませんが、とり急ぎエントリ投入。