home *** CD-ROM | disk | FTP | other *** search
- Path: bloom-beacon.mit.edu!uhog.mit.edu!nntp.club.cc.cmu.edu!cantaloupe.srv.cs.cmu.edu!mkant
- From: mkant+@cs.cmu.edu (Mark Kantrowitz)
- Newsgroups: comp.lang.lisp,comp.lang.clos,news.answers,comp.answers
- Subject: FAQ: Object-oriented Programming in Lisp 5/7 [Monthly posting]
- Supersedes: <LISP_5_782031621@CS.CMU.EDU>
- Followup-To: poster
- Date: 13 Nov 1994 08:01:49 GMT
- Organization: Carnegie-Mellon University, School of Computer Science
- Lines: 600
- Approved: news-answers-request@MIT.Edu
- Distribution: world
- Expires: 25 Dec 1994 08:00:25 GMT
- Message-ID: <LISP_5_784713625@CS.CMU.EDU>
- References: <LISP_4_784713625@CS.CMU.EDU>
- Reply-To: ai+lisp-faq@cs.cmu.edu
- NNTP-Posting-Host: glinda.oz.cs.cmu.edu
- Summary: Questions about CLOS, PCL and object-oriented programming in Lisp
- Xref: bloom-beacon.mit.edu comp.lang.lisp:7455 comp.lang.clos:1246 news.answers:29286 comp.answers:8319
-
- Archive-name: lisp-faq/part5
- Last-Modified: Thu Oct 20 21:47:27 1994 by Mark Kantrowitz
- Version: 1.51
- Maintainer: Mark Kantrowitz and Barry Margolin <ai+lisp-faq@cs.cmu.edu>
- URL: http://www.cs.cmu.edu:8001/Web/Groups/AI/html/faqs/lang/lisp/top.html
- Size: 29242 bytes, 608 lines
-
- ;;; ****************************************************************
- ;;; Answers to Frequently Asked Questions about Lisp ***************
- ;;; ****************************************************************
- ;;; Written by Mark Kantrowitz and Barry Margolin
- ;;; lisp_5.faq
-
- This post contains Part 5 of the Lisp FAQ. It is cross-posted to the
- newsgroup comp.lang.clos because it contains material of interest to
- people concerned with CLOS, PCL and object-oriented programming in
- Lisp. The other parts of the Lisp FAQ are posted only to the
- newsgroups comp.lang.lisp and news.answers.
-
- If you think of questions that are appropriate for this FAQ, or would
- like to improve an answer, please send email to us at ai+lisp-faq@cs.cmu.edu.
-
- CLOS/PCL Questions (Part 5):
-
- [5-0] What is CLOS (PCL) and where can I get it?
- How do you pronounce CLOS? What is the Meta-Object Protocol (MOP)?
- [5-1] What documentation is available about object-oriented
- programming in Lisp?
- [5-2] How do I write a function that can access defstruct slots by
- name? I would like to write something like
- (STRUCTURE-SLOT <object> '<slot-name>).
- [5-3] How can I list all the CLOS instances in a class?
- [5-4] How can I store data and CLOS instances (with possibly circular
- references) on disk so that they may be retrieved at some later
- time? (Persistent Object Storage)
- [5-5] Given the name of a class, how can I get the names of its slots?
- [5-6] Free CLOS software.
- [5-7] Common CLOS Blunders
-
- Search for \[#\] to get to question number # quickly.
-
- In general, questions about object oriented programming in Lisp,
- especially questions about using CLOS or compiling PCL, should be
- directed to the newsgroup comp.lang.clos.
-
- ----------------------------------------------------------------
- Subject: [5-0] What is CLOS (PCL) and where can I get it?
- How do you pronounce CLOS?
-
- CLOS (Common Lisp Object System) is the object-oriented programming
- standard for Common Lisp. It is the successor to Symbolics FLAVORS and
- Xerox LOOPS (Lisp Object Oriented Programming System). The acronym
- CLOS is pronouned either as "See-Loss" or "Closs", depending on taste.
- PCL (Portable Common Loops) is a portable CLOS implementation, and is
- available by anonymous ftp from
- parcftp.xerox.com:/pub/pcl/ [13.1.64.94]
- Also in the same directory are sources for CLX R5 and an inspecter.
-
- Most Common Lisp implementations now include their own CLOS
- implementations. Common Lisp implementations with native CLOS include:
- MCL, {A}KCL, Allegro CL (including Allegro CL\PC), Ibuki, Lucid,
- Medley, Symbolics Genera, CLOE, and Harlequin Lispworks. CMU CL uses a
- customized version of PCL as their CLOS. However, not all native CLOS
- implementations have as detailed a meta-object protocol as PCL. For
- example, MCL 2.0 users sometimes use the july-1d version of PCL
- instead of the native CLOS for precisely this reason.
-
- The book ``The Art of the Metaobject Protocol'' (see below) includes
- the CLOS Metaobject Protocol specification as chapters 5 and 6. The
- sources for the MOP spec itself are available from
- parcftp.xerox.com:/pub/pcl/mop/ [13.1.64.94]
- as the file spec.tar.Z, but this is no substitute for buying the
- book, since the book contains a lot of useful explanatory material
- beyond the spec. The Closette files related to the book are also
- available from parcftp as the file closette.lisp.
-
- The CLOS code repository is available by anonymous ftp to
- nervous.cis.ohio-state.edu:/pub/lispusers/clos/ [128.146.61.200]
- If you've got code you'd like to add to the repository, send mail to
- Arun Welch, commonloops-request@cis.ohio-state.edu.
-
- ----------------------------------------------------------------
- Subject: [5-1] What documentation is available about object-oriented
- programming in Lisp?
-
- Books about object-oriented programming in Lisp include:
-
- 1. dpANS CL describes the entire Common Lisp language, which includes the
- CLOS standard. Informally, CLtL2 can also be used to learn about CLOS,
- but please remember that CLtL2 is not an official X3J13 committee
- document. (The presentation of CLtL2 differs from that of the draft
- proposed standard, and some matters of fact have changed in the proposed
- standard since the publication of CLtL2.)
-
- 2. Sonya E. Keene
- "Object-Oriented Programming in Common Lisp:
- A Programmer's Guide to CLOS"
- Addison-Wesley (Reading, MA), 1989. 266 pages. ISBN 0-201-17589-4.
- Tutorial introduction to CLOS with many examples and
- a lot of good advice for designing large programs using CLOS.
-
- 3. Jo A. Lawless and Molly M. Miller.
- "Understanding CLOS: the Common Lisp Object System"
- Digital Press, 1991. 192 pages.
-
- 4. Gregor Kiczales, Jim des Rivieres, and Daniel G. Bobrow.
- "The Art of the Metaobject Protocol"
- MIT Press, 1991. 335 pages. ISBN 0-262-61074-4, $34.95.
- The first part of the book presents a model CLOS implementation,
- introduces the basic principles of metaobject protocols, and
- works through the key elements of the CLOS Metaobject Protocol.
- The second half is the detailed specification of the CLOS
- Metaobject Protocol. A simple working interpreter suitable
- for experimentation is contained in an appendix.
-
- 5. Robert R. Kessler and Amy R. Petajan.
- "LISP, Objects, and Symbolic Programming"
- Scott, Foresman and Company (Glenview, IL), 1988. 644 pages.
- Includes a small Lisp compiler.
-
- 6. A short introduction to CLOS written by Jeff Dalton of the
- University of Edinburgh <J.Dalton@ed.ac.uk> is available by
- anonymous ftp from
- aiai.ed.ac.uk:/lisp/random [192.41.104.6]
- as the file clos-guide.
-
- 7. Andreas Paepcke, editor.
- "Object-Oriented Programming: The CLOS Perspective"
- MIT Press, 1993. 400 pages, ISBN 0-262-16136-2 ($40).
- This book is a collection of essays on the following topics:
- - Description of CLOS and its design philosophy.
- - The Metaobject Protocol and its use.
- - Comparison of CLOS with Smalltalk, Eiffel, Sather, and C++.
- - CLOS Uses and Methodology. Descriptions of two large CLOS
- applications (Sun's LispView and a hybrid knowledge
- representation tool) and an approach to documenting
- object-oriented protocols (similar to that of AMOP).
- - Implementation details. Descriptions of TI CLOS for the
- Explorer and PCL's method dispatch mechanism.
-
- ----------------------------------------------------------------
- Subject: [5-2] How can I write a function that can access defstruct slots
- by name? I would like to write something like
- (STRUCTURE-SLOT <object> '<slot-name>).
-
- There is currently no portable, built-in way to access structure slots
- given only the name. If your Common Lisp includes an implementation
- of CLOS that supports the meta-object protocol specified in the
- original X3J13 draft spec (document X3J13/88-003), then it probably will
- allow (SLOT-VALUE <object> '<slot-name>); however, not all
- implementations of CLOS currently provide this. Lacking this, some
- implementations may provide implementation-dependent functions that
- allow access to structure slots by name; note that this may cause
- saved images to be larger, as some implementations normally open-code
- structure accessors and discard slot name information.
-
- While it is not possible to write a fully general STRUCTURE-SLOT function,
- it is not very difficult to write version that handles specific structure
- types. For instance, after defining:
-
- (defstruct spaceship name captain position velocity)
-
- one may then define:
-
- (defun spaceship-slot (spaceship slot-name)
- (ecase slot-name
- (name (spaceship-name spaceship))
- (captain (spaceship-captain spaceship))
- (position (spaceship-position spaceship))
- (velocity (spaceship-velocity spaceship))))
-
- or using CLOS (generic functions):
-
- (defgeneric spaceship-slot (spaceship slot-name)
- (:method ((x spaceship) (slot (eql :name)))
- (spaceship-name x))
- (:method ((x spaceship) (slot (eql :captain)))
- (spaceship-captain x))
- (:method ((x spaceship) (slot (eql :position)))
- (spaceship-position x))
- (:method ((x spaceship) (slot (eql :velocity)))
- (spaceship-velocity x)))
-
- Another popular way to define this is:
-
- (defun spaceship-slot (spaceship slot-name)
- (funcall (symbol-function
- (find-symbol (format nil "SPACESHIP-~A" slot-name)
- #.(package-name *package*)))
- spaceship))
-
- I personally recommend the first version. It is likely to be much faster
- and more memory efficient than the second version. It's also easy to get
- the second one wrong; many people forget to specify the package argument to
- FIND-SYMBOL, which can cause incorrect results when the package at run time
- is different from the one at compile time. Even my version assumes that
- SPACESHIP-SLOT is being defined in a file that is in the same package as
- the one containing the structure definition; if this isn't the case,
- #.(PACKAGE-NAME *PACKAGE*) should be replaced by a string naming the
- correct package.
-
- Another workaround is to define a MY-DEFSTRUCT macro that parses the
- defstruct arguments and expands into a call to DEFSTRUCT along with a
- definition of the runtime slot-accessor function.
-
- Some non-portable techniques include the use of SYSTEM:STRUCTURE-REF
- in Lucid (LCL:STRUCTURE-REF in earlier versions of Lucid) and
- EXCL:STRUCTURE-REF in Allegro.
- ----------------------------------------------------------------
- Subject: [5-3] How can I list all the CLOS instances in a class?
-
- There is no built-in way to enumerate the instances of a class. If you are
- only interested in listing the instances of classes that you have defined,
- it is not very difficult to implement it as part of your class definition.
- Add a shared slot, e.g. ALL-INSTANCES, with an initial value of NIL, to the
- class definition. Then write an after-method on INITIALIZE-INSTANCE for
- this class, which pushes the instance being initialized onto ALL-INSTANCES.
- Note that this must be done separately for each class that wants to maintain
- such a list; it can't be encapsulated in a mixin class, because all its
- dependent classes would share the same ALL-INSTANCES slot. A compromise
- would be to use a mixin to define the INITIALIZE-INSTANCE after-method (and
- any other general-purpose methods that use the slot), but not the shared
- slot; it would be up to the descendant classes to define the slot at the
- level of the class hierarchy that is appropriate. You could also try
- defining the classes that need instance-recording as instances of a
- metaclass that holds the instance registry on the class object. The
- recording behavior could then be built-in to an after method on
- initialize-instance for the root class of the metaclass, or even
- allocate-instance. To allow for garbage collection of old instances,
- you will also need to define a generic function to remove the recorded
- instances from the list of instances.
- ----------------------------------------------------------------
- Subject: [5-4] How can I store data and CLOS instances (with possibly
- circular references) on disk so that they may be
- retrieved at some later time? (Persistent Object Storage)
-
- There are two approaches to CLOS object persistence. The first uses
- regular CLOS facilities in concert with a standard file system. The
- second uses a more sophisticated storage facility, such as a database.
- The first solution provides just the persistence, and usually cannot
- retrieve only some of the objects from disc. The second goes beyond this
- by providing some or all of the facilities typically associated with
- databases: transaction management, concurrency control, queries,
- selective object materialization, etc. Below, the two solutions are
- addressed in turn.
-
- There are two main techniques for the file system solution. The first
- involves using #. to compile the data into a file. The second
- produces an ASCII representation which, when evaluated, will reproduce
- an equivalent set of data.
-
- If the data you wish to save is stored in the variable *hash-table*,
- create a file containing just the lines
- (in-package "YOUR-PACKAGE")
- (setq *hash-table* '#.*hash-table*)
- and compile it. The #. macro performs read-time evaluation of the
- expression following the dot, and so this compiles the data into the
- file. You may then load the file to restore the data. However, the
- resulting binary file is not portable between Lisp implementations,
- and sometimes not even for the same Lisp on different platforms. Also,
- some Lisps will treat the data as constant, and place it on pages in
- memory that are marked read-only (after it is loaded). If one tries to
- later modify the data, these Lisps will signal an error. Lucid CL only
- puts such constants in a read-only area when they appear inside
- functions, so this should be safe. Allegro CL doesn't seem to complain
- about modification if the data is a cons. DEC's VAXLisp, however, has
- problems with #. circular structures in .fas files. MCL seems to work
- well with using #. to save data (and even functions) to a file.
-
- The other technique is to produce an ASCII representation of the Lisp
- objects which may then be saved to a file. To reproduce the data, one
- can load (or compile and load) the file. This technique is portable
- between different Lisps and platforms. Unfortunately, the resulting
- data is not necessarily EQ to the original. Kerry Koitzsch's
- save-object.lisp package is included in the Lisp Utilities Repository,
- ftp.cs.cmu.edu:/user/ai/lang/lisp/code/ext/save_obj/
- The Lisp Utilities Repository is described in detail in the answer to
- question [6-1].
-
- See also the discussion of MAKE-LOAD-FORM and MAKE-LOAD-FORM-SAVING-SLOTS
- in CLtL2.
-
- Here are some solutions to object persistence that use databases instead
- of file systems.
-
- Free Persistent Object Storage systems include:
-
- WOOD (William's Object Oriented Database) is a simple persistent
- object store for MCL 2.0, written by Bill St. Clair
- <bill@cambridge.apple.com>. Its goal is to provide a way to
- save/restore Lisp objects to/from disk. It is available by anonymous
- ftp from the MCL repository on cambridge.apple.com:/pub/MCL2/CONTRIB/.
- Send bug reports to bug-wood@cambridge.apple.com. To be added to the
- mailing list, send mail to info-wood-request@cambridge.apple.com.
-
- PCLOS is a persistent object store for CLOS that was implemented using
- CLOS's metaobject protocol. It allowed multiple different storage
- facilities to be used. The benefit of this approach is it lets you use
- different storage facilities depending on your needs, ranging from a
- full-blown database with concurrency control and recovery to a very
- fast store that trades speed for functionality. For example, an
- in-memory store that saves its state to disk periodically can be much
- faster than traditional databases, but risks loss of data due to
- crashes. Unfortunately, PCLOS was built on a very old version of CLOS,
- so it is unusable in its current form, and there are no plans to
- update it. The introductory MOP chapter in the book "Object-Oriented
- Programming: The CLOS Perspective" (see [5-1] above) explains how to
- do the rewrite in principle and shows how the CLOS MOP was used for
- object persistence in PCLOS. See also
- 1. Andreas Paepcke, "PCLOS: A Flexible Implementation of CLOS
- Persistence", in Proceedings of ECOOP-88, S. Gjessing and K.
- Nygaard, editors, Lecture Notes in Computer Science, Springer
- Verlag, pages 374-389, 1988. [Explains the PCLOS architecture.]
- 2. Andreas Paepcke, "PCLOS: A Critical Review", in OOPSLA-89, 1989.
- [Uses PCLOS as a roadmap through the issues of object persistence.]
- 3. Andreas Paepcke, "PCLOS Reference Manual", Hewlett-Packard
- Laboratories, December, 1991.
- For more information about PCLOS, write to Andreas Paepcke
- <paepcke@parc.xerox.com>.
-
- GBB (see [6-3]) is a blackboard architecture with persistence of a
- sort. Every object in GBB is held in RAM, and there are dump and
- restore functions. It handles distributed object delivery and
- function-call triggering of receiving processes.
-
- Commercial Persistent Object Storage systems include:
-
- AllegroStore is a high-performance object-oriented database management
- system from Franz. It offers Allegro CL users persistent object
- storage with very fast retrieval and update of object data. It
- provides query processing and transaction-based operation. Built on a
- multi-client, multi-server architecture, it permits concurrent access
- over a network to objects by multiple independent processes. It uses
- the ObjectStore ODBMS from Object Design Inc, and thus has both Lisp
- and C interfaces and is also very fast. The CLOS interface is based
- on MOP, with dynamic class/schema modification and redefinition.
- AllegroStore can handle large-scale applications with minimal impact
- on performance. It uses page-faulting and page-locking mechanisms
- instead of object locking, providing high throughput and low overhead
- for concurrent access by multiple users. Standard database features
- include deadlock detection, referential integrity, and inverse
- functions. Exception handling is integrated into the Lisp condition
- system. AllegroStore runs on Sparc, SGI, HP, RS/6000, and
- MS-Windows/NT systems. For more information, send email to
- info@franz.com, write to Franz Inc., 1995 University Avenue, Berkeley,
- CA 94704, call 1-800-333-7260, 510-548-3600, fax 510-548-8253, or
- telex 340179 WUPUBTLXSFO.
-
- ITASCA ODBMS V2.2 is a distributed active object database management
- system. ITASCA allows clients to transparently access data that is
- distributed among multiple servers. ITASCA supports full dynamic
- schema modification that can be performed during any phase of the
- software lifecycle. Applications written in dissimilar and
- incompatible languages, such as C/C++ and CLOS, can share objects through
- ITASCA. ITASCA stores methods inside the database, promoting
- reusability and maintainability. ITASCA is based on work at MCC's
- Object-Oriented and Distributed Systems Lab on the ORION system. For
- more information, write to Itasca Systems, Inc., 7850 Metro Parkway,
- Minneapolis, MN 55425, sales@itasca.com, 612-851-3155, fax 612-851-3157.
- [Clint Hyde has written a MOP CLOS interface to Itasca, which has some
- features not present in their interface. For a free copy of his source
- code, send him mail to chyde@bbn.com.]
-
- Statice is a commercial product from Symbolics, that provides a
- powerful persistent ODBMS. It runs on Symbolics Lisp Machines and soon
- on Unix boxes under Lucid.
-
- ----------------------------------------------------------------
- Subject: [5-5] Given the name of a class, how can I get the names
- of its slots?
-
- (defun class-slot-names (class-name)
- "Given a CLASS-NAME, returns a list of the slots in the class."
- (mapcar #'clos:slot-definition-name
- (clos:class-slots (find-class class-name))))
-
- (defmethod class-slot-names ((instance standard-object))
- "Given an INSTANCE, returns a list of the slots in the instance's class."
- (mapcar #'clos:slot-definition-name
- (clos:class-slots (class-of instance))))
-
- You can use CLASS-DIRECT-SLOTS instead of CLASS-SLOTS if you don't
- want inherited slots. Note that these functions are from the
- meta-object protocol specified in the original X3J13 draft spec
- (document X3J13/88-003), and may not be supported by all Lisps.
-
- ----------------------------------------------------------------
- Subject: [5-6] Free CLOS software.
-
- Software Repositories:
-
- The CLOS code repository is available by anonymous ftp to
- nervous.cis.ohio-state.edu:/pub/lispusers/clos/ [128.146.61.200]
- If you've got code you'd like to add to the repository, send
- mail to Arun Welch, commonloops-request@cis.ohio-state.edu.
- The CLOS code repository includes dag.lisp.Z and 3DGeometry.lisp.
-
- CORBA:
-
- The CORBA (Common Object Request Broker Architecture) specification's
- Dynamic Invocation Interfaces (DII) are a collection of interfaces for
- writing extensible, distributed object applications. NEC Systems
- Laboratory Inc. has contributed both C and CLOS implementations of
- these specification to the Object Management Group (OMG). The CORBA
- specification (91-8-1) is available free to OMG members, and for $50
- to non-members. To order the document, send mail to documents@omg.org,
- or write to OMG, 492 Old Connecticut Path, Framingham, MA 01701, phone
- 508-820-4300, fax 508-820-4303. The DII implementation can be
- retrieved via anonymous ftp from omg.org:/pub/ [192.67.184.64] as the
- file NEC_DII/93-1-2.tar.Z. There are three dependencies in the
- contributed DII implementations. First, the CLOS images require an
- Allegro CL license due to its use of the Lisp foreign function
- interface. Second, the C executables require Sun SparcStations, but
- they can be re-compiled and re-linked for other architectures. Third,
- the implementation of the `Invoke' DII interface is considered
- proprietary. For further information, write to Don Vines, NEC Systems
- Laboratory, Inc., C&C Software Technology Center (CSTC), 1901 Gateway
- Drive, Irving, Texas 75038, call 214-518-3486, fax 214-518-3552, or
- send email to dvines@syl.dl.nec.com.
-
- ----------------------------------------------------------------
- Subject: [5-7] Common CLOS Blunders
-
- This question is based on a document written by Marty Hall
- <hall@aplcenmp.apl.jhu.edu>. The full text of Marty's
- "Introduction to CLOS" handout is available by anonymous ftp from
- ftp.cs.cmu.edu:/user/ai/lang/lisp/doc/intro/closintr.tgz
-
- This question lists a variety of common errors that occur when writing
- CLOS code. It is extremely useful to glance through this list when
- debugging CLOS code.
-
- [A] Omitting a set of parentheses around the arglist in DEFMETHOD.
-
- For example, writing
- (defmethod Area (Sq Square) ...)
- instead of
- (defmethod Area ((Sq Square)) ...)
-
- Lisp will accept the former, and think that you have two
- unspecialized arguments instead of one argument specialized as a
- Square.
-
- [B] Missing parentheses around the slot definition list in DEFCLASS.
-
- For example, writing
- (defclass Rectangle (Polygon)
- (Width ...)
- (Height ...))
- instead of
- (defclass Rectangle (Polygon)
- ((Width ...)
- (Height ...)))
-
- Lisp will not accept the former, but the error message doesn't
- always clearly identify the problem.
-
- [C] Forgetting to include an empty slot definition list if you don't
- define local slots in DEFCLASS.
-
- For example, writing
- (defclass Square (Rectangle))
- instead of
- (defclass Square (Rectangle) ())
- Lisp will not accept the former.
-
- [D] Referring to the class name instead of the instance variable in
- DEFMETHOD.
-
- For example, writing
- (defmethod Area ((Sq Square))
- (* (Width Square) (Width Square)))
- instead of
- (defmethod Area ((Sq Square))
- (* (Width Sq) (Width Sq)))
-
- Lisp may give you a warning about an unknown free variable, but
- probably won't even do that if you type the defmethod directly into
- the Lisp Listener (Lucid doesn't). So you might not encounter a
- problem until run-time.
-
- [E] Forgetting that accessors are functions and thus could conflict
- with built-in function names.
-
- For example, writing
- (defclass Graphical-Object ()
- ((Position :accessor Position)))
- will signal an error, since you cannot redefine the built-in
- POSITION function.
-
- [F] Putting the new value last instead of first in the definition of a
- SETF method.
-
- For example, writing
- (defmethod (setf Area) ((Sq Square) (New-Area number))
- (setf (Width Sq) (sqrt New-Area)))
- instead of
- (defmethod (setf Area) ((New-Area number) (Sq Square))
- (setf (Width Sq) (sqrt New-Area)))
-
- Lisp will accept the former, causing users to be later puzzled as
- to why (setf (Area Square-1) 10) doesn't work.
-
- [G] Putting the new value last instead of first in a call to a :writer
- method.
-
- For example, given
- (defclass Circle ()
- ((Radius :reader Radius :writer Set-Radius :initform 5)))
- (setq Circle-1 (make-instance 'Circle))
- and writing
- (Set-Radius Circle-1 10)
- instead of
- (Set-Radius 10 Circle-1)
-
- [H] Confusion about documentation strings in DEFMETHOD.
-
- People often write code like
- (defmethod Area ((Rect Rectangle))
- "WIDTH times HEIGHT of the rectangle"
- (* (Width Rect) (Height Rect)))
- without clearly thinking about what this might mean. Some people
- think it will make a documentation string on the generic function that
- can be retrieved by calling (DOCUMENTATION 'Area 'function) or the
- equivalent emacs keystrokes. Others vaguely expect it to make a doc
- string on each separate method, and that the call to DOCUMENTATION
- will somehow be able to automagically figure out which method it
- applies to.
-
- In fact, Lisp won't complain about this code, with the result that the
- documentation is added to the method *object*, which beginners
- probably know nothing about.
-
- Use the :documentation entry in defgeneric to add a documentation
- string to the generic function.
-
- [I] Invalid :initargs are accepted by MAKE-INSTANCE.
-
- Many Lisp implementations will accept unknown keyword initargs without
- complaint, even at the highest safety settings.
-
- So the following code, which includes a typo of :SLOT1 instead of
- :SLOT-1 in the call to make-instance
- (defclass Foo ()
- ((Slot-1 :accessor Slot-1 :initarg :Slot-1 :initform 5)))
-
- (setq Test (make-instance 'Foo :Slot1 10))
- will not produce an error message, with the result that
- (Slot-1 Test) returns 5, not 10.
-
- This is a bug in the implementation; all implementations are
- supposed to flag this as an error.
-
- [J] Forgetting the class must exist before any method can specialize upon it.
-
- Lisp programmers are used to being able to define functions in any
- order, where even if FOO calls BAR, FOO can be defined first. But doing
- (defmethod Area ((Rect Rectangle)) ...)
- (defclass Rectangle (Polygon) ...)
- is illegal. You have to define the class first.
-
- If while trying to debug the problem, you define the class by
- evaluating the definition without reordering the code to put the
- class first, you'll only run into problems later the next time you
- try to recompile the code from scratch.
-
- Many experienced programmers put each class definition in its own
- file at the top of the file, with methods for that class after it
- in the file. Others opt to put all the class definitions for a
- program in a single file that is loaded first, with methods in files
- that are loaded later.
-
- [K] Changing a method to apply to a more general class does not
- supersede previous method.
-
- For example, suppose a user writes
- (defmethod Half-Area ((Rect Filled-Rectangle))
- (/ (Area Rect) 2))
- and then notices that this functionality could apply to all
- Rectangles, not just Filled-Rectangles. They might then change the
- class referenced in this method, under the specious intuition that by
- changing the old defintion, they are replacing it. In fact, they are
- actually adding a new, less-specific method.
-
- Now suppose that later on, they change this new method (in this
- example, by adding a call to FLOAT to avoid returning a ratio),
- (defmethod Half-Area ((Rect Rectangle))
- (float (/ (Area Rect) 2)))
- If they test it on an instance of Filled-Rectangle, they will be
- puzzled as to why their new definition appears to have not taken
- effect. But because the old definition specialized to Filled-Rectangle
- still exists, they're actually getting the old, more-specific definition.
-
- Moreover, the next time they restart a fresh Lisp and recompile
- the code, the problem will magicly disappear, since the old
- definition is no longer in the code.
-
- ----------------------------------------------------------------
- ;;; *EOF*
-
-