Exercise 2.8

いちおう試験にはパス。問題に compare this version to the original solution とあるので確認してみることに。
{bound, free}-vars についてはそんなに差は無いです。1.19 の bound-vars が以下。

(define bound-vars
  (lambda (exp)
    (let inner ((l (enum-filter-vars exp)))
      (if (null? l)
	  '()
	  (if (occurs-bound? (car l) exp)
	      (cons (car l) (inner (cdr l)))
	      (inner (cdr l)))))))

で、2.8 の bound-vars が以下。

(define bound-vars
  (lambda (exp)
    (let inner ((l (enum-filter-vars exp)) (i-exp (parse-expression exp)))
      (if (null? l)
	  '()
	  (if (occurs-bound? (car l) i-exp)
	      (cons (car l) (inner (cdr l) i-exp))
	      (inner (cdr l) i-exp))))))

lambda な式を parse して abstract syntax に変換しなきゃいけなくて、それを inner でも持ち回ってます。差分については free-vars も同様。
そーゆー意味では

(bound-vars (parse-expression '(lambda (x) x)))

みたいにすれば実装はそのまんまで OK だったりするのか。とは言え、occurs-{bound, free}? については abstract-syntax な実装である必要はありますが。
抽象化、という観点においてなかなかに面白い問題だなと。