Functional Arguments (defun map (FUN X) (cond ((null X) X) (t (cons (FUN (first X)) (map FUN (rest X)))) ) ) applies function FUN to each element of the list X and returns a list of the results
Funarg Problem (defun consall (X YS) (map '(lambda (y) (cons X y)) YS)) (consall 'BEAT '(HARVARD YALE)) we expect to get: ((BEAT HARVARD) (BEAT YALE)) we actually get: ((HARVARD YALE) HARVARD) ((YALE) YALE))
Why? Because (lambda (y) (cons X y))
is called within map, which binds X to the second argument: (defun map (FUN X) (cond ((null X) X) (t (cons (FUN (first X)) (map FUN (rest X)))))) which in the first call is (HARVARD YALE) and in the second is (YALE)
15
4/20/2010
Solution: closure Capture the environment with the FUNCTION operator: (defun consall (X YS) (map (function (lambda (y) (cons X y)) YS))) with: (consall ‘BEAT '(HARVARD YALE)) we actually get: ((BEAT HARVARD) (BEAT YALE))
Dialect of Lisp that adopted lexical scoping (from Algol 60) and turned all functions into
lexical closures, thereby avoiding to explicitly use FUNCTION
Lexical scoping allows determining which free variables are used in a function and hence avoiding to store the whole environment
17
4/20/2010
Meta Programming
Lisp macros are the most powerful
They provide access to the program code itself, represented as a list and can manipulate it with the full language power (typical macro processors for instance do not allow recursion)
Macros: extending the language Function are not enough. Trying defining if: (defun if (test then else)
Defmacro (defmacro if (test then else) (list 'cond (list test then) (list t else))) A macro is dealt specially by eval: it applies the macro to the argument expressions, and then it evaluates the resulting expression. For example:
(if (= x 0) infinity (/ 1 x)) => (cond ((= x 0) infinity) (t (/ 1 x)))
19
4/20/2010
HTML Templates
HTML templates or Web scripting languages adopt an opposite convention everything is constant except when escaped