240 likes | 390 Views
66-2210-01 Programming in Lisp. Common Lisp Object System (CLOS). Association Lists. Previous lecture: Association Lists A common way to represent data (setf course-1 '( (course-number CSCI221001) (credit-hours 1) (name (Programming in Lisp)) (instructor (Alok Mehta))
E N D
66-2210-01 Programming in Lisp Common Lisp Object System (CLOS) Alok Mehta - Programming in Lisp - CLOS
Association Lists • Previous lecture: Association Lists • A common way to represent data • (setf course-1 '( • (course-number CSCI221001) • (credit-hours 1) • (name (Programming in Lisp)) • (instructor (Alok Mehta)) • (department (Computer Science)))) • Association • Pair: (<Association-Name> <Association Value>) • Example: (course-number 66221001) • Association List • A list of associations • Example: ( (course-number 66221001) (credit-hours 1) … ) Alok Mehta - Programming in Lisp - CLOS
Assoc • Assoc • Lisp procedure • Searches for a given association in a list of associations • Example: • > (assoc 'credit-hours course-1) • (credit-hours 1) • Can be used to find the value of an association • > (second (assoc 'credit-hours course-1)) • 1 • List of Associations • Common way to represent a single object (structure/record) • Object = Set of Properties • Each property is stored as an association • The set of properties is stored as a list of associations Alok Mehta - Programming in Lisp - CLOS
Simple Database • A database as a list of “records” • (setf course-database '( • ((course-number 66221001) • (credit-hours 1) • (name (Programming in Lisp)) • (instructor (Alok Mehta)) • (department (Computer Science))) • ((course-number 66220001) • (credit-hours 1) • (name (Programming in C++)) • (instructor (Louis Ziantz))) • )) • This is a List of a “List of Associations” Alok Mehta - Programming in Lisp - CLOS
Constructors, Readers, Writers • Use readers, constructors, and writers • To hide data details • Example functions written for a single course • make-course • get-course-name, get-course-number, get-course-instructor • taught-by-alok-p • Example functions written for a list of courses • get-course-numbers • get-courses-taught-by-alok • count-courses-taught-by-alok • find-first-course-taught-by-alok Alok Mehta - Programming in Lisp - CLOS
Comparison to C++ • Lisp: Free form • ((course-number 66221001) • (credit-hours 1) • (name (Programming in Lisp)) • (instructor (Alok Mehta)) • (department (Computer Science))) • C++: Well defined class • class Course { • private: • int credit_hours; • String name; • String instructor; • String department; • Course (…) // Instead of make-course • int get_credit_hours(); // Accessors • bool is_taught_by_alok (); // Other functions • }; Alok Mehta - Programming in Lisp - CLOS
CLOS • CLOS = Common Lisp Object System • Brings object oriented programming concepts to Lisp • Declare class course • > (defclass course () • ((course-number :accessor course-number • :initarg :course-number • :initform NIL) • (credit-hours :accessor credit-hours • :initarg :credit-hours • :initform 3) • (instructor :accessor instructor • :initarg :instructor • :initform NIL) • (department :accessor department • :initarg :department • :initform NIL))) • Defclass automatically creates readers, constructors, writers • Can extend pre-written operations with your own methods Alok Mehta - Programming in Lisp - CLOS
Predefined constructor • Make-instance: Predefined constructor • Example • > (setf c1 (make-instance 'course • :course-number 66221001 • :instructor '(Alok Mehta) • :department '(Computer Science))) • #<COURSE #xE7CA90> • Syntax • (make-instance '<class-name> • <initarg-1> <value-1> <initarg-2> <value-2> … ) • Unspecified initarg’s are set to default values • Example: credit-hours • Name of initarg is specified by “:initarg” parameter in defclass • Default value is specified by “:initform” parameter in defclass Alok Mehta - Programming in Lisp - CLOS
Accessing/Updating variables • Readers • Accessors are predefined by defclass • Name is specified by “:accessor” parameter in defclass • > (department c1) • (Computer Science) • > (credit-hours c1) • 3 • Writers • Mechanism to update variables is to use setf with the accessor • > (setf (credit-hours c1) 1) • 1 Alok Mehta - Programming in Lisp - CLOS
Describe • Describe is used to … well, describe things • Works on almost any type of expression in Lisp • > (describe 3) ;; prints 3 is a fixnum • > (describe “Hello”) ;; Hello is a string • > (describe 'Hello2) ;; Hello2 is a symbol • > (describe '(1 2)) ;; (1 2) is a CONS • > (defun xyz () (print 'hi)) • > (describe #'xyz) ;; xyz is a code-object • > (describe c1) ;; ... is a COURSE, values… • > (describe (class-of c1)) ;; … is a STANDARD-CLASS … Alok Mehta - Programming in Lisp - CLOS
Defmethod • Defmethod - Used to define methods • Example • > (defmethod is-taught-by-alok-p ((c course)) • (equal (instructor c) '(Alok Mehta))) • Syntax • > (defmethod <method-name> ( (var1 type1) (var2 type2) … ) • <definition>) • Each variable has a type specification • The variable “c” is of type “course” • Example call • > (is-taught-by-alok-p c1) • T • C1 is an object of type “course”. • Since this matches the prototype of the defmethod, the method is called • The method runs, evaluates to “T”, and returns Alok Mehta - Programming in Lisp - CLOS
Case Study: The Throttle Class • Goal: store and manipulate the status of a simple throttle • Controls flow of fuel • Used often in small engines (e.g. lawn mower) • Functions needed • Function to set throttle to its “shutoff” position • > (shut-off t1) ;; where t1 is a throttle • Function to shift a throttle’s position by given amount • > (shift t1 -2) ;; Decrement position by 2 • Function that returns the fuel flow, as a proportion of maximum flow (current / MAX) • > (flow t1) • Function that tells whether the throttle is currently on. • > (on-p t1) ;; Is the throttle t1 on? 6 Fast 5 4 3 2 1 Slow OFF Alok Mehta - Programming in Lisp - CLOS
Lisp Code • (defclass throttle () • ((pos :initform 0 :accessor pos))) • (defmethod shut-off ((the-throttle throttle)) • (setf (pos the-throttle) 0)) • (defmethod shift ((the-throttle throttle) (amount number)) • (let ((new-pos (+ (pos the-throttle) amount))) • (cond ((< new-pos 0) (setf new-pos 0)) • ((> new-pos 6) (setf new-pos 6))) • (setf (pos the-throttle) new-pos))) • (defmethod flow ((the-throttle throttle)) • (/ (pos the-throttle) 6)) • (defmethod on-p ((the-throttle throttle)) • (> (pos the-throttle) 0)) • ;; Example calls • (setf t1 (make-instance 'throttle)) • (shut-off t1) • (shift t1 2) • (flow t1) • (on-p t1) Alok Mehta - Programming in Lisp - CLOS
Case Study: The Point Class • Store/manipulate two dimensional points • Coordinates (x,y) • Initialize point • Shift (Move) a point • Rotate a point • Display a point Alok Mehta - Programming in Lisp - CLOS
C++ Point Class • C++ Class Declaration • class Point { • private: • double x; • double y; • public: • Point (); • Point (double initial_x, double initial_y); • void initialize (double new_x, double new_y); • void move (double dx, double dy); • void rotate90(); /* Rotate clockwise */ • double get_x () const { return x; } • double get_y () const { return y; } • }; Alok Mehta - Programming in Lisp - CLOS
Methods of Point • Lisp code for handling points • (defclass point () • ((x :initform 0 :accessor x :initarg :x) • (y :initform 0 :accessor y :initarg :y))) • (defmethod initialize ((p point) (newx number) (newy number)) • (setf (x p) newx) (setf (y p) newy) p) • (defmethod move ((p point) (dx number) (dy number)) • (setf (x p) (+ (x p) dx)) (setf (y p) (+ (y p) dx)) p) • (defmethod rotate-90 ((p point)) • (let ( (newx (y p)) (newy (- (x p))) ) • (setf (x p) newx) • (setf (y p) newy)) • p) • Question: Why is p returned by each method? • How would you rotate 180? Alok Mehta - Programming in Lisp - CLOS
Case Study: Line class • (defclass g-line () • ((p1 :accessor p1 • :initarg :p1 • :initform (make-instance 'point)) • (p2 :accessor p2 • :initarg :p2 • :initform (make-instance 'point)))) • (defmethod initialize-gline ((l g-line) • (x1 number) (y1 number) (x2 number) (y2 number)) • (initialize (p1 l) x1 y1) • (initialize (p2 l) x2 y2) • l) • (defmethod move ((l g-line) (dx number) (dy number)) • (move (p1 l) dx dy) • (move (p2 l) dx dy) • l) • (defmethod rotate-90 ((l g-line)) • (rotate-90 (p1 l)) • (rotate-90 (p2 l)) • l) Alok Mehta - Programming in Lisp - CLOS
Using Lines, Points • (setf p (make-instance 'point :x 3 :y 4)) • (initialize p 88 99) • (move p -5 -5) • (setf l1 (make-instance 'g-line)) • (initialize-gline l1 3 4 89 33) • (move l1 -1 -1) ;; Sets L1 coords to (2,3), (88,32) • ( x (p2 l1) ) ;; Get the x value of point p2 of line l1 • (setf (x (p2 l1)) 99) ;; Set l1.p2.x = 99 Alok Mehta - Programming in Lisp - CLOS
Polymorphism - Display Method • Method to display a Point • > (defmethod display ((p point)) • (list (x p) (y p))) • Example Call • > (display p) • (83 94) • Method to display a Line • > (defmethod display ((l g-line)) • (list (display (p1 l)) (display (p2 l)))) • Example Call • > (display l1) • ( (2 3) (99 32) ) • The “display” method • Determines the appropriate definition to invoke • Based on the type of object being displayed (polymorphism) Alok Mehta - Programming in Lisp - CLOS
Using Lines, Points • Create some points • (setf pA (make-instance 'point :x 0 :y 0)) • (setf pB (make-instance 'point :x 1 :y 1)) • (setf pC (make-instance 'point :x 2 :y 2)) • Create lines, initializing points explicitly • (setf l2 (make-instance 'g-line :p1 pA :p2 pB)) • (setf l3 (make-instance 'g-line :p1 pB :p2 pC)) • Move lines • (move l2 -1 -1) • (move l3 -1 -1) • Display line coordinates • (display l2) • (display l3) • This doesn’t work as expected! • pB is a SHARED object • Move operation is applied twice on pB Alok Mehta - Programming in Lisp - CLOS
Calculate Distances, Midpoints • Distance between two points • (defmethod distance ((p1 point) (p2 point)) • (let ((a (- (x p1) (x p2))) • (b (- (y p1) (y p2)))) • (sqrt (+ (* a a) (* b b))))) • (setf p2 (make-instance 'point :x 2 :y 2)) • (setf p3 (make-instance 'point :x 4 :y 4)) • (distance p2 p3) ;; Example call • Distance between a point and a line • (defmethod distance ((p point) (l g-line)) • … • ) • Midpoint between two points • (defmethod midpoint ((p1 point) (p2 point)) • (make-instance 'point • :x (/ (+ (x p1) (x p2)) 2.0) • :y (/ (+ (y p1) (y p2)) 2.0))) Alok Mehta - Programming in Lisp - CLOS
Inheritance • CLOS supports inheritance • Example • Document - DocumentName, Author, Editor, • AccessDocument(), Copy() OnLine ManPage - UnixCommandName HLPFile - FileName WWWPage - HttpAddress PrintedDoc - Publisher, nPage, ISBN Paperback Magazine Hardcover Alok Mehta - Programming in Lisp - CLOS
CLOS class definition stubs • Definition of classes to set up example hierarchy • (defclass document () (documentName author editor)) • (defclass online (document) ()) • (defclass manpage (online) (commandName)) • (defclass HLPFile (online) (fileName)) • (defclass WWWPage (online) (httpAddress)) • (defclass printeddoc (document) (publisher nPage ISBN)) • (defclass paperback (printeddoc) ()) • (defclass magazine (printeddoc) ()) • (defclass hardcover (printeddoc) ()) • Note • CLOS supports multiple inheritance Alok Mehta - Programming in Lisp - CLOS
Creating/manipulating instances • Creating and manipulating instances • (setf a (make-instance 'hardcover)) • (describe a) • #<HARDCOVER #xE79338> is a HARDCOVER: • DOCUMENTNAME: unbound • AUTHOR: unbound • EDITOR: unbound • PUBLISHER: unbound • NPAGE: unbound • ISBN: unbound • (setf (slot-value a 'isbn) 'ISBN-0-201-08319-1) • (slot-value a 'isbn) • ISBN-0-201-08319-1 • (slot-value a 'editor) • ** Error: Unbound slot ** • (slot-boundp a 'editor) • NIL • (slot-boundp a 'isbn) • T Alok Mehta - Programming in Lisp - CLOS