CS 342 Lecture -*- Outline -*- * Name bindings statically scoped Common LISP follows Scheme in this ** define (define name E) binds name to the value of E, doesn't complain if name already has a binding mutates the environment! (define (name x) E) =def= (define name (lambda (x) E)) shorthand for function definitions. The function's environment includes binding of name, so allows recursion. ---------- (define (my-member x L) (cond ((null? L) '()) ((eq? x (car L)) L) (else (my-member x (cdr L))))) ---------- ** let, simultaneous local bindings (let ((x1 e1) ... (xn en)) E) =def= ((lambda (x1 ... xn) E) (e1 ... en)) simultaneous local binding of names (note that the xi cannot be used in defining the other xj) *work examples* ** let*, sequential local bindings (let* ((x1 e1)) E) =def= (let ((x1 e1)) E) (let* ((x1 e1) ... (xn en)) E) =def= ((lambda (x1) (let* ((x2 e2) ... (xn en)) E)) (e1)) sequential binding of names can use x1 in x2, etc. ** set! (set! id e2) binds value of e2 to variable id, which must be defined (define a #t) (set! a 1) a => 1 must already be defined set! and define both mutate the environment. *** Binding vs. assignment let sets up a binding, does not change existing bindings (assignment) => referential transparency set! makes assignment no referential transparency ** initial environment binds #f to () #t to #t car to "the function that computes car", etc.