![](https://secure.gravatar.com/avatar/29e40ec843bec4b66414022ddce75718.jpg?s=120&d=mm&r=g)
On Fri, Jul 15, 2011 at 8:50 AM, Mark Evenson <evenson@panix.com> wrote:
On Jul 14, 2011, at 20:42 , Erik Huelsmann wrote:
My idea would be to disambiguate the two functions by making
writeToString() a java-side PRINT-OBJECT, renaming it to printObject() and documenting that's what it does. Then, probably, the lisp side function %write-to-string should be renamed to %print-object too. Probably, more adjustments are required throughout the code base, but those are probably at the 'implementation detail' level.
I think that the meaning of writeToString() was that the function should provide an implementation of serialization to a string able to be READ with the #S notation. It is not really performing a PRINT-OBJECT-alike function which is a specialization of such an implementation on Lisp STANDARD-OBJECT or STRUCTURE-OBJECT.
On the other hand, the clhs specifies that an implementation defines enough additional methods besides the STANDARD-OBJECT and STRUCTURE-OBJECT ones to make sure there will always be an applicable method. We seem to do that through a single T method which forwards to the internal writeToString() Java method. Additionally, the clhs page for PRINT-OBJECT specifies that readable printing [for standard objects and structure objects] is done through the PRINT-OBJECT method rather than its MAKE-LOAD-FORM method. Many of our Java side functions try to behave this way by checking the values of the various *PRINT-xxx* special variables. One of the conclusions could be that our writeToString() functions are really trying to behave as PRINT-OBJECT implementations.
On the other hand there is some justification for not calling such an implementation writeToString() as that will certainly confuse a Java user used to every object either inheriting or overrriding java.lang.Object.toString(). I might suggest then, that to clarify that this function isn't a direct implementation of CL's PRINT-OBJECT which actually takes an both arguments to specify the object it is operating on and to specify the output streamthat we rename the Java-side to writeLispObject(). The return type of this method, java.lang.String, makes something more verbose like writeLispObjectToString() superfluous. I'd leave the Lisp %write-to-string alone, as the presence of WRITE-TO-STRING in the CL namespace makes it pretty clear that this is the primitive implementation. Since %write-to-string has a simple implementation, looking up its behavior is rather easy.
In any case, I would take advantage of the architecture I started to define in org.armedbear.lisp.protocol to create an interface which defines this contract:
package org.armedbear.lisp.protocol;
/** The implementing object can be serialized ala WRITE. */ public interface WriteSerializable { // XXX not crazy about the name here /** Serialize the implementing object instance in a manner that may be READ via #S */ public String writeLispObject(); }
and then make LispObject implement this interface.
This provides a suitable place for encapsulation and documentation, being the natural place that a Java programmer will go to figure out what this method should do as it implements the interface.
Given the purpose of PRINT-OBJECT as taken from the CLHS, I guess only the discussion about the naming remains? And of course the conclusion that if writeToString() actually implements the PRINT-OBJECT protocol, it's failing to do that horribly: generating unreadable presentations when *PRINT-READABLY* is bound to non-NIL values... Right? Bye, Erik.