;;;; chapter 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 4 (+ 2 2) ; 55 (+ 1 2 3 4 5 6 7 8 9 10) ;This is Lisp for (900 + 900 + 90 + 9) - (5000 + 500 + 50 + 5) = 4444 (- (+ 9000 900 90 9) (+ 5000 500 50 5)) ;; section "1.1 Symbolic Computation") ;(PAT KIM ROBIN SANDY) @ 6) (append '(Pat Kim) '(Robin Sandy)) ;The quote mark instructs Lisp to treat the list as data." '(pat Kim) ;:section "1.4 Lists") (defparamter *p* '(John Q Public)) (first *p*) (rest *p*) (second *p*) (third *p*) (fourth *p*) (length *p*) "It is also possible to build up new lists" *p* (cons 'Mr *p*) (cons (first *p*) (rest *p*)) (defparameter *town* (list 'Anytown 'USA)) (list p 'of *town* 'may 'have 'already 'won!) (append p '(of) *town* '(may have already won)) p ;:section "1.5 Defining New Functions" ;The special form DEFUN stands for 'define function.'" ;It is used here to define a new function called last-name:" (defun last-name (name) "Select the last name from a name represented as a list." (first (last name))) (defun first-name (name) "Select the first name from a name represented as a list." (first name)) (last-name *p*) (last-name '(Rex Morgan MD) (last-name '(Spot)) (last-name '(Aristotle)) "We can also define the function first-name." "Even though the definition is trivial (it is the same as FIRST)," "it is good practice to define first-name explicitly." (defun last-name (name) (first (last name))) (defun first-name (name) (first name)) *p* (first-name *p*) (first-name '(Wilma Flintstone)) (defparameter *names* '((John Q Public) (Malcolm X) (Admiral Grace Murray Hopper) (Spot) (Aristotle) (A A Milne) (Z Z Top) (Sir Larry Olivier) (Miss Scarlet))) (first-name (first *names*)) ;:section "1.6 Using Functions" "Consider the following expression, which can be used to test LAST-NAME:" (mapcar #'last-name *names*) "The #' notation maps the name of a function to the function itself." (mapcar #'- '(1 2 3 4)) (mapcar #'+ '(1 2 3 4) '(10 20 30 40)) "Now that we understand mapcar, let's use it to test FIRST-NAME:" (mapcar #'first-name names) "Suppose we wanted a version of FIRST-NAME that ignored titles like Miss:" (defparameter *titles* '(Mr Mrs Miss Ms Sir Madam Dr Admiral Major General) "A list of titles that can appear at the start of a name.") (defun first-name (name) "Select the first name from a name represented as a list." (if (member (first name) *titles*) (first-name (rest name)) (first name))) (mapcar #'first-name *names*) (first-name '(Madam Major General Paula Jones)) "We can see how this works by tracing the execution of first-name:" (trace first-name) (first-name '(John Q Public)) (first-name '(Madam Major General Paula Jones)) (untrace first-name) ;:section "1.7 Higher-Order Functions" (apply #'+ '(1 2 3 4)) (apply #'append '((1 2 3) (a b c))) "Now we define a new function, self-and-double, and apply it to arguments." (defun self-and-double (x) (list x (+ x x))) (self-and-double 3) (apply #'self-and-double '(3)) "Now let's return to the mapping functions:" (mapcar #'self-and-double '(1 10 300)) (mappend #'self-and-double '(1 10 300) "FUNCALL is similar to APPLY; it too takes a function as its first argument and applies the function to a list of arguments, but in the case of FUNCALL, the arguments are listed separately:" (funcall #'+ 2 3) (apply #'+ '(2 3)) ;;;; chapter 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;(defexamples 2 "A Simple Lisp Program" "This chapter shows how to combine the basic functions and" "special forms of Lisp into a complete program" "The program generates random English sentences." ;:section "2.2 A Straightforward Solution" "We can test the program by generating a few random sentences." "(Note that since these are random, you won't get the same ones" "as in the book.)" (load "simple.lisp") #| (defparameter *simple-grammar* '((sentence -> (noun-phrase verb-phrase)) (noun-phrase -> (Article Noun)) (verb-phrase -> (Verb noun-phrase)) (Article -> the a) (Noun -> man ball woman table) (Verb -> hit took saw liked)) "A grammar for a trivial subset of English.") |# (sentence) (sentence) (sentence) (noun-phrase) (verb-phrase) (trace sentence noun-phrase verb-phrase article noun verb) (sentence) (untrace) ;section "2.3 A Rule-Based Solution" "An alternative implementation concentrates on making it easy" "to write grammar rules." (generate 'sentence) (generate 'sentence) (generate 'noun-phrase) (generate 'verb-phrase) "One advantage of this approach is its easier to change grammars." (setf *grammar* *bigger-grammar*) (generate 'sentence) (generate 'sentence) "Another advantage is that the same data (grammar) can be used" "for more than one purpose. Consider generate-tree:" (generate-tree 'sentence) ;;;; chapter 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;defexamples 3 "Overview of Lisp" "This chapter briefly covers the most important special forms and" "functions in Lisp." ;:section "3.2 Special Forms" "Start with functions and special forms for repetition:" "First, functions like MAPCAR can apply to any number of lists:" (mapcar #'- '(1 2 3)) (mapcar #'+ '(1 2) '(10 20) '(100 200)) "Second, many of the functions accept keywords:" (remove 1 '(1 2 3 2 1 0 -1)) (remove 1 '(1 2 3 2 1 0 -1) :key #'abs) (remove 1 '(1 2 3 2 1 0 -1) :test #'<) (remove 1 '(1 2 3 2 1 0 -1) :start 4) "Third, some have corresponding -IF or -IF-NOT versions:" (remove-if #'oddp '(1 2 3 2 1 0 -1)) (remove-if-not #'oddp '(1 2 3 2 1 0 -1)) "The forms TRACE and UNTRACE are used to control debugging info:" (defun length9 (list) (if (null list) 0 (+ 1 (length9 (rest list))))) (trace length9) (length9 '(1 b c)) (untrace length9) (length9 '(1 b c)) :section "3.7 Functions on Trees" (defparameter *tree* '((a b) ((c)) (d e))) (tree-equal *tree* (copy-tree tree)) (defun true (&rest ignore) (declare (ignore ignore)) t) (defun same-shape-tree (a b) "Are two trees the same except for the leaves?" (tree-equal a b :test #'true)) (same-shape-tree *tree* '((1 2) ((3)) (4 5))) (same-shape-tree *tree* '((1 2) (3) (4 5))) "There are two functions for substituting a new expression into a tree:" (subst 'new 'old '(old ((very old)))) (sublis '((old . new)) '(old ((very old)))) (subst 'new 'old 'old) "Here is an example:" (defun english->french (words) "Transalte english to french. Usage: (english->french list-of-words)" (sublis '((are . va) (book . libre) (friend . ami) (hello . bonjour) (how . comment) (my . mon) (red . rouge) (you . tu)) words)) (english->french '(hello my friend - how are you today?)) ;:section "3.10 Destructive Functions" "Consider the following:" (defparameter *x* '(a b c)) (defparameter *y* '(123)) (nconc *x* *y*) *x* *y* "NCONC computes the same result as APPEND, but it alters the first argument." "It is called a 'destructive' function." "There is quite a conceptual load on the programmer who uses NCONC." "The advantage of NCONC is that it doesn't use any storage." "" ;:section "3.11 Overview of Data Types" "The function TYPE-OF returns the type of its argument." (type-of 123) (typep 123 'fixnum) (typep 123 'integer) (typep 123.0 'integer) (subtypep 'fixnum 'integer) ;:section "3.12 Input/Output" "FORMAT is the main function for formatted output:" (format t "hello, world") (format t "~&~a plus ~s is ~f" "two" "two" 4) (let ((numbers '( 1 2 3 4 5))) (format t "~&~{~r~^ plus ~} is ~@r" numbers (apply #'+ numbers))) ;:section "3.13 Debugging tools" (documentation 'first 'function) (documentation 'english->french 'function) (describe 'english->french) (documentation 'pi 'variable) ;:section "3.14 Antibugging Tools" (defun f (n) (dotimes (i n) nil)) (time (f 100000)) (compile 'f) (time (f 100000)) ;:section "3.15 Evaluation" "The following five forms are equivalent:" (+ 1 2 3 4) (funcall #'+ 1 2 3 4) (defun adder (c) "Return a function that adds c to its argument." #'(lambda (x) (+ x c))) (apply #'+ '(1 2 3 4)) (apply #'+ 1 2 '(3 4)) (eval '(+ 1 2 3 4)) ;:section "3.16 Closures" "In the general case, a function consists of the body of the function" "coupled with any free lexical variables that the function references." "Consider the example:" (mapcar (adder 3) '(1 3 10)) (mapcar (adder 10) '(1 3 10)) "In the following, two calls to BANK-ACCOUNT create two different closures," "each with a separate value for the lexical variable BALANCE." (defun bank-account (balance) "Open a bank account starting with the given balance." #'(lambda (action amount) (case action (deposit (setf balance (+ balance amount))) (withdraw (setf balance (- balance amount)))))) (defparameter *my-account* (bank-account 500.00)) (defparameter *your-account* (bank-account 250.00)) (funcall *my-account* 'withdraw 75.00) (funcall *your-account* 'deposit 250.00) (funcall *your-account* 'withdraw 100.00) (funcall *my-account* 'withdraw 25.00)