CMSC 671 - Fall '10 LISP LECTURE NOTES FOR 9/8/10 Prof. Marie desJardins SIMPLE LISP EXAMPLE (setf x '(1 2 3)) (car x) (setf (car x) 'a) x (length x) ;; APPEND is non-destructive (it creates or "conses up" a new list structure) (append x '(4 5)) x (length x) ;; NCONC is destructive (it modifies the list structure passed into it) (nconc x '(4 5)) x (length x) ;; Macros and special functions can have interesting call-by-reference behavior (setf y 1) (incf y) y ;; You can't incf a non-number! (mapcar #'incf x) ;; ...and you can't mapcar incf because it's a macro, not a function (mapcar #'incf (cdr x)) ;; ...but you can mapcar a lambda function that invokes incf ;; (note that lisp doesn't care that the local variable has the same ;; name as the global variable you've passed in) (mapcar #'(lambda(x) (incf x)) (cdr x)) x ;; ...but then incf isn't destructive in the way you might want it to ;; be, since the lambda function is not a macro ;; More fun and games with lists... (cons 'a x) x (append x '(a)) x (setf x (append x '(a))) (nconc x '(b)) x BASIC LISP PROGRAMMING AND DEBUGGING - FIBONACCI SEQUENCE EXAMPLE -- FIBONACCI SEQUENCE 0 1 1 2 3 5 8 13 21 34 55 ... (each Fibonacci number is the sum of the previous two Fibonacci numbers) Fib (0) = 0 Fib (1) = 1 Fib (n) = Fib (n-1) + Fib (n-2), n in Integers, n > 1 -- VERSION 1 (just plain wrong) (defun fib (n) (+ n (decf n))) -- VERSION 2 (at least it's recursive... infinitely recursive!) (defun fib (n) (+ n (fib (decf n)))) -- VERSION 3 (recursion is getting better... how about a base case?? try tracing the function!) (defun fib (n) (+ (fib (decf n)) (fib (decf n)))) -- VERSION 4 (now we've got a base case, but there are these cond and decf problems that need to be fixed) (defun fib (n) (cond ((eql n 0) 0) (eql n 1) 1 (t (+ (fib (decf n)) (fib (decf (decf n))))))) -- VERSION 5 (pretty good, but how about some documentation and error checking?) (defun fib (n) (cond ((eql n 0) 0) ((eql n 1) 1) (t (+ (fib (- n 1)) (fib (- n 2)))))) -- VERSION 6 (perfect! correct, indented, elegant, commented, and error checked) (defun fib (n) "Computes the nth Fibonacci number" (cond ((or (not (numberp n)) (< n 0)) ;; error case (error "~s is not a legal value for n!~&" n)) ((eql n 0) 0) ;; base case ((eql n 1) 1) ;; base case (t (+ (fib (- n 1)) ;; recurse and compute (fib (- n 2)))) )) -- LET'S TRY IT! (fib -1) (fib '(list)) (fib 0) (fib 1) (fib 2) (fib 4) (loop for i from 0 to 10 do collect (fib i)) (mapcar #'fib '(0 1 2 5 10 20))