Forwarder

Stephen Pair spair at advantive.com
Thu Jul 26 01:44:14 UTC 2001


Ah...now I get what you're after...

The trampoline is probably the cleanest way without getting into the VM.
Method wrappers allow you to add behavior before and after methods
without needing to touch the source, but I don't think they would do
what you're after.

The trampolin allows you to write:

	anObject asend someMessage -or-
	anObject aqsend someMessage, etc

Similarly, we could do:

	anObject delegate someMessage

These forms are really dictating the manner in which a message is sent.
To be consistent, we could allow:

	anObject supersend someMessage  "this is probably breaking
encapsulation in this case"
	(anObject sendAt: SomeAncestorClass) someMessage

The special variable 'super' only instructs the compiler to use a
different send bytecode (it's still pushing self on the stack).

So, the most efficiate solution in these cases might be to add new send
bytecodes, and modify the compiler to generate them when it sees this
special syntax.

>:-) I don't know if that is a word, but I have the wrong idea of a
Delegator.  Are you saying that
> it delegates method lookup? 

Not exactly...messages sent to the forwarder, actually create a context
that looks just like a context created for the forwardee (in fact, there
is only one message lookup, just as if the message were sent directly to
the forwardee), with the exception of an additional pointer back to the
forwarder.  Bytecodes that push self have been modified such that they
push this special pointer.  Regular message sends just fill this slot in
the context with the receiver.  It's very efficient.

>More interesting to me are transparent proxies that maintains identity
under self reference, 
>forward all messages, and allows me to do management of the message
send in a :before and 
>:after sense.

I think that adding a delegated send bytecode (and compiler to generate
the bytecode) and supporting a customizable message lookup (don't really
know how difficult this part would be) will do what you want.  Without
the customizable message lookup, you can approximate a custom lookup
using DNU in the delegator (the DNU method would only need to delegate
everything it receives to the delegatee).  Then, any method added to the
delegator will shadow the same method in the delegatee.  You can then do
something before, make the delegated send, and do something after.  If
you subclass nil, your class would only have the instance methods that
you want to override (and DNU if you don't have the customizable message
lookup).

MethodWrappers would allow you to add before and after code, but not for
single instances (unless you create a special subclass and change the
instance(s) to that new subclass).

I've got a headache...

- Stephen

-----Original Message-----
From: squeak-dev-admin at lists.squeakfoundation.org
[mailto:squeak-dev-admin at lists.squeakfoundation.org] On Behalf Of
Withers, Robert
Sent: Wednesday, July 25, 2001 8:16 PM
To: 'squeak-dev at lists.squeakfoundation.org'
Subject: RE: Forwarder




Stephen Pair wrote: 
> 
> >Great stuff!  I'm very excited by your work, especially as a 
> mechanism 
> for delegation.  I am 
> >currently using the Trampoline object, that I think you originally 
> developed, Stephen.  I am unsure 
> >of how the delegation mechanism would work with this forwarder, so 
> please continue the ramblings at 
> >the bottom. 
> 
> Thanks!  No, I didn't do the trampoline...someone else did (can't 
> remember)...but, I incorporated into a little asynchronous messaging 
> demo that I did. 
Ah yes, so I did get that from you.  I also have been working on an
asynchronous messaging framework, so I did get the Trampoline idea and
the asend protocol from you.  I extended the contract somewhat.  I
wanted to allow asynchronous message sends, with the further constraint
that returns or exceptions from that send must return to the sending
Process.  Thus I have the Trampoline with an AsyncMessageGenerator which
creates a QueuedPromise and passes that with the AsyncMessageSend
object.  Both the send and the return go through the respective queues
of the Objects communicating.  This is done with secretaries, both a
global and background Secretaries.  I want to embed all of this into the
VM, along the lines of ConcurrentSmalltalk.
> >[rob - delegation hooks] 
> >This is where I am a bit confused about how this may work in 
> practice. 
> I believe your usage was to 
> >coalesce the reference to a changable object, which would be 
> polymorphic in protocol, to avoid the 
> >cost of a #become:.  Is this right?   
> 
> Yes, roughly...I wouldn't think of it as coalescing...there are still 
> two distinct objects, one just delgates everything it receives to the 
> other. 
Ok, but you maintain the same reference externally, even while the
implementation of the Forwardee mutates.  This is extremely interesting.
 
