CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
1
CSCI 2210: Programming in Lisp
Programming TechniquesData StructuresMore Built-in Functions
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
2
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
3
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
4
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
5
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
6
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
7
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
8
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
9
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
10
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
11
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
12
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)))) Course Name Instructor Credit Hours Department
CSCI220001 Programming in C++ Louis ZiantzCSCI221001 Programming in Lisp Alok MehtaCSCI222001 Programming in Java Alok MehtaCSCI223001 Programming in Perl Louis Ziantz
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
13
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
14
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
15
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)) 2SQL: 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
16
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
17
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
18
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
19
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
20
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
21
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
22
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
23
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
24
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
25
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
26
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
27
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
C
D
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
28
N-ary Tree DS Using Lists
3 -A ry Tree
A 1 A 2 A 3
A
B 1 B 2 B 3
B
C 1 C 2 C 3
C
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
29
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
30
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
31
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
32
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
33
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))
A
B
C
D
CSCI 2210 - Programming in Lisp; Instructor: Alok Mehta; 3_structs.ppt
34
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
35
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
36
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
37
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
38
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
39
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
40
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
41
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 valuesCourse 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)