410 likes | 593 Views
CSCI 2210: Programming in Lisp. Programming Techniques Data Structures More Built-in Functions. Functional Programming. Functional Programming Writing programs that return values Instead of modifying things (side effects) Avoid things like setf Dominant paradigm in Lisp
E N D
CSCI 2210: Programming in Lisp Programming TechniquesData StructuresMore Built-in Functions CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Functional Programming • Functional Programming • Writing programs that return values • Instead of modifying things (side effects) • Avoid things like setf • Dominant paradigm in Lisp • Allows interactive testing • Can immediately test anything at any time • Don't have to worry that it will mess up some "state" • Don't have long edit-compile-run cycle • Compare this to testing in other languages CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Functions as Objects • Functions are regular objects • Function • Returns the object associated with the function • > (function +) • #<Compiled-Function + 17BA4E> • Can use #' macro as a convenience • > #'+ • #<Compiled-Function + 17BA4E> • Example • > (funcall #'+ 1 2 3) • > (apply #'+ '(1 2 3)) • ; Note: These are equivalent to (+ 1 2 3) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Funcall • Funcall • Template • (funcall #'<procedure> <arg1> … <argN>) • Calls the specified procedure with the given argments • Equivalent to • (<procedure> <arg1> … <argN>) • Example • > (funcall #'+ 3 2 7) ;; Same as (+ 3 2 7) • 12 • Example 2 • > (defun eval-infix (arg1 operator arg2) • (funcall operator arg1 arg2)) • > (eval-infix 3 #'+ 2) • Useful if you need to pass in a procedure name, to be applied at a future time CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Apply • Apply • Similar to Funcall • (typically) takes two arguments, • procedure object • list of arguments to be passed to procedure object • (funcall #'+ 3 2 7) ;; Same as (+ 3 2 7) • (apply #'+ '(3 2 7)) ;; Same as (+ 3 2 7) • Apply can actually take additional arguments • Extra arguments are combined into a single list • Following are equivalent • (apply #'+ '(1 2 3 4 5 6)) • (apply #'+ 1 2 3 '(4 5 6)) • Argument fed to + is (append (list 1 2 3) ‘(4 5 6)) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Data Representation Using Lists • Record information about courses • Basic definition • > (setf lisp-course-info '(CSCI221001 ; course number • (Programming in Lisp) ; course name • (Alok Mehta) ; instructor • (Computer Science))) ; department • (CSCI221001 (PROGRAMMING IN LISP) … ) • What is the name of the course ‘lisp-course-info’? • > (second lisp-course-info) • (PROGRAMMING IN LISP) • Poor practice - Depends on the ordering of the list • What if the order changes, or you need to add something CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Modified Course Structure • Example, if we need to add credit hours information • (setf lisp-course-info '(CSCI221001 • 1 ; Credit hours • (Programming in Lisp) ; Course name • (Alok Mehta) ; Instructor • (Computer Science))) ; Department • All programs that access name of course-1 have to change from using SECOND to using THIRD • > (third lisp-course-info) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Association Lists • Better way to represent data: Association Lists • (setf lisp-course-info '( • (course-number CSCI221001) • (credit-hours 1) • (name (Programming in Lisp)) • (instructor (Alok Mehta)) • (department (Computer Science)))) • What is the name of ‘lisp-course-info’? • > (second (third lisp-course-info)) • (PROGRAMMING IN LISP) • > (assoc 'name lisp-course-info) • (NAME (PROGRAMMING IN LISP)) • > (second (assoc 'name lisp-course-info)) • (PROGRAMMING IN LISP) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Simple Database • A database as a list of “records” • (setf course-database '( • ((course-number CSCI221001) • (credit-hours 1) • (name (Programming in Lisp)) • (instructor (Alok Mehta)) • (department (Computer Science))) • ((course-number CSCI220001) • (credit-hours 1) • (name (Programming in C++))) • )) • What is the name of the lisp course? • (second (assoc 'name (first course-database))) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Access Functions • Write functions to access low-level details • (defun get-course-name (course) • (second (assoc 'name course))) • Don’t have to remember how data is stored • Can change storage details easily • Access to data is achieved at a higher level • Easier to read and understand • More maintainable code • Write functions to construct and manipulate data • (defun make-course (&key course-number credit-hours • name instructor department) • (list (list 'course-number course-number) • (list 'credit-hours credit-hours) • (list 'name name) • (list 'instructor instructor) • (list 'department department) • )) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Calling Access Functions • > (setf course-1 (make-course • :name '(Programming in Java) • :instructor '(Alok Mehta))) • ((COURSE-NUMBER NIL) • (CREDIT-HOURS NIL) • (NAME (PROGRAMMING IN JAVA)) • (INSTRUCTOR (ALOK MEHTA)) • (DEPARTMENT NIL)) • > (get-course-name course-1) • (PROGRAMMING IN JAVA) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
A simple database example • (setf courses (list • (make-course :course-number 'CSCI220001 • :name '(Programming in C++) • :instructor '(Louis Ziantz)) • (make-course :course-number 'CSCI221001 • :name '(Programming in Lisp) • :instructor '(Alok Mehta)) • (make-course :course-number 'CSCI222001 • :name '(Programming in Java) • :instructor '(Alok Mehta)) • (make-course :course-number 'CSCI223001 • :name '(Programming in Perl) • :instructor '(Louis Ziantz)) • )) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Which courses are offered? • Example Usage • > (get-course-numbers courses) • (CSCI220001 CSCI221001 CSCI222001 CSCI223001) • > (defun get-course-number (course) • (second (assoc 'course-number course))) • > (defun get-course-numbers (course-list) • (if (endp course-list) • NIL • (cons (get-course-number (first course-list)) • (get-course-numbers (rest course-list))))) • Implements a “Transformation” • SQL Equivalent: • SELECT course_number • FROM courses; CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Which are taught by Alok? • List the courses taught by Alok Mehta • > (get-courses-taught-by-alok courses) • (((COURSE-NUMBER CSCI221001) …) ((COURSE-NUMBER CSCI222001) ...) ...) • (defun get-course-instructor (course) • (second (assoc 'instructor course))) • (defun taught-by-alok-p (course) • (if (equal '(Alok Mehta) (get-course-instructor course)) • t • NIL)) • (defun get-courses-taught-by-alok (course-list) • (cond • ((endp course-list) NIL) • ((taught-by-alok-p (first course-list)) • (cons (first course-list) • (get-courses-taught-by-alok (rest course-list)))) • (t (get-courses-taught-by-alok (rest course-list))))) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
How many are taught by Alok • List the courses taught by Alok Mehta [Filter] • > (get-courses-taught-by-alok courses) • Implements “Filtering” • SQL: SELECT * FROM COURSES • WHERE instructor = ‘Alok Mehta’; • How many courses are taught by Alok? [Count] • > (length (get-courses-taught-by-alok courses)) • 2 • SQL: SELECT COUNT(*) FROM COURSES • WHERE instructor = ‘Alok Mehta’; • What is the first course taught by Alok? [Find] • > (first (get-courses-taught-by-alok courses)) • ((COURSE-NUMBER CSCI221001) • (CREDIT-HOURS NIL) • (NAME (PROGRAMMING IN LISP)) • (INSTRUCTOR (ALOK MEHTA)) • (DEPARTMENT NIL)) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
More efficient way to Count • A more efficient way to count • Don’t have to get all courses first! • (defun count-courses-taught-by-alok (course-list) • (cond ((endp course-list) 0) • ((taught-by-alok-p (first course-list)) • (+ 1 (count-courses-taught-by-alok • (rest course-list)))) • (t (count-courses-taught-by-alok • (rest course-list))))) • A more efficient way to find first course • (defun find-first-course-taught-by-alok (course-list) • (cond ((endp course-list) nil) • ((taught-by-alok-p (first course-list)) • (first course-list)) • (t (find-first-course-taught-by-alok • (rest course-list))))) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Cliches • Many procedures have a common template • (defun <list-transformer> (input-list) • (if (endp input-list) • nil • (cons (<element-transformer> (first input-list)) • (<list-transformer> (rest input-list))))) • Example: • List-transformer: get-course-numbers • Element-transformer: get-course-number • (defun get-course-numbers (course-list) • (if (endp course-list) • NIL • (cons (get-course-number (first course-list)) • (get-course-numbers (rest course-list))))) • This template is frequently used • Lisp uses the primitive (MAPCAR) to make this easier CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Mapcar and Maplist • Mapcar - MAPs a function to successive CARs • Examples • > (mapcar #'(lambda (x) (* x 2)) '(1 2 3 4 5)) • (2 4 6 8 10) • > (mapcar #'= '(1 2 3) '(3 2 1)) • (NIL T NIL) • Other MAPxxxx functions • Maplist • Mapc • Mapcan CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Mapcar • MAPCAR • (mapcar <procedure> <argument>) • Applies <procedure> to each element of <argument> • Example • > (mapcar #'oddp '(1 2 3)) • (T NIL T) • > (mapcar #'get-course-number courses) • (CSCI220001 CSCI221001 CSCI222001 CSCI223001) • > (mapcar #'= '(1 2 3) '(3 2 1)) • (NIL T NIL) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Remove-If, Remove-If-Not • Remove-If, Remove-If-Not • > (remove-if-not #'taught-by-alok-p courses) • [Removes all courses for which “taught-by-alok-p” returns NIL] • This will return all courses taught by Alok • > (remove-if #'taught-by-alok-p courses) • [Removes all courses for which “taught-by-alok-p” returns non-NIL] • This will return all courses NOT taught by Alok • Count-If, Count-If-Not • > (count-if #'taught-by-alok-p courses) • Counts the number of elements for which “taught-by-alok-p” returns non-NIL • Find-If, Find-If-Not • > (find-if #'taught-by-alok-p courses) • Returns the FIRST element of courses for which “taught-by-alok-p” returns non-NIL CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Lambda • Lambda generates an unnamed function • Example • > ((lambda (x) (+ x 100)) 1) • 101 • Defines an unnamed function which takes one parameter (x), and has the body (+ x 100) • The function adds 100 to its argument • Invokes the unnamed function with a value of 1 for the paramter • The return value is 1 + 100 = 101 • Why use unnamed functions? • Analogy to Java's "anonymous" classes • Don’t have to make up names for procedures • Definition of procedure is close to where it is used CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Lambda Procedures • Useful if you need an “anonymous” procedure • Don’t want to give it a name • A named procedure • (defun taught-by-alok-p (course) • (if (equal '(Alok Mehta) (get-course-instructor course)) • t • NIL)) • An equivalent un-named procedure • (lambda (course) • (if (equal '(Alok Mehta) (get-course-instructor course)) • t • NIL)) • Example usage: How many courses are taught by Alok? • (count-if #'(lambda (course) • (if (equal '(Alok Mehta) • (get-course-instructor course)) • t • NIL)) • courses) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Lambda procedures • Advantage • Don’t have to make up names for procedures • Definition of procedure is close to where it is used • (defun get-courses-taught-by-alok (course-list) • (remove-if-not • #'(lambda (x) • (equal '(Alok Mehta) (get-course-instructor x))) • course-list)) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Data Structures Using Lists • There is no explicit pointer manipulation in Lisp • In Lists, handled automatically via cons cells • Variables are pointers to values • pointer to a cons cell; or • pointer to an atomic value • Lists • Powerful for implementing variety of data structures • Examples of data structures are on next few slides CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Linked List DS using Lists • Linked List • Copy-List • Built-in function that takes a list and returns a copy of it • > (defun our-copy-list (lst) • (if (atom lst) • lst • (cons (car lst) (our-copy-list (cdr lst))))) A B C X CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Stack DS using Lists • Push, Pop macros implement the stack data structure using Lists A B C X CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Binary Tree DS Using Lists • Cons cell of List can be used as the left/right branches of a binary tree • (a (b c) d) A B D C CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
N-ary Tree DS Using Lists CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Tree Functions • Copy-tree • Built-in function to copy a tree • Similar to Copy-List, except it does a deep recursive copy on the CAR as well as the CDR • Doubly recursive • Example implementation • > (defun our-copy-tree (tr) • (if (atom tr) • tr • (cons (our-copy-tree (car tr)) • (our-copy-tree (cdr tr))))) • Other built-in tree functions • subst, tree-equal CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Set DS Using Lists • Member • > (member 'b '(a b c)) • (B C) • > (member '(a) '((a) (z)) :test #'equal) • ((A) (Z)) • > (member 'a '((a b) (c d)) :key #'car) • ((A B) (C D)) • Adjoin - Adds an element to a set [conditional cons] • > (adjoin 'b '(a b c)) • (A B C) • > (adjoin 'z '(a b c)) • (Z A B C) • Union, Intersection, Set-Difference • > (union '(a b c) '(c b s)) • (A C B S) • > (intersection '(a b c) (b b c)) • (B C) • > (set-difference '(a b c d e) '(b e)) • (A C D) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Sequences • Sequence - an ordered series of objects • > (length '(a b c)) • 3 • > (subseq '(a b c d e f) 2 5) ; Index of A=0; B=1; ... • (C D E) ; Note: Returns elements at index X, where 2<=X<5 • > (reverse '(a b c)) • (C B A) • > (sort '(7 4 2 9) #'<) • (2 4 7 9) • > (sort '(A B C D R S C A E) #'string<) • (A A B C C D E R S) • > (every #'> '(1 3 5) '(0 2 4)) ;((1>0)&&(3>2)&&(5>4)) • T • > (some #'= '(1 3 5) '(0 3 5)) ;((1=0)||(3=3)||(5=5)) • T CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Dotted Lists • A proper list is either NIL or a CONS who's CDR is a proper list • Dotted List • Really a two-part structure • The "CDR" part doesn't point to a list • > (setf x (cons 'a 'b)) • (A . B) • > (setf x '(a . b)) ; Shorthand • (A . B) • Don't use dotted lists • Not really needed A X B CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Graph DS Using Lists • A Graph consists of vertices and edges • One way to represent a graph • ((v1 . Neighbors-of-v1) (v2 . Neighbors-of-v2) …) • Example • > (setf graph-1 '((a b c) (b c) (c d))) • ((A B C) (B C) (C D)) B D C A CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Specialized Data Structures • We've seen that Lists are extremely versatile • I said that everything in Lisp is an Atom or a List • I lied... • I sort of lied… • depends on what the meaning of Atom is… • There are many types of atoms • More efficient than Lists CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Vector • Vector - one dimensional array • > (setf x (vector "a" 'b 3)) • #("a" B 3) ; The # is a short-hand/notation for array • Vectors are atoms, not lists • > (atom x) ; A vector is an Atom • T • > (listp x) ; A vector is not a List • NIL • > (length x) ; Length works for lists and vectors • 3 • > (null (vector)) ; An empty vector #() is not NIL • NIL • AREF is used to update/access elements • > (aref x 0) ; get the zero'th element of x • "a" • > (setf (aref x 1) 'c) • C • > x • #("a" C 3) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Example: Binary Search • (defun bin-search (obj vec • &optional (start 0) (end (- (length vec) 1)) • &aux (range (- end start)) • (midpt (+ start (round (/ range 2))))) • (print (list obj vec start end)) ; Optional, to display • (if (> start end) • NIL ; We crossed over • (let ((obj_at_midpt (aref vec midpt))) • (cond ((equal obj obj_at_midpt) obj) ; Found • ((< obj obj_at_midpt) ; In lower half • (bin-search obj vec start (- midpt 1))) • ((> obj obj_at_midpt) ; In upper half • (bin-search obj vec (+ midpt 1) end)))))) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Multi-Dimensional Arrays • MAKE-ARRAY - Generates arrays • Has keywords :initial-element and :initial-contents • > (setf arr (make-array '(2 3))) • #2A((NIL NIL NIL) (NIL NIL NIL)) • > (setf vec (make-array 4 :initial-element 1)) • #(1 1 1 1) ; A Vector is a 1-dimensional array; note keyword parameter above • > (setf tic-tac-toe (make-array '(3 3) :initial-contents • '((- O O) • (- X X) • (- X -)))) • #2A((- O O) (- X X) (- X -)) • Aref used to reference multi-dimensional arrays • > (setf (aref tic-tac-toe 0 0) 'O) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Strings and Characters • String - A vector of characters • Character - Denoted using #\ • > (setf x "abcde") • "abcde" • > (aref x 2) • #\c • > (setf (aref x 2) #\z) • #\z • > x • "abzde" CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
User Defined Structures • Association lists were used to represent data • (setf lisp-course-info '( • (course-number CSCI221001) • (credit-hours 1) • (name (Programming in Lisp)) • (instructor (Alok Mehta)) • (department (Computer Science)))) • A more efficient - but less flexible way: • User Defined Structures • > (defstruct course ; The structure name • course-number ; The fields of the structure • (credit-hours 4) • (name (progn (format t "Course Name: ") (read))) • instructor • department) • COURSE Dflt Value = 4 Default Value = Prompt user CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Defstruct • Defines a structure with given name and fields • Automatically writes code to define functions • Constructors, type-checking • make-course, course-p, copy-course • Field access/update • course-course-number, course-credit-hours, course-name, course-instructor, course-department • An example of a function that generates functions • There is no equivalent analogy for C/C++, Java, etc. • You can write functions like Defstruct • CLOS - Common Lisp Object System CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
Using Course Structure • Examples of using the course defstruct • > (setf c2 (make-course • :credit-hours 1 • :name '(Programming in Lisp))) • #S(COURSE :COURSE-NUMBER NIL :CREDIT-HOURS 1 :NAME (PROGRAMMING IN LISP) :INSTRUCTOR NIL :DEPARTMENT NIL) • > (setf c1 (make-course)) ; Uses default values • Course Name: (Programming in C++) • #S(COURSE :COURSE-NUMBER NIL :CREDIT-HOURS 4 :NAME (PROGRAMMING IN C++) :INSTRUCTOR NIL :DEPARTMENT NIL) • > (setf (course-instructor c2) '(Alok Mehta)) • (ALOK MEHTA) CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt