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

Object Printing Discussion



Continuing the object printing discussion, I'd like to address 
some points brought up by Moon, and summarize things so far.

Before going further, however, I'd like to provide some 
motivation for continuing
this discussion. As mentioned in a previous note, the Objective-C Filer has
proven to be a useful tool for Objective-C programmers, even though it does
have some serious disadvantages as a mechanism for storing objects. 
Additionally, CommonObjects never defined a default 
storage mechanism (primarily because
the issues of abstraction violation were not fully thought out) and it has
proven to be a perennial problem. Binary storage mechanisms based on compiler
modifications, databases and the like are all interesting, but some base
level hooks and a simple default storage mechanism using existing Common Lisp
read macros where possible and ASCII text can simplify applications development
and provide backward compatibility with DEFSTRUCT. I'm sure, if it is
not provided, someone will to question why DEFSTRUCT's have
a readable storage representation and objects do not.

On to the discussion:

>Since we seem to be agreeing that the technique for creating objects
>will not make the physical slots directly visible, but instead will add
>a layer of abstraction, there is the issue that this transformation
>may not be reversible:  It may not be self-evident how to convert the
>slot-values of an object into a set of arguments to make-instance that
>will create an object with the same slot-values.  Suppose that not all
>of the slots have initargs that can initialize them.

I agree with the need for a layer of abstraction, however, the level of
MAKE-INSTANCE may be too high. In particular, if, as Moon's comments indicate,
the defined initialization protocol for the class will not accomodate 
initializing an object with the current slot value when read back in,
it would not be possible to write out an object's slot values and read
them back in using MAKE-INSTANCE. An example would be when no initarg
is defined for a slot (i.e., it is not initializable from MAKE-INSTANCE).

>In addition to this issue of slot values, I don't think the concept
>of "allowing an object printed out to be read back in" is well-defined,
>because the concept of reading "the same object" is not well-defined.
>In the simplest cases, creating an object of the same class with
>slot values "printed out and read back in" will do the job, but only
>in the simplest cases.  In general, an object is part of a data structure
>and ripping the object out of that data structure and jamming it
>into a world by itself may not be meaningful.  This is the same reason
>why we don't provide a general copy-object function.

I think you could make this argument for any Lisp data structure, including
lists, vectors, or what have you. Perhaps more strongly for objects, since
they tend to be more highly structured. I certainly agree it may not be
meaningful to write out an object and read it back in, but, in the default
case, I think the metaclass could provide some kind of meaning, which
could then be customized on a class by class (or metaclass by metaclass)
basis. In cases where it is not possible to provide meaning (like
writing out packages and fundefs in Common Lisp), the #< read macro
can be used to prohibit reading the representation back in.

>I think it would make sense to have a standardized mixin class for
>those simple objects whose semantics are defined entirely by the
>values of their initializable slots.  This class would define a
>print-object method that used either #S(...) or #.(make-instance ...),
>and would probably also define methods for copying and for dumping
>into binary files output by compilers.  This is fine; the thing I
>want to be very cautious about is assuming that -all- objects should
>have these methods.  It's much better to package them in a mixin that
>is there if you want it and not otherwise.  Any suggestions for a
>good name for this class?  simple-object?

As mentioned in a previous note, I think that control of object representation
should be left to the metaclass, and therefore this functionality should
be part of the metaobject protocol. The metaobject protocol controls how
objects and classes get created within memory, and thus it seems logical
that it should also control how objects move out to disc. 

	.	.	.	.	.	.

Lacking any concensus on object creation, it's difficult to outline a 
detailed proposal as to what should be done. Here's a summary of
my thinking on the issue so far:

1) CLOS should specify a default printable object representation which
is readable again, if only because programmers find it useful.

2) This representation should be ASCII and should use existing Common Lisp 
read macros where possible, to facilitate portability and backward 
compatibility.

3) The abstraction level should be below MAKE-INSTANCE, so that slots
which are not initable through MAKE-INSTANCE initargs can still be
initialized, but above the level of simply setting the slot, so the
class can customize initialization from a dumped object if desired.

4) The hooks should be part of the metaobject protocol, since the
metaobject protocol controls the representation of classes and
instances.

With regard to 3) and 4), possibly the issue of conversion of slot
values could be dealt with via a method on the STANDARD-SLOT-DESCRIPTION
class. However, I'll forgo any detailed proposals until hearing whether
there is any agreement about the overall issues.

		Jim Kempf		kempf@hplabs.hp.com