On Wed, May 24, 2006 at 06:02:18PM -0500, Matthew D Swank wrote:
> In that case, why does sbcl even allow my method to be defined?
Because there is no locking mechanism (like package locks) for
specialization on standardized generic functions. Patches welcome! :)
> What use is a print-object method (my extension, or the standard
> mandated one) that doesn't hook into the lisp printer?
I believe the intent is to allow for greater implementation choice on how
primitive objects are printed. (For example, to allow for a low-level
fast path for standardized common objects that doesn't involve method
dispatch.) Keep in mind that SBCL (and CMUCL, from which it came)
spend most of their boostrapping lives without a CLOS implementation,
and they still need to print objects somehow.
Whether this is wise (in the specification or in an implementation)
is something I don't know enough to comment on.
For more insight, look at OUTPUT-UGLY-OBJECT in src/code/print.lisp.
;; KLUDGE: The TYPECASE approach here is non-ANSI; the ANSI definition of
;; PRINT-OBJECT says it provides printing and we're supposed to provide
;; PRINT-OBJECT methods covering all classes. We deviate from this
;; by using PRINT-OBJECT only when we print instance values. However,
;; ANSI makes it hard to tell that we're deviating from this:
;; (1) ANSI specifies that the user isn't supposed to call PRINT-OBJECT
;; (2) ANSI (section 18.104.22.168.2) says it's undefined to define
;; a method on an external symbol in the CL package which is
;; applicable to arg lists containing only direct instances of
;; standardized classes.
;; Thus, in order for the user to detect our sleaziness in conforming
;; code, he has to do something relatively obscure like
;; (1) actually use tools like FIND-METHOD to look for PRINT-OBJECT
;; methods, or
;; (2) define a PRINT-OBJECT method which is specialized on the stream
;; value (e.g. a Gray stream object).
;; As long as no one comes up with a non-obscure way of detecting this
;; sleaziness, fixing this nonconformity will probably have a low
;; priority. -- WHN 2001-11-25
Patches probably welcome to fix this, too, though it won't neccessarily
make your code portable to other implementations.
(In any event I feel your pain - I had a situation once where I needed
to print arrays in such a way that they would be read back in with a
particular specialized type. It was also circular to the nth degree,
and that had to be preserved as well. I wound up crawling the structure
and wrapping them with an object that knows how to print them (as
#.(make-array ...)), turned on *print-circle*, and printed the whole mess.
But it was ugly, and specializing PRINT-OBJECT on ARRAY would have been