Lisp: Case Study ref: Lisp (3 rd Ed) Winston & Horn (Chapter 6) Donald F. Ross
Lisp: Case Study Exercise build a library system object: book collection:library title / author / class (attributes) data abstraction constructor (make) (sound familiar?) reader (get) writer (set) Program clichés (patterns) 2
Lisp: Case Study: the answer! (defun make book (title author class) (defun baw (book author) (list (list 'title title) (if (eql 'author (first (first book))) (list 'author author) (cons (list 'author author) (rest book)) (list 'class class) )) (cons (first book) (baw (rest book) author))))) (defun book title (book) (second (assoc 'title book)) ) (defun book author (book) (second (assoc 'author book)) ) (defun book class (book) (second (assoc 'class book)) ) (defun fictionp (book) (member 'fiction (book class book)) ) (mapcar # <function> books) ; apply <function> to each element (remove if # <predicate> books) ; filter (find if # <predicate> books) ; find first (count if # <predicate> books) ; count 3
Lisp: Case Study: Comments Database A B C D E a b c d e x x Selection & projection Goals introduce Constructors Readers Writers Filters Find Count Functional thinking mapcar 4
Lisp: Case Study Design Aspects Association list Contains sub lists: symbol (key) + value (setf sarah ((height 1.65) (weight 65))) ((height 1.65) (weight 65)) Retrieval is performed by (assoc <key> <association list>) (assoc weight sarah) (weight 65) (second (assoc weight sarah)) 65 Advantages of a reader The data structure can be changed Only the (internal) code for the reader need be changed The functionality remains the same book author: book author You all knew that! 5
Lisp: Case Study (setf book ex2 ( (title (Artificial Intelligence )) ; Title (author (Patrick Henry Winston)) ; Author (class (Technical AI )) ) ; Class ) Find the title (second (assoc title book ex2)) Find the author (second (assoc author book ex2)) Find the class (second (assoc class book ex2)) Which can be generalised (defun find (key object) (second (assoc key object))) (find title book ex2) (Artificial Intelligence) ; definition ; call 6
Lisp: Case Study reader readers define a reader for each key (attribute) (setf book ex2 ( (title (Artificial Intelligence )) ; Title (author (Patrick Henry Winston )) ; Author (class (Technical AI )) ) ; Class ) (defun book author (book) (second (assoc author book)) (defun book title (book) (second (assoc title book)) (defun book class (book) (second (assoc class book)) function name parameter function body Application (function call): (book author book ex2) Value (application result): (Patrick Henry Winston) 7
Lisp: Case Study constructor Constructor (note: literal symbols & parameter VALUES) (defun make book (title author class) (list (list title title ) (list author author ) (list class class ))) >(setf book ex4 ; NB this is a writer (setter) (make book (Common Lisp) (Guy Steele) (Technical Lisp))) result: ((title (Common Lisp)) (author (Guy Steele)) (class (Technical Lisp))) 8
Lisp: Case Study constructor the constructor may be used in a writer or to create a DB of books (setf book ex make book( )) ; writer (list (make book ( ) (make book ( ) ) ; create DB This list can in turn be Transformed list of author names Filtered according to some predicate All fiction books ; selection (row) All authors ; projection (col) 9
Lisp: Case Study writer Writers >(setf book ex4 (make book '(Common Lisp) '(Guy Steele) '(Technical Lisp)) ) ((TITLE (COMMON LISP)) (AUTHOR (GUY STEELE)) (CLASS (TECHNICAL LISP))) >(defun book author writer (book author) (if (eql 'author (first (first book))) (cons (list 'author author) (rest book)) (cons (first book) (book author writer (rest book) author))) ) >(setf book ex4 (book author writer book ex4 '(Guy L Steele))) ((TITLE (COMMON LISP)) (AUTHOR (GUY L STEELE)) (CLASS (TECHNICAL LISP))) 10
Lisp: Case Study: Book Collection The Library Artificial Intelligence Patrick Henry Winston Technical AI Common Lisp Guy L Steele Technical Lisp Moby Dick Herman Melville Fiction Tom Sawyer Mark Twain Fiction The Black Orchid Rex Stout Fiction Mystery 11
Lisp: Case Study projection >(defun list authors (books) (if (endp books) nil ; empty list (cons (book author (first books)) ) ) >(list authors books) ; head / tail (list authors (rest books)) ) ; (cons A B) ((PATRICK HENRY WINSTON) (GUY L STEELE) (HERMAN MELVILLE) (MARK TWAIN) (REX STOUT)) 12
Lisp: Case Study selection Find all the books in class fiction >(defun book class (book) (second (assoc 'class book))) >(book class (third books)) (fiction) >(defun fictionp (book) (member 'fiction (book class book)) ) >(fictionp (third books)) (fiction) Now use a programming cliché 13
Lisp: Case Study selection >(defun list fiction books (books) (cond ((endp books) nil) ; empty list? ((fictionp (first books)) ; is fiction? (cons (first books) ; yes include (list fiction books (rest books)))) (t (list fiction books (rest books))) )) ; otherwise ; no omit 1 2 3 ; (1) empty list (2) first book is fiction (3) default (t = true) cond is if (A) expra elsif (B) exprb else expr_default (logical switch!) (cond (predicate1 expr1) (predicate2 expr2) (t expr_default)) 14
Lisp: Case Study selection >(list fiction books books) (((TITLE (MOBY DICK)) (AUTHOR (HERMAN MELVILLE)) (CLASS (FICTION))) ((TITLE (TOM SAWYER)) (AUTHOR (MARK TWAIN)) (CLASS (FICTION))) ((TITLE (THE BLACK ORCHID)) (AUTHOR (REX STOUT)) (CLASS (FICTION MYSTERY)))) >(length (list fiction books books)) ;how many? 3 15
Lisp: Case Study apply all Lisp provides primitives to perform these actions (remove (filter), count & find (first)) mapcar apply a function to each list element (mapcar # oddp (1 2 3)) (T NIL T) List authors now becomes >(mapcar # book author books) ((PATRICK HENRY WINSTON) (GUY L STEELE) (HERMAN MELVILLE) (MARK TWAIN) (REX STOUT)) 16
Lisp: Case Study count Counters: count if / count if not >(count if # fictionp books) 3 >(count if not # fictionp books) 2 17
Lisp: Case Study find/remove Finders: find if / find if not finds the first occurrence Filters: remove if / remove if not >(find if # fictionp books) ((TITLE (MOBY DICK)) (AUTHOR (HERMAN MELVILLE)) (CLASS (FICTION))) >(find if not # fictionp books) ((TITLE (ARTIFICIAL INTELLIGENCE)) (AUTHOR (PATRICK HENRY WINSTON)) (CLASS (TECHNICAL AI))) >(remove if # fictionp books) (((TITLE (ARTIFICIAL INTELLIGENCE)) (AUTHOR (PATRICK HENRY WINSTON)) (CLASS (TECHNICAL AI))) ((TITLE (COMMON LISP)) (AUTHOR (GUY L STEELE)) (CLASS (TECHNICAL LISP)))) >(remove if not # fictionp books) (((TITLE (MOBY DICK)) (AUTHOR (HERMAN MELVILLE)) (CLASS (FICTION))) ((TITLE (TOM SAWYER)) (AUTHOR (MARK TWAIN)) (CLASS (FICTION))) ((TITLE (THE BLACK ORCHID)) (AUTHOR (REX STOUT)) (CLASS (FICTION MYSTERY)))) 18
Lisp: Case Study: final version (defun make book (title author class) (defun baw (book author) (list (list 'title title) (if (eql 'author (first (first book))) (list 'author author) (cons (list 'author author) (rest book)) (list 'class class) )) (cons (first book) (baw (rest book) author))))) (defun book title (book) (second (assoc 'title book)) ) (defun book author (book) (second (assoc 'author book)) ) (defun book class (book) (second (assoc 'class book)) ) (defun fictionp (book) (member 'fiction (book class book)) ) (mapcar # <function> books) ; apply <function> to each element (remove if # <predicate> books) ; filter (find if # <predicate> books) ; find first (count if # <predicate> books) ; count 19
Lisp: Case Study Lisp constructs primitive functions first, rest association list (assoc) setf mapcar remove if remove if not find if find if not count if count if not Clichés (patterns) Constructor Reader Writer Filter Find Count Apply function to each list element (mapcar) 20