; SLIME 2006-11-26 CL-USER> (load "make.lisp")(demo :all) ; compiling file "/home/ctobrey/opt/lisp/proj1/ch3/3-8.lisp" (written 03 FEB 2008 04:10:38 PM): ; compiling (EGS :|3.8| ...) ; /home/ctobrey/opt/lisp/proj1/ch3/3-8.fasl written ; compilation finished in 0:00:00 ; compiling file "/home/ctobrey/opt/lisp/proj1/ch3/3-15.lisp" (written 03 FEB 2008 04:10:36 PM): ; compiling (EGS :|3.15| ...) ; /home/ctobrey/opt/lisp/proj1/ch3/3-15.fasl written ; compilation finished in 0:00:00 ;;;; 1) A Guide to Lisp Style ;IN: (DEMO 3.1) ;;;; 1) being specific when naming variables ;IN: (DEFVAR *NAMES* '((ROBERT E. LEE) (ULYSSES S. GRANT))) ;GOT: *NAMES* ;ok ;;;; 2) creating a specific function to access names rather than evaluating caddar *names* ;IN: (DEFUN LAST-NAME (NAME) (LAST NAME)) ;GOT: LAST-NAME ;ok ;;;; 3) using the last-name function ;IN: (LAST-NAME (FIRST *NAMES*)) ;GOT: (LEE) ;ok ;;;; 4) last-name again ;IN: (LAST-NAME (SECOND *NAMES*)) ;GOT: (GRANT) ;ok ;GOT: 0 ;ok ;;;; 2) list functions ;IN: (DEMO 3.3) ;;;; 1) defining a list ;IN: (SETF X '(A B C)) ; in: LAMBDA NIL ; (SETF X '(A B C)) ; ==> ; (SETQ X '(A B C)) ; ; caught WARNING: ; undefined variable: X ; ; caught WARNING: ; This variable is undefined: ; X ; ; compilation unit finished ; caught 2 WARNING conditions ;GOT: (A B C) ;ok ;;;; 2) another list ;IN: (SETF Y '(1 2 3)) ; in: LAMBDA NIL ; (SETF Y '(1 2 3)) ; ==> ; (SETQ Y '(1 2 3)) ; ; caught WARNING: ; undefined variable: Y ; ; caught WARNING: ; This variable is undefined: ; Y ; ; compilation unit finished ; caught 2 WARNING conditions ;GOT: (1 2 3) ;ok ;;;; 3) using first on a list evaluates to the first element ;IN: (FIRST X) ;GOT: A ;ok ;;;; 4) using second on a list evaluates to the second element ;IN: (SECOND X) ;GOT: B ;ok ;;;; 5) using third on a list evaluates to the third element ;IN: (THIRD X) ;GOT: C ;ok ;;;; 6) using nth 0 on a list evaluates to the nth element and is zero based ;IN: (NTH 0 X) ;GOT: A ;ok ;;;; 7) rest evaluates to all but the first element ;IN: (REST X) ;GOT: (B C) ;ok ;;;; 8) another name for first -- Contents of Address Register ;IN: (CAR X) ;GOT: A ;ok ;;;; 9) another name for rest -- Contents of data register ;IN: (CDR X) ;GOT: (B C) ;ok ;;;; 10) last cons cell in a list ;IN: (LAST X) ;GOT: (C) ;ok ;;;; 11) length evaluates to the number of elements in a list ;IN: (LENGTH X) ;GOT: 3 ;ok ;;;; 12) puts the list in reverse order ;IN: (REVERSE X) ;GOT: (C B A) ;ok ;;;; 13) add to the front of the list ;IN: (CONS 0 Y) ;GOT: (0 1 2 3) ;ok ;;;; 14) appends list elements together ;IN: (APPEND X Y) ;GOT: (A B C 1 2 3) ;ok ;;;; 15) makes a new list ;IN: (LIST X Y) ;GOT: ((A B C) (1 2 3)) ;ok ;;;; 16) append last argument to others ;IN: (LIST* 1 2 X) ;GOT: (1 2 A B C) ;ok ;;;; 17) predicate is true of the empty list ;IN: (NULL NIL) ;GOT: T ;ok ;;;; 18) and false for everythinf else ;IN: (NULL X) ;GOT: NIL ;ok ;;;; 19) predicate is true for any list, including nil ;IN: (LISTP X) ;GOT: T ;ok ;;;; 20) and false for non-lists ;IN: (LISTP 3) ;GOT: NIL ;ok ;;;; 21) predicate is true of non-nil lists ;IN: (CONSP X) ;GOT: T ;ok ;;;; 22) and false for atoms, including nil. ;IN: (CONSP NIL) ;GOT: NIL ;ok ;;;; 23) true for lists that look the same ;IN: (EQUAL X X) ;GOT: T ;ok ;;;; 24) and false for lists that look different ;IN: (EQUAL X Y) ;GOT: NIL ;ok ;;;; 25) sort y with a comparison function ;IN: (SORT Y #'>) ;GOT: (3 2 1) ;ok ;;;; 26) subsequence of a list with start and end points ;IN: (SUBSEQ X 1 2) ;GOT: (B) ;ok ;GOT: 0 ;ok ;;;; 3) Functions on Sequences ;IN: (DEMO 3.5) ;;;; 1) using nth to get the nth element in a list ;IN: (NTH 1 *NAMES*) ;GOT: (ULYSSES S. GRANT) ;ok ;;;; 2) using elt on a list. gets the element at the specified zero-based ;IN: (ELT *NAMES* 0) ;GOT: (ROBERT E. LEE) ;ok ;GOT: 0 ;ok ;;;; 4) Functions for Maintaining Tables ;IN: (DEMO 3.6) ;;;; 1) here is the table we are working with. It is a list of dotted pairs where each pair has a key and a value ;IN: (PRINT STATE-TABLE) ((AL . ALABAMA) (AK . ALASKA) (AZ . ARIZONA) (AR . ARKANSAS)) ;GOT: ((AL . ALABAMA) (AK . ALASKA) (AZ . ARIZONA) (AR . ARKANSAS)) ;ok ;;;; 2) using assoc to look up a state by it two letter abbreviation. ;IN: (ASSOC 'AK STATE-TABLE) ;GOT: (AK . ALASKA) ;ok ;;;; 3) using cdr and assoc to return only the state name given its two letter abbreviation. ;IN: (CDR (ASSOC 'AK STATE-TABLE)) ;GOT: ALASKA ;ok ;;;; 4) looking up a pair that is not in the table ;IN: (ASSOC 'TX STATE-TABLE) ;GOT: NIL ;WANT: TEXAS ;BAD !!!!!!!!!!!!!!!!!!! ;;;; 5) Using rassoc to search the table by value rather than by key ;IN: (RASSOC 'ARIZONA STATE-TABLE) ;GOT: (AZ . ARIZONA) ;ok ;;;; 6) using car on the previous function to return only the two letter abbrev. when given the value of the pair ;IN: (CAR (RASSOC 'ARIZONA STATE-TABLE)) ;GOT: AZ ;ok ;;;; 7) using gethash to access the hash-table ;IN: (GETHASH 'AK TABLE) ;GOT: ALASKA ;ok ;;;; 8) if only there was a texas ;IN: (GETHASH 'TX TABLE) ;GOT: NIL ;WANT: TEXAS ;BAD !!!!!!!!!!!!!!!!!!! ;;;; 9) retrieving values from the property list ;IN: (GET 'AK 'STATE) ;GOT: ALASKA ;ok ;;;; 10) still no Texas ;IN: (GET 'TX 'STATE) ;GOT: NIL ;WANT: TEXAS ;BAD !!!!!!!!!!!!!!!!!!! ;;;; 11) property lists ;IN: (GET 'STATE-TABLE 'AK) ;GOT: ALASKA ;ok ;;;; 12) property list example ;IN: (GET 'STATE-TABLE 'ALASKA) ;GOT: NIL ;WANT: AK ;BAD !!!!!!!!!!!!!!!!!!! ;GOT: 4 ;ok ;;;; 5) Functions on numbers ;IN: (DEMO 3.8) ;;;; 1) Addition ;IN: (+ 4 2) ;GOT: 6 ;ok ;;;; 2) Subtraction ;IN: (- 4 2) ;GOT: 2 ;ok ;;;; 3) Division ;IN: (/ 4 2) ;GOT: 2 ;ok ;;;; 4) greater than (also >=) ;IN: (> 100 99) ;GOT: T ;ok ;;;; 5) equals also (/=, not equal) ;IN: (= 100 100) ;GOT: T ;ok ;;;; 6) random integer from 0 to 99 ;IN: (RANDOM 100) ;GOT: 8 ;ok ;;;; 7) exponentiation (also exp, log, and ex ;IN: (EXPT 4 2) ;GOT: 16 ;ok ;;;; 8) sine (also cos, tan, etc) ;IN: (SIN PI) ;GOT: 1.2246063538223773d-16 ;ok ;;;; 9) arcsin (also acos, atan, etc) ;IN: (ASIN 0) ;GOT: 0.0 ;ok ;;;; 10) min (also max) ;IN: (MIN 2 3 4) ;GOT: 2 ;ok ;;;; 11) absloute value ;IN: (ABS -3) ;GOT: 3 ;ok ;;;; 12) square root ;IN: (SQRT 4) ;GOT: 2.0 ;ok ;;;; 13) round off (also truncate, floor, ceiling) ;IN: (ROUND 4.1) ;GOT: 4 ;ok ;;;; 14) remainder (also mod) ;IN: (REM 11 5) ;GOT: 1 ;ok ;GOT: 0 ;ok ;;;; 6) Destructive Functions ;IN: (DEMO 3.10) ;;;; 1) assigning ( a b c ) to x ;IN: (SETF X '(A B C)) ; in: LAMBDA NIL ; (SETF X '(A B C)) ; ==> ; (SETQ X '(A B C)) ; ; caught WARNING: ; undefined variable: X ; ; caught WARNING: ; This variable is undefined: ; X ; ; compilation unit finished ; caught 2 WARNING conditions ;GOT: (A B C) ;ok ;;;; 2) assigning ( 1 2 3 ) to y ;IN: (SETF Y '(1 2 3)) ; in: LAMBDA NIL ; (SETF Y '(1 2 3)) ; ==> ; (SETQ Y '(1 2 3)) ; ; caught WARNING: ; undefined variable: Y ; ; caught WARNING: ; This variable is undefined: ; Y ; ; compilation unit finished ; caught 2 WARNING conditions ;GOT: (1 2 3) ;ok ;;;; 3) append is a pure function so x and y retain their values ;IN: (APPEND X Y) ;GOT: (A B C 1 2 3) ;ok ;;;; 4) x retaining is original value ;IN: (PRINT X) (A B C) ;GOT: (A B C) ;ok ;;;; 5) y retains its original value ;IN: (PRINT Y) (1 2 3) ;GOT: (1 2 3) ;ok ;;;; 6) using nconc , a destructive function to combine the lists ;IN: (NCONC X Y) ;GOT: (A B C 1 2 3) ;ok ;;;; 7) nconc has the side effect of altering its first argument ;IN: (PRINT X) (A B C 1 2 3) ;GOT: (A B C 1 2 3) ;ok ;;;; 8) y retains its initial value ;IN: (PRINT Y) (1 2 3) ;GOT: (1 2 3) ;ok ;GOT: 0 ;ok ;;;; 7) Input/Output functions ;IN: (DEMO 3.12) ;;;; 1) using the macro with-open-stream to open a file and associate it with a stream ;IN: (WITH-OPEN-FILE (STREAM test.txt DIRECTION OUTPUT) (PRINT '(HELLO THERE) STREAM) (PRINC 'GOODBYE STREAM)) ;GOT: GOODBYE ;ok ;;;; 2) using the macro with-open file to open test.txt and associate it with a stream ;IN: (WITH-OPEN-FILE (STREAM test.txt DIRECTION INPUT) (LIST (READ STREAM) (READ-CHAR STREAM) (READ STREAM) (READ STREAM NIL 'EOF))) ;GOT: ((HELLO THERE) G OODBYE EOF) ;ok ;;;; 3) deleting the file so this example can run again and again ;IN: (DELETE-FILE test.txt) ;GOT: T ;ok ;;;; 4) the first argument of the function format is the stream to print to. here we use t to specify the terminal ;IN: (FORMAT T hello, world) hello, world;GOT: NIL ;ok ;;;; 5) the format directive ~&~ moves to a fresh line. ~a prints the next argument as princ would ;IN: (FORMAT T ~&~a plus ~s is ~f two two 4) two plus "two" is 4.0;GOT: NIL ;ok ;;;; 6) ~r prints the next argument which should be a number and ~~@r prints a number as a roman numeral. ;IN: (LET ((NUMBERS '(1 2 3 4 5))) (FORMAT T ~&~{~r~^ plus ~} is ~@r NUMBERS (APPLY #'+ NUMBERS))) one plus two plus three plus four plus five is XV;GOT: NIL ;ok ;GOT: 0 ;ok ;;;; 8) Antibugging Tools ;IN: (DEMO 3.14) ;;;; 1) the function average with a continuable error defined within. You can also specify an error but that would kill the example ;IN: (DEFUN AVERAGE (NUMBERS) (IF (NULL NUMBERS) (PROGN (CERROR Use 0 as the Average. Average of empty list is undefined.) 0) (/ (REDUCE #'+ NUMBERS) (LENGTH NUMBERS)))) ;GOT: AVERAGE ;ok ;;;; 2) calling the average function on an empty list ;IN: (AVERAGE 'NIL) ;GOT: 0 ;ok ;;;; 3) using check-type. if sqr is called with a non number argument, an appropriate error message is printed ;IN: (DEFUN SQR (X) multiply x by itself (CHECK-TYPE X NUMBER) (* X X)) ;GOT: SQR ;ok ;;;; 4) calling square with a non-number argument ;IN: (SQR jello) Type a form to be evaluated: 145 ;GOT: 21025 ;ok ;;;; 5) another finction times-two that uses assert (numberp x)(x) to check if argument is a number and giving a value to change in the event of an error ;IN: (DEFUN TIMES-TWO (X) multiple x by two (ASSERT (NUMBERP X) (X)) (* X 2)) ;GOT: TIMES-TWO ;ok ;;;; 6) calling times-two with a list instead of a number ;IN: (TIMES-TWO '(HOW ARE YOU?)) The old value of X is (HOW ARE YOU?). Do you want to supply a new value? (y or n) y Type a form to be evaluated: 23556456456567456748345134 ;GOT: 47112912913134913496690268 ;ok ;;;; 7) a function we will time ;IN: (DEFUN F (N) (DOTIMES (I N) NIL)) ;GOT: F ;ok ;;;; 8) timing the function wtih the time function ;IN: (TIME (F 100000)) Evaluation took: 0.001 seconds of real time 0.0 seconds of user run time 0.004 seconds of system run time 0 calls to %EVAL 0 page faults and 0 bytes consed. ;GOT: NIL ;ok ;;;; 9) compiling f ;IN: (COMPILE 'F) ;GOT: F ;ok ;;;; 10) timing the compiled function ;IN: (TIME (F 100000)) Evaluation took: 0.001 seconds of real time 0.004001 seconds of user run time 0.0 seconds of system run time 0 calls to %EVAL 0 page faults and 0 bytes consed. ;GOT: NIL ;ok ;GOT: 0 ;ok ;;;; 9) Evaluation ;IN: (DEMO 3.15) ;;;; 1) using an arithmetic operator ;IN: (+ 1 2 3 4) ;GOT: 10 ;ok ;;;; 2) using funcall ;IN: (FUNCALL #'+ 1 2 3 4) ;GOT: 10 ;ok ;;;; 3) using apply ;IN: (APPLY #'+ '(1 2 3 4)) ;GOT: 10 ;ok ;;;; 4) using apply ;IN: (APPLY #'+ 1 2 '(3 4)) ;GOT: 10 ;ok ;;;; 5) using eval ... Norvig -- If you are using eval you are probably doing the wrong thing ;IN: (EVAL '(+ 1 2 3 4)) ;GOT: 10 ;ok ;GOT: 0 ;ok ;;;; 10) using a rule base solution to defin a simple grammer ;IN: (DEMO 3.19) ;;;; 1) defining the naive math-quiz ;IN: (DEFUN MATH-QUIZ (OP RANGE N) Ask the user a series of math problems. (DOTIMES (I N) (PROBLEM (RANDOM RANGE) OP (RANDOM RANGE)))) ;GOT: MATH-QUIZ ;ok ;;;; 2) problem function used in math quiz ;IN: (DEFUN PROBLEM (X OP Y) Ask a math problem, read reply, and say if correct (FORMAT T ~&How Much is ~d ~a ~d? X OP Y) (IF (EQL (READ) (FUNCALL OP X Y)) (PRINC Correct!) (PRINC Sorry incorrect :())) ;GOT: PROBLEM ;ok ;;;; 3) math quiz in use ;IN: (MATH-QUIZ '+ 100 2) How Much is 65 + 69?134 Correct! How Much is 95 + 25?59032 Sorry incorrect :(;GOT: NIL ;ok ;GOT: 0 ;ok 0 CL-USER>