XEROX PCL 2 4 1 PCL 1 4 By: CLOSSupport.pa@Xerox.com INTRODUCTION PCL originated as a portable implementation of CommonLoops, since then we have been evolving it into an implementation of the Common Lisp Object System (CLOS) . This evolution is not complete; PCL is different from the CLOS specification in many ways. Also, PCL is known not to be debugged although we do fix all reported bugs. A copy of the current draft of the CLOS specification is included in the Lyric lispusers release, but unfortunately the best documentation is the source. For these reasons, we are supplying the PCL code primarily for those who wish to experiment with a pre-release version of what will evolve into the standard Common Lisp Object System. The following is a short, incomplete, and a bit over simplified description of some of the features of PCL and guidelines for programming in it. It is intended to be sufficient to write portable object-oriented programs that will be upwardly compatible with the future CLOS standard. For the definitive explanation of these concepts, see the CLOS specification. All the files associated with PCL should be in a PCL sub-directory. To load: Load the file LOAD-PCL, eg: (load "PCL>LOAD-PCL") BASIC TERMINOLOGY class, an object used to define a lisp data structure. Classes contain slots similar to defstruct but they inherit slots by being subclasses of superclasses. For example to define a ship that is a subclass of (i.e. whose superclass is) vehicle, and has the slots "velocity" and "position": (defclass vehicle () ()) (defclass ship (vehicle) ((velocity :initform 0) (position))) object, an instance of any lisp data structure. To make an instance of a ship called s: (setq s (make-instance 'ship)) slot, a named place in an object to hold a value. To get the velocity of the ship s say: (slot-value s 'velocity). To set the value to 1 say: (setf (slot-value s 'velocity) 1). shared slot, a slot in a class that does not appear in every instance. Instead it is like a global variable for all instances of that class. To make all clipper-ships have the same size (defclass clipper-ship (ship) ((size :allocation :class :initform 50))) instance (of a class), an object with the slots specified by its class. Objects may be inspected and passed as arguments to generic functions. To invoke a method (send a message, call a generic function) use standard function call syntax. E.g: (accelerate s). generic function, an object callable as a function (a funcallable object) that discriminates on the arguments passed to decide which method to invoke. For example: (accelerate s) would invoke a method specialized on the ship class. method, an object used to operate on instances of classes. Methods accept objects as arguments. The objects accepted must be of the class (or superclass of the class) specified in the defmethod form. To define a method on the class ship: (defmethod accelerate ((s ship)) (incf (slot-value s `velocity) 1)) specialized on a class, methods that specify a class as one of the required parameters are said to be specialized on that class. For example, the accelerate method is specialized on the ship class. The top-most superclass is T. Unspecialized required parameters are said to be specialized on T. congruent lambda list, The lambda list of all methods for a generic function must accept the same number of required and &optional parameters. The use of &allow-other-keys, &key and &rest should also be the same. Hopefully these restrictions will relax over time. multi-method, a method specialized on more than one class. method spec, a shorthand description of a method to feed to ed. E.g, (ed `(accelerate (ship)) will bring up the editor on the method specialized on ship. call-next-method, a macro used inside a method that invokes the next method, presumably a method on the super-class, and then returns. class-browser, a grapher-based "web editor" to help see the inheritance relationships among classes and to build and change classes and methods. Use it to add and delete methods. For the Lyric lispusers release it contains many unimplemented features that cause break windows. See clos-browser.tedit for details. To load: (load "clos-browser.dfasl") Grapher and SEdit are used by the browser. To browse all the classes under `object: (web:browse-class 'object). GUIDELINES AND CAVEATS * Although well proven as a methodology for building and maintaining large systems, there are space and speed limitations inherent in object programming. * PCL does not include declarative method combination (e.g. :before or :after method qualifiers) mentioned in the CLOS spec. Nor does it include the initialization protocol or the documented lambda list congruence rules. * Use setf of slot-value to initialize slots in an instance. * Congruent lambda lists mean you need to plan ahead when defining the first method. If you try to redefine a method to accept more required arguments, your new method may be shadowed by the old. * While many people have used PCL's existing meta-class protocol, it is not upward compatible with CLOS and is only documented in the PCL source. * Avoid blindly translating defstructs and RECORD declarations into classes (and avoid blindly translating functions into methods). Spend time discussing and designing appropriate classes, generic functions, and methods before writing them. * Avoid using functions internal to the PCL package. They are not part of the CLOS standard and subject to change. An exception is pcl::make-specializeable. You must first use pcl::make-specializeable if you wish to define a method that has the same name as an existing function. For example: (pcl::make-specializable 'close :arglist '(object &key abort)) * The PCL package will go away someday. It may become the CLOS package or it may be merged into CL. A global package change will be necessary. If you cl:use-package the PCL package, it should be fairly painless. Some Known bugs: * the forms to initialize shared slots (class variables) do not get evaluated. For example (defclass bar () (contents :allocation :class :initform (+1 1))) instead of having the value 2 for contents, results in the unevaluated form (+ 1 1). * In Lyric, circular structures such as class, method, and generic function objects do not automatically get garbage collected. If the instances of the classes you create do not have circular references there should be no problem. Optimization techniques for CLOS programming in general: 1. Avoid invoking generic functions inside a tight low-level loop. 2. For a tall inheritance hierarchy with lots of methods, such as something the size of a sophisticated window system, if cached method misses are causing an efficiency problem, replace calls to generic functions in critical places by functions that use typecase statements. (LIST ((PAGE NIL (PAPERSIZE LETTER STARTINGPAGE# 170) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD CENTERED) CHARLOOKS (SUPERSCRIPT 0 INVISIBLE OFF SELECTPOINT OFF PROTECTED OFF SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF EXPANSION REGULAR SLOPE REGULAR WEIGHT MEDIUM INVERTED OFF USERINFO NIL STYLE NIL) FORMATINFO NIL) (174 36 288 36) NIL) (HEADING NIL (HEADINGTYPE RUNNINGHEAD) (84 744 528 36) NIL) (TEXT NIL NIL (84 96 456 600) NIL))) (PAGE NIL (PAPERSIZE NIL . LETTER) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD CENTERED) CHARLOOKS (SUPERSCRIPT 0 INVISIBLE OFF SELECTPOINT OFF PROTECTED OFF SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF EXPANSION REGULAR SLOPE REGULAR WEIGHT MEDIUM INVERTED OFF USERINFO NIL STYLE NIL) FORMATINFO NIL) (174 36 288 36) NIL) (HEADING NIL (HEADINGTYPE RUNNINGHEAD) (84 744 528 36) NIL) (TEXT NIL NIL (84 96 456 600) NIL))) (PAGE NIL (PAPERSIZE NIL . LETTER) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD CENTERED) CHARLOOKS (SUPERSCRIPT 0 INVISIBLE OFF SELECTPOINT OFF PROTECTED OFF SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF EXPANSION REGULAR SLOPE REGULAR WEIGHT MEDIUM INVERTED OFF USERINFO NIL STYLE NIL) FORMATINFO NIL) (174 36 288 36) NIL) (HEADING NIL (HEADINGTYPE RUNNINGHEAD) (84 744 528 36) NIL) (TEXT NIL NIL (84 96 456 600) NIL))))) .ÈÈ(È(ŠŠ8(ŠŠ8DÈÈ PAGEHEADING RUNNINGHEAD((((((MODERN MODERN MODERN MODERNLOGOMODERN  HRULE.GETFNMODERN  HRULE.GETFNMODERN  HRULE.GETFNMODERN  HRULE.GETFNMODERN  HRULE.GETFNMODERN       lF        ~  ‡R   W 2  ±Š  N& ¨Ã& :ÎHø / 1]v  $&,(›ß>Æ“ó*'Øóè9C,zº