I recently got in possession of a copy of "Essentials of Programming Languages", second edition. At page 29, the book introduces the following Scheme-flavored grammar for lambda calculus:
<expression> ::= <identifier>
::= (lambda (<identifier>) <expression>)
::= (<expression> <expression>)
It then proceeds to introduce a definition (Definition 1.3.3, page 31) for free and bound variables, which reads:
A variable x occurs free in a lambda calculus expression E if and only if
1. E is a variable reference and E is the same as x; or
2. E is of the form (lambda (y) E'), where y is different from x and x occurs free in E'; or
3. E is of the form (E1 E2) and x occurs free in E1 or E2.
A variable x occurs bound in a lambda calculus expression E if and only if
1. E is of the form (lambda (y) E'), where x occurs bound in E' or x and y are the same variable and y occurs free in E'; or
2. E is of the form (E1 E2) and x occurs bound in E1 or E2.
Such a definition is then readily transformed in two Scheme procedures, named, resp., occurs-free?
and occurs-bound?
:
(define occurs-free?
(lambda (var exp)
(cond
((symbol? exp) (eqv? exp var))
((eqv? (car exp) 'lambda)
(and (not (eqv? (caadr exp) var))
(occurs-free? var (caddr exp))))
(else (or (occurs-free? var (car exp))
(occurs-free? var (cadr exp)))))))
(define occurs-bound?
(lambda (var exp)
(cond
((symbol? exp) #f)
((eqv? (car exp) 'lambda)
(or (occurs-bound? var (caddr exp))
(and (eqv? (caadr exp) var)
(occurs-free? var (caddr exp)))))
(else (or (occurs-bound? var (car exp))
(occurs-bound? var (cadr exp)))))))
One would expect occurs-bound?
to return #t
when combinators (i.e., procedures only consisting of bound variables) are fed as input. However, the test fails for the K combinator:
> (occurs-bound? 'x '(lambda (c) (lambda (x) c)))
#f
This is because point 1. in the definition of bound variables, which states that for a variable to be bound it must be both quantified in a lambda and later appear free in its body. Sincex
is ignored in the body of the inner lambda, the test returns false.
Apparently, occurs-bound?
is not presented in the third edition, so it is not possible to make any comparison with the most recent edition of the book.
Is the above definition flawed, or am I missing something? Here's a repl for the code.
Thank you