lisp: further constructs€¦ · lisp: further constructs ref: lisp (3rded) winston & horn...
TRANSCRIPT
Lisp:FurtherConstructsref:Lisp(3rd Ed)Winston&Horn
Donald F. Ross
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
1
Datastructures:defstruct• defstruct defines new structure types
• a data structure xxx• a constructor make‐xxx• a reader (per field) xxx‐<field name>• a writer (per field) (setf <reader> value)• a predicate xxx‐p
• defstruct does not create instances• To instance use setf + the constructor (setf x make‐xxx)
• access is via readers & writers• the internal structure is not known (ADT)
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
2
Datastructures:defstruct example
>(defstruct person(sex nil) ; default value(personality nice)) ; default value
>(setf p1 (make‐person))#S(person :sex nil :personality: nice)
>(describe p1)#S(PERSON :SEX NIL :PERSONALITY NICE) is a structure of type PERSON.
Slots:SEX = NIL (default)PERSONALITY = NICE (default)
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
3
Datastructures:defstruct example
>(setf p2 (make‐person :sex ‘female))#S(person :sex female :personality nice)
>(describe p2)#S(PERSON :SEX FEMALE :PERSONALITY NICE) is a structure of type PERSON.
Slots:SEX = FEMALE (supplied)
PERSONALITY = NICE (default)
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
4
Datastructures:defstruct example
>(setf (person‐personality p1) ‘happy‐hacker) ;writerHAPPY‐HACKER
>(describe p1)#S(PERSON :SEX NIL :PERSONALITY HAPPY‐HACKER) is a structure of type PERSON.
Slots:SEX = NILPERSONALITY = HAPPY‐HACKER
>(person‐personality p1) ; readerHAPPY‐HACKER
>(person‐sex p2) ; readerFEMALE
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
5
Datastructures:defstruct>(defstruct employee
(length‐of‐service 0)(payment ‘salary))
>(defstruct (hacker (:include employee)) ;; nested structure (extends)(preferred‐language ‘lisp))
>(setf h1 (make‐hacker))#S(HACKER :LENGTH‐OF‐SERVICE 0 :PAYMENT SALARY :PREFERRED‐LANGUAGE LISP)
>(hacker‐payment h1)SALARY
>(describe h1)#S(HACKER :LENGTH‐OF‐SERVICE 0 :PAYMENT SALARY :PREFERRED‐LANGUAGE LISP) is
a structure of type HACKER.As such, it is also a structure of type EMPLOYEE.Slots:LENGTH‐OF‐SERVICE = 0PAYMENT = SALARYPREFERRED‐LANGUAGE = LISP
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
6
Datastructures:defstruct• Advantages
• Access procedures efficient• Fields are defined once and for all
• With property lists more properties may be added!• Similarly with association lists
• Useful in large projects with several programmers
• Disadvantages• Since values are stored, this is clearly not functional programming
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
7
Lisp:functions• (mapcar #’ATOM ‘(1 (1) A))
• (T NIL T)• (mapcar #’+ ‘(1 2 3) ‘(4 5 6))
• (5 7 9)• (every #’= ‘(1 2 3) ‘(3 2 1))
• nil• (some #’= ‘(1 2 3) ‘(3 2 1))
• T
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
8
Lisp:functions• (some #’atom ‘(1 A)) T• (some #’atom ‘((1) A)) T• (some #’alpha‐char‐p “test1”) T• (some #’alpha‐char‐p “test”) T• (some #’digit‐char‐p “test1”) T• (some #’digit‐char‐p “1234”) T
• NB: some == there exists
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
9
Lisp:functions• (every #’atom ‘(1 A)) T• (every #’atom ‘((1) A)) nil• (every #’alpha‐char‐p “test1”) nil• (every #’alpha‐char‐p “test”) T• (every #’digit‐char‐p “test1”) nil• (every #’digit‐char‐p “1234”) T
• NB every == for all
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
10
Lisp:functions• (member ‘X ‘(A X B X C)) (X B X C)• (member ‘X ‘(A (X) B)) nil• (setq L ‘((A B) (C D)) ((A B) (C D))• (member ‘(C D) L) nil• (member ‘(C D) L :test #’EQUAL) ((C D))• (member 2.0 ‘(1 2 3)) nil• (member 2.0 ‘(1 2 3) :test #’=) (2 3)• (member 2.0 ‘(1 2 3) :test #’<) (3)
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
11
OptionalParameters:&rest&rest – allows variable length parameter lists
(defun raise‐aux (result num‐list)(if (endp num‐list) result(raise‐aux (expt result (first num‐list)) (rest num‐list)) ))
(defun raise (x &rest numbers)(raise‐aux x numbers))
>(raise 2 3 5) ; result is 2, num‐list is ( 3 5 ); (raise 2 to the power 3), to the power 5 i.e. (23)5
; raise 2 yields 2; raise 2 3 yields 8; raise 2 3 5 yields 32768
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
12
OptionalParameters:&key&key – allows multiple parameters – bound to default values (mostly)
(defun rotate‐list (L &key direction (distance 1)) ; NB default value!(if (eq direction ‘left)
(rotate‐list‐left L distance)((rotate‐list‐right L distance))) ; default 1 to the right
(rotate‐list ‘(a b c d e)) ; 1 to the right (rotate‐list ‘(a b c d e) :direction ‘left) ; 1 to the left (rotate‐list ‘(a b c d e) :distance 2) ; 2 to the right (rotate‐list ‘(a b c d e) :distance 2 :direction ‘left) ; 2 to the left (rotate‐list ‘(a b c d e) :direction ‘left :distance 2) ; 2 to the left
Note that the bindings are determined by keywords (distance, direction) and not the order defined
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
13
OptionalParameters:&aux• &aux – allows local data objects to be evaluated
• (a disguised let* construct)
>(defun both‐ends‐with‐let (whole‐list))(let* ((element (first whole‐list))
(trailer (last whole‐list)))(cons element trailer)))
>(defun both‐ends‐with‐aux (whole‐list &aux(element (first whole‐list))(trailer (last whole‐list)))
(cons element trailer))
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
14
Lisp:mindset• List syntax (+ 2 2) • Data abstraction
• constructor• readers & writers• Association lists• Property lists• User defined structures
• Function abstraction• Functions as first‐class objects: parameters & return values• (fn arg1 arg2 … argn)• Mapping functions over lists ‐mapcar• Filters
• find‐if find‐if‐not• count‐if count‐if‐not• remove‐if remove‐if‐not
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
15
Lisp:Whatnext?• Lisp is actually a composite language
• Functional programming aspects• Imperative programming aspects• Object oriented aspects
• CLOS – Common Lisp Object system• Classes may be defined
• In this course part we want to study FP• CLOS will be left for a future class• IP constructs are strongly discouraged!
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
16
Lisp:developingcode• Top‐down stepwise refinement approach• Save a copy of the last working version• Test constructs if you are not sure• Think functionally & recursively• Think in terms of transforming data objects• Thinkwhat you want to do in the abstract
• then check what Lisp offers you to achieve this
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
17
Lisp:finalcomments• What is required to learn & understand Lisp?
• Functional mindset• No (few) variables• Functions are higher order objects• Conditional expressions• Recursion (especially tail recursion)
• Lisp programming clichés• Transform, filter, count• Constructor, reader, writer (setf <reader> <value>)• mapcar – map functions over lists
• Experimentation• Use the interpreter to check results interactively• Perform small tests before writing larger procedures
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
18
Specialform:Case(case <key form>(<key 1> <consequent 1‐1> …)(<key 2> <consequent 1‐2> …)‐‐‐(<key m> <consequent 1‐m> …)(otherwise <consequent 1‐o> …)
)
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
19
Case:example:findtheareaofanobject:( case thing(circle (* pi r r))(sphere (* 4 pi r r))(otherwise 0)
);; corresponding cond
(cond ((eq thing ‘circle (* pi r r))((eq thing ‘sphere (* 4 pi r r))
)
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
20
Case:notes
•Case• is used to find a value among several possibilities• Uses EQL (cond uses eq)• If no otherwise and no clause triggered, NIL is returned
• The keys may be lists e.g. (circle wheel) and memberis used
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
21
Datastructures:access• Access procedures (in general)
• Constructor: create data (instances)• Reader: extract data (get‐attribute)• Writer: change data (set‐attribute)
• In Lisp• The constructor is often called make‐xxx• The writer is often (setf (reader) value)
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
22
Datastructures:propertylistsproperty lists – symbolically indexed data objectsA collection of property names and values• Symbol may have
• Property value (key / index)• Ordinary value
• Writer (& constructor (first write)) for a property value• (setf <reader> <property value>)• (setf (get ‘patrick ‘parents) ‘(robert dorothy))
(robert dorothy)
• Reader for a property value• (get <symbol> <property name>)• (get ‘patrick ‘parents)
(robert dorothy)
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
23
Datastructures:propertylists• Functions for property lists
• symbol‐plist: get a description of a property list• remprop: remove a property from a property list
>(setf (get ‘patrick ‘address) ‘(Karlstad))>(symbol‐plist ‘patrick)(address (Karlstad) parents (robert dorothy))
>(remprop ‘patrick ‘parents)>(symbol‐plist ‘patrick)(address (Karlstad))
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
24
Datastructures:arraysArrays – numerically indexed data objects>(setf arr‐ex (make‐array 4)) ; 0..3>(setf arr‐ex (make‐array ‘(8 8)) ; 0..7, 0..7>(setf arr‐ex (make‐array 4) :initial‐element ‘e)#(E E E E)
• Access ‐ read• (aref arr‐ex 0) ; 1st element 1D array• (aref arr‐ex 0 3) ; first row 4th element 2D array
• Access – write• (setf (aref arr‐ex 0) ‘books) ; write to first element
• NB: array‐dimension returns the size of an array• dotimes (iteration) is often used in conjunction with arrays (!)
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
25
Lisp:help&debugging• Top‐down and stepwise development• Abstraction: data and procedure• Modularity• Procedures (functions) should
• be short• have few arguments • be built around goals
• Test & implement changes step‐wise !!!
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
26
Lisp:help&debugging• (trace <procedure‐name>)
• Prints the procedure name, arguments & values
>(trace match)2. Trace: MATCH ==> (DOT ".")2. Trace: (MATCH '#S(PSTATE :LOOKAHEAD (DOT ".") :STREAM #<INPUT BUFFERED FILE‐STREAM CHARACTER #P"testok1.pas" @6>) 'DOT)
2. Trace: MATCH ==> (EOF "")2. Trace: (MATCH '#S(PSTATE :LOOKAHEAD (EOF "") :STREAM #<INPUT BUFFERED FILE‐STREAM CHARACTER #P"testok1.pas" @7>) 'EOF)
2. Trace: MATCH ==> (EOF "")1. Trace: PROGRAM ==> (EOF "")Parser says true.
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
27
Lisp:help&debugging• (trace xxx) is useful – use it!• There are also 2 less used functions
• STEP procedures go 1 step at a time• BREAK stops evaluation ‐ prints argument
• Writes from the program may also be a useful help in debugging• (format t "The incoming lexeme is: ~S ~%" lexeme)• (if (program (create‐parser‐state stream))
(format t "Parser says true. ~%")(format t "Parser says false. ~%")
)
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
28
Lisp:help&debugging• Describe – give a description of a Lisp symbol
>(describe ‘match)
MATCH is the symbol MATCH, lies in #<PACKAGE COMMON‐LISP‐USER>, is accessible in 1 package COMMON‐LISP‐USER, names a
function, has 3 properties SYSTEM::TRACING‐DEFINITION, SYSTEM::TRACED‐DEFINITION, SYSTEM::DEFINITION.
For more information, evaluate (SYMBOL‐PLIST 'MATCH).
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
29
Lisp:help&debugging• dribble – output the session to a file>(dribble “session.txt”) ; switch on> (runtests)>(dribble) ; switch off
TESTS: syntactically incorrect a‐zMatch error Expected Symbol: PROGRAM Found: (EOF "")Parser says false.Match error Expected Symbol: PROGRAM Found: (ID "testb")Parser says false.Match error Expected Symbol: ID Found: (LP "(")Parser says false.Match error Expected Symbol: LP Found: (ID "input")Parser says false.
25/0
5/20
15P
S -
Lisp
-Fu
rther
Con
stru
cts
30
Lisp:debugging• (dribble <file‐name>)• (dribble)• (trace <function‐name>)• (untrace <function‐name>)
• (step s) s – expression• (describe o) o – object
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
31
Lisp:debugging• (symbol‐name s) s – symbol• (symbol‐value s) s – symbol• (symbol‐function s) s – symbol• (symbol‐plist s) s – symbol
• (time e) e ‐ expression• (exit)
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
32
Lisp:readingcode• “Inside‐out”
• Lisp code may contain several nested function applications• (fn(fn‐1(…(f1(arg)))))• Document each function as fk: x y with corresponding arguments and result
• Read from the inside out
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
33
Lisp:readingcode(fn arg1 arg2 … argn ) is a typical function applicationwhere fn may be
• A Lisp built‐in or user defined function (defun)• (member ‘X ‘(A X B X C))
• An applied user defined function (funcall)• (funcall lexeme‐mapper result)
• A Lisp reader / writer function(setf (pstate‐lookahead state)(get‐next‐token (pstate‐stream state) #'map‐lexeme))
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
34
Lisp:readingcode• For data structures, look for
• Constructors make‐xxx• Readers (struct‐field instance)• Writers (setf <reader> value)• Predicates (to test for the type)
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
35
Lisp:readingcodeIn the parser example we have(writer (reader instance) value)
(setf (pstate‐lookahead state)(get‐next‐token (pstate‐stream state)
#'map‐lexeme))
where the value consists of a function applicationwith 2 parameters, the first of which is a readerapplied to a dataThe value of pstate‐lookahead is set to the result from get‐next‐token i.e. a (token, lexeme) pair
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
36
Lisp:readingcodeIn the above example
(setf (pstate‐lookahead state)(get‐next‐token (pstate‐stream state) #'map‐lexeme))
state must be a data object of type pstatewith 2 fields – as implied by the readers
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
37
Lisp:readingcode• Make a list of all the functions in a program
• f: x y (with arguments & results)
• This will help recognise if functions appear as arguments to other functions AND if functions are returned as results from other functions
• It will also help the reading of function applications
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
38
Lisp:readingcodeLook for clichés such as tail recursion
>(defun list‐authors (books)(if (endp books) nil ; empty list(cons (book‐author (first books))
(list‐authors (rest books)))))
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
39
Lisp:readingcode• Look for clichés such asfunction application, filter, find, count
(mapcar #’<function> books) ; apply <function> to each element
(remove‐if #’<predicate> books) ; filter(find‐if #’<predicate> books) ; find(count‐if #’<predicate> books) ; count
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
40
Lisp:writingcode• Know the basic functions in the language• Think using lists – use tail recursion• Think in programming clichés
• Map functions (transform lists)• Filter, find and count clichés
• Try to keep functions small• Be very careful with equality operations• Small is beautiful (E.F. Shumacher)
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
41
Lisp:writingcode• Use preconditions e.g.
• Is the object a list?• Is the list empty?
(defun mapcar (fun lis)(cond
( (null lis) ‘())(T (cons (funcall fun (first lis))
(mapcar fun (rest lis)))))
)
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
42
Lisp:writingcode• Use a clear (2‐D) layout for code – e.g.
(defun map‐lexeme (lexeme)(format t "The incoming lexeme is: ~S ~%" lexeme)(list (cond
((string= lexeme "program") 'PROGRAM)((string= lexeme "var") 'VAR); ...((string= lexeme "(") 'LP)((string= lexeme ")") 'RP); ...; ((is‐id lexeme) 'ID); ((is‐number lexeme) 'NUM)(t 'UNKNOWN))
lexeme))
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
43
Lisp:writingcode• Be very careful about testing equality
• If in doubt TEST FIRST!• Expression? EQUAL• Symbol or number? EQL• Symbol? EQ• Number? =• Characters char‐equal / char=• Strings string‐equal / string=
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
44
Lisp:writingcode• In procedures, use optional parameters and default values• &rest
• Variable length parameter lists• &key
• Parameters bound to default values• &aux
• (disguised let*)
25/0
5/20
15D
FR -
Lisp
Con
clus
ion
45