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

Re: interceptors



The problem with == is that it is really a low-level thing that doesn't do
double dispatching, instead being defined to be object equality testing.  If
you tried "23 = x" and "x = 23", they'll both return true, since "=" is
implemented using double dispatching.  You could fairly easily write your own
version of "==" that did double dispatching.

One problem with invoking primitives with transparent forwarders as
arguments (or refinements (children) for that matter) is that the primitive
expects a particular type of object as an argument, and fails with a
badTypeError if that expectation is not met.  But the primitive wrapper method
(the Self method that calls the primitive) should make sure that when given
a transparent forwarder or a refinement of a legal argument, which to the 
rest of the Self world can pass just fine for the other object, that the 
forwardee or refinee object is extracted and passed to the primitive.  This
can be implemented by having the primitive wrapper send a message to each of
the primitive's arguments; this message coerces the argument
to the correct object of the expected type.  We have already started to do this
to some of our primitives here at Stanford (but haven't released the new code
yet), but theoretically it should be done for all primitive calls, so that
transparent forwarders and refinements may be passed to a primitive wrapper.

This problem is why the (1 - x) test returns -22.0, not -22. The "-" wrapper
invokes the _IntSub primitive with a forwarder as an argument, gets a badType
Error, coerces both arguments to floats (which since it's done as a message
works fine with the forwarder), and retries the "-" message, returning -22.0.
Adding the extra message before the _IntSub primitive call, say sending
"primIntArg" to both arguments to the primitive that is defined in defaults
to return self, and in any refinements of an integer to return its parent, 
would fix the problem, and (1 - x) would return -22 as expected.

As far as capturing self, that's a little trickier.  The solution you
implement is simulating the forwarder being a refinement of the forwardee, by
using explicit delegation.  The first thing that happens in your example is
that the primitive is failing because the "primVectorArg" message isn't sent
as described above.  Then what happens is that the error handling code is
sending a message to self that accesses a private slot.  But since the 
receiver (the forwarder) isn't a child of the private slot holder, the private
slot access is denied, and you get the error you see.  If there were a public
slot of the same name, you would have called that one, instead of the 
private slot that would have been called if the transparent forwarder hadn't
been in the way.  It seems then that in general true transparent forwarding
cannot be built in Self this way.  Maybe an extra flavor of Perform primitive
would fix the problem.

-- Craig