290 likes | 554 Views
ICS 313: Programming Language Theory. Module 11: CLOS. CLOS. Objectives: Understand basic principles of CLOS Understand similarities and differences between CLOS and other OO systems. Elements of CLOS: Classes, Instances and Slots. Classes: Common Lisp types Instances of a class:
E N D
ICS 313: Programming Language Theory Module 11: CLOS
CLOS • Objectives: • Understand basic principles of CLOS • Understand similarities and differences between CLOS and other OO systems.
Elements of CLOS: Classes, Instances and Slots • Classes: • Common Lisp types • Instances of a class: • share structure, behavior, and type • Slots: • Determine the structure of a class • Have a name and a value • Can be read and written by slot accessors • Local slots maintain a separate value for each instance • Shared slots maintain a common (class-wide) value
Elements of CLOS: Superclasses • Allow classes to be built from other classes • New class inherits structure and behavior from superclasses • Classes can inherit structure and behavior from multiple superlasses.
Generic functions • Syntactically identical to normal functions • Semantic difference I: • Normal functions specify interface and implementation • Generic functions specify only interface: implementation is distributed a set of methods. • Semantic difference II: • Implementation of a normal function does not vary from call to call. • Implementation of a generic function varies depending upon the class of its arguments. • Behavior of a generic function involves both selection and composition of methods.
Elements of CLOS: Methods • The underlying implementation of generic functions • Methods are similar to ordinary Lisp functions, but are not called directly. • Method “role” determines its part in generic fn: • Primary methods perform bulk of work. • Only one primary method is called each time a generic function is called. • Provides the return value of the generic fn. • Before methods called before the primary • After methods called after the primary • Around methods “sandwich” the primary
Elements of CLOS: Inheritance • Inheritance is the sharing of characteristics and behavior among a set of classes. • Both slots and methods can be shared among classes. • Multiple inheritance creates problem of differently defined methods or slots with the same name in different ancestors. • CLOS computes a class precedence list to determine which method to inherit: • A class always has precedence over its superclasses • The order in which classes are listed in a class definition sets their precedence
Example class hierarchy window window- window- with-label with-border primary method: refresh window Code to Clear Window Generic function after method: refresh Code to window- refresh draw border with-border after method: refresh Code to window- draw label with-label
Example refresh invocation Instance of argument window-with-label refresh implementation side effects value Implementation: primary method: refresh Code to window Clear Window after method: refresh Code to window- draw label with-label
Method combination • The process of determining the implementation associated with a generic function for a given set of arguments is called generic dispatch: • Find all applicable methods • Sort them by order of precedence • Call one or more of them • Method ordering: • All before methods in most-specific-first order • The most specific primary method • All after methods in most-specific-last order
Example: window-with-border instance • before method for window-with-border • before method for window • most specific primary method • after method for window • after method for window-with-border
Slot access and method combination • Slot accessors are simply primary methods: • (defclass triangle (shape) ((side-a :accessor side-a) (side-b :accessor side-b) (side-c :accessor side-c) (area :reader area))) • We can update the area slot automatically whenever a side changes value by defining an :after method: • (defmethod (setf side-a) :after (new-length (tri triangle)) (setf (area tri) <new area>))
Multi-methods • Methods can be written to specialize on multiple parameters. • Multi-methods allow methods to “belong” to more than one class simultaneously. basic- basic- product OS Life Adventure unix windows (defmethod install ((sw basic-product) (os basic-OS)) (restore-product sw os) (compile-product sw os) (configure-site sw os) (verify-product sw os))
Meta-object protocol • Used to define default model of OO above. • Allows implementation of alternative paradigms • Specifies: • What a subclass inherits from its superclasses • How a subclass determines the precedence of superclasses • How generic functions dispatch • Classes are themselves instances of a meta-class • Meta-classes specify the structure and behavior of classes • Meta-classes inherit structure and behavior from their super meta-classes.
CLOS vs. Java • Java does not support generic functions • Java methods analogous to CLOS methods • Java does not explicitly support member function composition • Java does not support multi-methods • Methods owned by a single class • Java does not provide a meta-object protocol • Inheritance and dispatch procedure hardwired. • Java provides access control (public, private..)
CLOS Pizza Party • Objectives: • Understand the basic mechanisms and syntax of CLOS.
Create a pizza • ;;; (editor) • (defclass pizza () ((size :initarg :size • :initform 12 • :accessor pizza-size) • (topping :initarg :topping • :initform nil • :accessor pizza-topping)) • (:documentation "A pizza"))
Try it out • ;;; (listener) • USER(3): (make-instance 'pizza) • #<PIZZA @ #xd22eae> • USER(4):
Improve printing • ;;; (editor) • (defmethod print-object ((pizza-instance pizza) stream) • "Printing procedure for pizza instances." • (format stream "~d inch pizza with toppings: ~s" • (pizza-size pizza-instance) • (pizza-topping pizza-instance)) • pizza-instance)
Example with printing • ;;; (listener) • USER(4): (make-instance 'pizza) • 12 inch pizza with toppings: NIL
A Mistake • ;;; (listener) • USER(5): (make-instance 'pizza :toppings '(anchovies peppers)) • Error: :TOPPINGS are invalid initargs to make-instance of class • #<STANDARD-CLASS PIZZA @ #xd20a9e>. The valid initargs are :SIZE :TOPPING. • [condition type: PROGRAM-ERROR] • Restart actions (select using :continue): • 0: Ignore • [1c] USER(6): :reset
Right way • ;;; (listener) • USER(7): (make-instance 'pizza • :topping '(anchovies peppers)) • 12 inch pizza with toppings: (ANCHOVIES PEPPERS)
Define subclass • ;;; (editor) • (defclass calzone (pizza) • ((crust :initarg :crust • :initform 'light • :accessor calzone-crust)) • (:documentation "A kind of pizza"))
Define printed representatin • ;;; (editor) • (defmethod print-object :after • ((calzone-instance calzone) stream) • "Printing procedure for calzone instances." • (format stream " and a ~s crust." • (calzone-crust calzone-instance)) • calzone-instance)
Try it out • ;;; (listener) • USER(5): (make-instance 'calzone) • 12 inch pizza with toppings: NIL and a LIGHT crust. • USER(6): (setf my-calzone (make-instance 'calzone)) • 12 inch pizza with toppings: NIL and a LIGHT crust. • USER(7): (setf (calzone-crust my-calzone) 'dark) • DARK • USER(8): my-calzone • 12 inch pizza with toppings: NIL and a DARK crust.
Extra Credit Homework • Modify your previous homework assignment to CLOS. • In other words, create a class called “bank” and methods that allow deposits and withdrawals by individual users. • Due on Friday at start of midterm (with other homework).