- the parameters of a lambda expression must be distinct
- variables must be properly bound

(define-record Var (name)) (define-record Const (value)) (define-record Lam (formals body)) (define-record Ap (fun args))Let us define a procedure

`check`

that determines if the parameters
of every lambda expression in a program are distinct.
(define check (lambda (e) (cond ((Const? e) #t) ((Var? e) #t) ((Lam? e) (and (check-unique (Lam->formals e)) (check (Lam->body e)))) ((Ap? e) (and (check (Ap->fun e)) (andmap check (Ap->args e))))))) (define andmap (lambda (f l) (if (null? l) #t (and (f (car l)) (andmap f (cdr l)))))) (define check-unique (lambda (names) (if (null? names) #t (and (not (member (car names) (cdr names))) (check-unique (cdr names))))))We can use the syntactic form

`variant case`

to furhter simplify
`check`

.
(define check (lambda (e) (variant-case e (Const (value) #t) (Var (name) #t) (Lam (formals body) (and (check-unique formals) (check body))) (Ap (fun args) (and (check fun) (andmap check args))))))

`(+ 1 2)`

is not necessarily equal to
3. The reason is that `+`

may be locally bound. For example,
consider
((lambda (+) (+ 1 2)) -)This expression appears to yield -1, but again

`-`

might be
locally bound. Now what about:
(lambda (+) +)This is an identity function, no matter where it appears in a program.

Certain constructs of any programming language are binders. The Scheme contructs that are binders are:

- lambda
- let
- let*
- lectrec
- define

(lambda (x) e) ^ (let ((x e)) e) ^A

(lambda (a) (a (lambda (a) a) a)) 1 2 3 4 5Occurrences 1 and 3 are binding occurrences, while 2, 4, 5 are bound occurrences. Uses 2 and 5 refer to binding 1, while use 4 refers to binding 3.

The ** scope of a binding**
is the region of text within its binder minus any regions which bind
the same name. The

x occurs free in e if and only if

e = x OR x = (lambda (y[1] ... y[n]) e') and x occurs free in e' and x not in any y[i] OR x = (e[0] e[1] ... e[n]) and x occurs free in at least one of e[i]Based on this definition we can write occurs-free.

(define occurs-free? (lambda (e x) (variant-case e (Var (name) (equal? name x)) (Lam (formals body) (and (occurs-free? body x) (not (member x formals)))) (Ap (fun args) (or (occurs-free? fun x) (ormap (occurs-free? (lambda (a) (occurs-free? a x)) args)))))))

x occurs bound in e if and only if

e = (lambda (y[1] ... y[n]) e') and x = y[i] for some i or x occurs bound in e' OR (e[0] e[1] ... e[n]) and x occurs bound in at least one e[i]

- Write occurs-bound?
- Build an implementation of sets of symbols that supports
- make-empty
- union
- element-of?
- difference
- list->set
- set->list

- Define FV (free vars) and BV (bound vars)