> >If I were to use a delegation model, or a managed object 
> >model, then I think the forwardee is the delegator or manager.  
> 
> Actually, this is the opposite of the way I would describe 
> it.  I would 
> describe the Forwarder as the delegator, and the forwardee as the 
> delegatee (is that a word?)...I don't really remember what (if any) 
> standard terminology has been established regarding delegation. 

:-) I don't know if that is a word, but I have the wrong idea of a
Delegator.  Are you saying that it delegates method lookup?  
More interesting to me are transparent proxies that maintains identity
under self reference, forward all messages, and allows me to do
management of the message send in a :before and :after sense.  I don't
want to have duplicate all of the protocol in a surrogate class for the
proxied object.  This is what I was thinking with the term Managed
Objects.  This management may include Security checks, faulting, async
sending/remote sending and future management.
The Trampoline object subclasses from ProtoObject and so there is an
identity problem, as well as not always forwarding all message sends.
It does this with DNU, so that is the point at which I can do the
:before and :after work.   It isn't clear to me where I can do this with
the Forwarder.  I would like to configure the Forwarder with a manager,
which could intercept the message send and transform it into a different
type of send.  
The possible solutions I know about are: 
        - Trampoline with a DNU, but the current version doesn't reroute
all message sends. 
        - MethodWrappers, I really haven't looked at these, but it
doesn't present a new, managed reference. 
        - Forwarder, but I don't see how to activate the Manager 
Perhaps it is a delegator model I am looking for, with your ability to
install custom lookup.  This may be the managed sending that I want.  I
will have to read the Self papers and more about AOP.  I can sense that
maintenance of self and identity would be interesting in this Delegative
model.
<snip> 
> I think you've lost me...also the Forwarder would not be used 
> at all in 
> delegation (it can't because because no method will ever be activated 
> for any of its instances)...in my mind delegation requires that you be

> able to send a message to an object, and receive any messages that are

> sent to self in the target method.  It's kind of like dynamically 
> subclassing the target object, but it only affects the instances 
> involved, it is only in effect for the duration of the 
> delegated message 
> send, and the two objects remain distinct (having separate 
> state...unlike subclassing, in which instances reflect a union of all 
> instance variable in the class and its superclasses). 
> 
> DNU comes into play when a delegated method context sends a message to

> self, which would get routed back to the delegator...which may not 
> natively understand the message and desires to once again 
> delegate (this 
> is analogous to the the lookup of a method in the superclass chain). 
> Alternatively, the delegator may implement the method, and choose to 
> delegate it, optionally adding behavior of its own (this is 
> analogous to 
> a super send). 
> 
> Of course, you would need to support additional syntax to generate a 
> "delegated send" bytecode. 
> 
> So, having a mechanism to define a custom lookup could be beneficial. 
> You could choose to first do a normal lookup, then try one of several 
> instance variables for potential delegation, or any number of 
> possibilites.  I don't think calling back into Smalltalk for 
> that would 
> be an issue...the default case of a normal lookup has to be handled 
> efficiently though.  And, you have to be careful not to melt 
> down into a 
> infinte recursion trying to lookup the method lookup method lookup 
> method lookup method lookup method lookup....you get the idea.  But, I

> think if you want the real deal...you have to go all the way to Self. 
> 
> I haven't experimented with the delegation aspect...so, there may be 
> something in there that blows apart my whole notion of how it might 
> work.  I'm going to play around with the forwarding capability for a 
> while first. 
> 
> - Stephen 
>  
- Rob 





More information about the Squeak-dev mailing list