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

STREAMP and CLOS



    Date: Mon, 24 Feb 1992 08:25 PST
    From: barmar@think.com (Barry Margolin)

	Date: Mon, 24 Feb 1992 12:51 EST
	From: bwild@azurro.fzi.de (Bernd Wild)

	We got a surprising result when applying STREAMP to an arbitrary CLOS  
	instance. It always returns T. This behavior has changed from Genera  
	8.0 to 8.1. While in 8.0 only "real" streams resulted in a T-value in  
	8.1 this can be observed for every instance.

    I can't reproduce this.  I did

    (clos:defclass foo () ())
    (setq a (clos:make-instance 'foo))

    (streamp a) => NIL

    (send a :which-operations) => (:SEND-IF-HANDLES :WHICH-OPERATIONS :OPERATION-HANDLED-P :PRINT-SELF)

    I'm running Genera 8.1.1, in case you're running plain 8.1.  I don't
    think it should make a difference, though; none of the CLOS patches in
    the ECO seem to relate to this.

Gack!  This surprising behavior can be obtained simply by loading
CLIM!  Bern, are you trying this in an environment with CLIM 1.0
loaded?

This bug is caused by a team effort of several random Genera/CLIM
facilities.

1) STREAMP is implemented in Genera by seeing if the object
handles the :TYI or :TYI message (as opposed to, say, checking to
see if it is a subclass of STREAM, or has a STREAMP method that
returns T).  This is due to the long and convoluted history of
the Genera stream implementation.

2) The WHICH-OPERATIONS implementation for CLOS objects works by
mapping over all the generic functions that are mapped to Flavor
messages via the :SELECTOR option to DEFGENERIC.  For each
function, it maps over all the methods, looking at the class of
the method's specialization argument.  If that class is in the
class precedence list of the class of the argument to
WHICH-OPERATIONS, it adds that message to the operations list.

3) CLIM uses the :SELECTOR mechanism to map STREAM-WRITE-CHAR to
:TYO, so STREAM-WRITE-CHAR is on the list of "selector" GF's
checked by WHICH-OPERATIONS.

4) CLIM also defines a method for STREAM-WRITE-CHAR on the class
T (so that STREAM-WRITE-CHAR method invocations on old Genera
stream objects will forward to a call to WRITE-CHAR).

So, the fact that STREAM-WRITE-CHAR is in the list of generic
functions with selectors (in this case, to the associated message
:TYO), and that it has a method defined on class T, and that
class T is a superclass of your FOO class defined above, all
means that WHICH-OPERATIONS thinks that FOO supports the :TYO
message, and therefore STREAMP thinks that an instance of FOO is
a stream.

(Pant, pant)

I am going to be pretty embarrassed if Mr. Wild is not using
CLIM.

I am open to suggestions for the right place to fix this.