[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


I stumbled across this recently when some low-level changes I was making broke
DESCRIBE and I decided to update it to the new spec rather than fixing the old

Forum:		Cleanup
References:	CLtL p441-2
		88-002R, DESCRIBE function
Edit history:	Version 1, 10-Mar-89, Kim A. Barrett

Problem description:

 The CLOS Specification (X3J13 Document 88-002R) changes the definition of the
 function DESCRIBE, making it a generic function.  However, it does not specify
 any of the protocol needed to make user-defined methods interact properly to
 produce some of the effects mentioned in CLtL.  For example, CLtL says that
 sometimes the method for describing an object will involve describing
 something that it finds inside the object, and that such recursive
 descriptions are indented appropriately.  How do user-written methods achieve
 this indentation?  Must they arrange for the indentation explicitly, or is
 there some automatic mechanism that handles it?

 The new specification does not easily lend itself to certain kinds of features
 which some implementations have included in their versions of DESCRIBE, such
 as analogues to the printer's depth limits (*PRINT-DEPTH*) and circular
 structure detection during recursion (*PRINT-CIRCLE*).

 In addition, DESCRIBE does not take a stream argument, instead always doing
 output to *STANDARD-OUTPUT*.  This means that a program which wants to use
 DESCRIBE to output some information to a particular stream must rebind
 *STANDARD-OUTPUT* around the call to DESCRIBE.  This is a nuisance, and is
 also potentially a bad idea in implementations which have interrupts and such.


 Remove the section of 88-002R which specifies that DESCRIBE is a generic
 function.  Modify DESCRIBE to accept an optional second stream argument, which
 defaults to *STANDARD-OUTPUT*.  The value of this argument is the stream which
 output will be directed to.  Specify that DESCRIBE is implemented in terms of
 the generic function DESCRIBE-OBJECT, described below.

 DESCRIBE-OBJECT object stream				[Generic Function]

  The generic function DESCRIBE-OBJECT writes a description of an object to a
  stream.  The function DESCRIBE-OBJECT is called by the DESCRIBE function; it
  should not be called by the user.

  Each implementation is required to provide a method on the class
  STANDARD-OBJECT and methods on enough other classes so as to ensure that
  there is always an applicable method.  Implementations are free to add
  methods for other classes.  Users can write methods for DESCRIBE-OBJECT for
  their own classes if they do not wish to inherit an implementation-supplied


   The first argument is any Lisp object.  The second argument is a stream; it
   cannot be T or NIL.


   The values returned by DESCRIBE-OBJECT are unspecified.


   Methods on DESCRIBE-OBJECT may recursively call DESCRIBE.  Indentation,
   depth limits, and circularity detection are all taken care of automatically,
   provided that each method handles exactly one level of structure and calls
   DESCRIBE recursively argument if there are more structural levels.

   If this rule is not obeyed, the results are undefined.

   In some implementations the stream argument passed to a DESCRIBE-OBJECT
   method is not the original stream, but is an intermediate stream that
   implements parts of DESCRIBE.  Methods should therefore not depend on the
   identity of this stream.


 This proposal was closely modeled on the CLOS description of PRINT-OBJECT,
 which was well thought out and provides a great deal of functionality and
 implementation freedom.  The same implementation techniques applicable to
 PRINT-OBJECT will be applicable to DESCRIBE-OBJECT.

 The reason for making the return values for DESCRIBE-OBJECT unspecified is to
 avoid forcing users to include explicit (VALUES) in all their methods.
 DESCRIBE will take care of that.

Current practice:

 Probably nobody does precisely what this proposal suggests.

Cost to Implementors:

 A fair amount of work may be required, since every method/subfunction of
 DESCRIBE in an implementation may need at least some fixing to be in line with
 this proposal.  On the other hand, that work may already be needed in order to
 conform to 88-002R, and this proposal may make the conversion easier by
 simplifying the translation of an existing implementation of DESCRIBE.

Cost to Users:

 Any users who are using an implementation which supports the current CLOS
 specification of DESCRIBE and have defined their own methods will have to
 change them.  CLOS is sufficiently recent that this probably isn't a big

 Those users who have made use of implementation-specific hooks into DESCRIBE
 to define their own methods will likely have to change, but that was already
 the case.

 Users who are currently binding *STANDARD-OUTPUT* around calls to DESCRIBE may
 wish to change their code.

Cost of non-adoption:

 Portable DESCRIBE methods may be difficult to write because the protocol they
 must follow is insufficiently specified.


 The constraints on DESCRIBE methods are better specified, making it easier to
 write such methods properly.




 An additional change which is not included in the present proposal would be to
 make the syntax of DESCRIBE and DESCRIBE-OBJECT be

  DESCRIBE object &optional stream &key
  DESCRIBE-OBJECT object stream &key

 allowing implementation-specific extensions to the arguments.  A possible
 standard keyword argument is :VERBOSE, which might be used to specify how much
 output to produce.

 It might be desirable to define some new describe control variables analogous
 to the printer control variables, ie. *DESCRIBE-LEVEL* and *DESCRIBE-CIRCLE*,
 and possibly *DESCRIBE-LENGTH*.