<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 5.5.2653.12">
<TITLE>RE: Forwarder</TITLE>
</HEAD>
<BODY>
<P><FONT SIZE=2>mmmm, I also have a headache... although for more reasons than just this complicated topic.</FONT>
</P>
<P><FONT SIZE=2>Perhaps I can optionally instantiate the Forwarder with a Manager which understands the previous methods. In the send primitive, we can check for the manager (in slot 2 of the forwarder) and send the before and after methods to it, if it is installed. That may really slow down the rest of the image so maybe it is a bad idea. The great thing is I have your footprints to follow in my exploration. I can just try it myself!</FONT></P>
<P><FONT SIZE=2>cheers,</FONT>
<BR><FONT SIZE=2>Rob</FONT>
</P>
<P><FONT SIZE=2>> -----Original Message-----</FONT>
<BR><FONT SIZE=2>> From: Stephen Pair [<A HREF="mailto:spair@advantive.com">mailto:spair@advantive.com</A>]</FONT>
<BR><FONT SIZE=2>> Sent: Wednesday, July 25, 2001 9:44 PM</FONT>
<BR><FONT SIZE=2>> To: squeak-dev@lists.squeakfoundation.org</FONT>
<BR><FONT SIZE=2>> Subject: RE: Forwarder</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> Ah...now I get what you're after...</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> The trampoline is probably the cleanest way without getting </FONT>
<BR><FONT SIZE=2>> into the VM.</FONT>
<BR><FONT SIZE=2>> Method wrappers allow you to add behavior before and after methods</FONT>
<BR><FONT SIZE=2>> without needing to touch the source, but I don't think they would do</FONT>
<BR><FONT SIZE=2>> what you're after.</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> The trampolin allows you to write:</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> anObject asend someMessage -or-</FONT>
<BR><FONT SIZE=2>> anObject aqsend someMessage, etc</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> Similarly, we could do:</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> anObject delegate someMessage</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> These forms are really dictating the manner in which a </FONT>
<BR><FONT SIZE=2>> message is sent.</FONT>
<BR><FONT SIZE=2>> To be consistent, we could allow:</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> anObject supersend someMessage "this is probably breaking</FONT>
<BR><FONT SIZE=2>> encapsulation in this case"</FONT>
<BR><FONT SIZE=2>> (anObject sendAt: SomeAncestorClass) someMessage</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> The special variable 'super' only instructs the compiler to use a</FONT>
<BR><FONT SIZE=2>> different send bytecode (it's still pushing self on the stack).</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> So, the most efficiate solution in these cases might be to </FONT>
<BR><FONT SIZE=2>> add new send</FONT>
<BR><FONT SIZE=2>> bytecodes, and modify the compiler to generate them when it sees this</FONT>
<BR><FONT SIZE=2>> special syntax.</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> >:-) I don't know if that is a word, but I have the wrong idea of a</FONT>
<BR><FONT SIZE=2>> Delegator. Are you saying that</FONT>
<BR><FONT SIZE=2>> > it delegates method lookup? </FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> Not exactly...messages sent to the forwarder, actually create </FONT>
<BR><FONT SIZE=2>> a context</FONT>
<BR><FONT SIZE=2>> that looks just like a context created for the forwardee (in </FONT>
<BR><FONT SIZE=2>> fact, there</FONT>
<BR><FONT SIZE=2>> is only one message lookup, just as if the message were sent </FONT>
<BR><FONT SIZE=2>> directly to</FONT>
<BR><FONT SIZE=2>> the forwardee), with the exception of an additional pointer </FONT>
<BR><FONT SIZE=2>> back to the</FONT>
<BR><FONT SIZE=2>> forwarder. Bytecodes that push self have been modified such that they</FONT>
<BR><FONT SIZE=2>> push this special pointer. Regular message sends just fill </FONT>
<BR><FONT SIZE=2>> this slot in</FONT>
<BR><FONT SIZE=2>> the context with the receiver. It's very efficient.</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> >More interesting to me are transparent proxies that </FONT>
<BR><FONT SIZE=2>> maintains identity</FONT>
<BR><FONT SIZE=2>> under self reference, </FONT>
<BR><FONT SIZE=2>> >forward all messages, and allows me to do management of the message</FONT>
<BR><FONT SIZE=2>> send in a :before and </FONT>
<BR><FONT SIZE=2>> >:after sense.</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> I think that adding a delegated send bytecode (and compiler </FONT>
<BR><FONT SIZE=2>> to generate</FONT>
<BR><FONT SIZE=2>> the bytecode) and supporting a customizable message lookup </FONT>
<BR><FONT SIZE=2>> (don't really</FONT>
<BR><FONT SIZE=2>> know how difficult this part would be) will do what you want. Without</FONT>
<BR><FONT SIZE=2>> the customizable message lookup, you can approximate a custom lookup</FONT>
<BR><FONT SIZE=2>> using DNU in the delegator (the DNU method would only need to delegate</FONT>
<BR><FONT SIZE=2>> everything it receives to the delegatee). Then, any method </FONT>
<BR><FONT SIZE=2>> added to the</FONT>
<BR><FONT SIZE=2>> delegator will shadow the same method in the delegatee. You </FONT>
<BR><FONT SIZE=2>> can then do</FONT>
<BR><FONT SIZE=2>> something before, make the delegated send, and do something after. If</FONT>
<BR><FONT SIZE=2>> you subclass nil, your class would only have the instance methods that</FONT>
<BR><FONT SIZE=2>> you want to override (and DNU if you don't have the </FONT>
<BR><FONT SIZE=2>> customizable message</FONT>
<BR><FONT SIZE=2>> lookup).</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> MethodWrappers would allow you to add before and after code, </FONT>
<BR><FONT SIZE=2>> but not for</FONT>
<BR><FONT SIZE=2>> single instances (unless you create a special subclass and change the</FONT>
<BR><FONT SIZE=2>> instance(s) to that new subclass).</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> I've got a headache...</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> - Stephen</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> -----Original Message-----</FONT>
<BR><FONT SIZE=2>> From: squeak-dev-admin@lists.squeakfoundation.org</FONT>
<BR><FONT SIZE=2>> [<A HREF="mailto:squeak-dev-admin@lists.squeakfoundation.org">mailto:squeak-dev-admin@lists.squeakfoundation.org</A>] On Behalf Of</FONT>
<BR><FONT SIZE=2>> Withers, Robert</FONT>
<BR><FONT SIZE=2>> Sent: Wednesday, July 25, 2001 8:16 PM</FONT>
<BR><FONT SIZE=2>> To: 'squeak-dev@lists.squeakfoundation.org'</FONT>
<BR><FONT SIZE=2>> Subject: RE: Forwarder</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> Stephen Pair wrote: </FONT>
<BR><FONT SIZE=2>> > </FONT>
<BR><FONT SIZE=2>> > >Great stuff! I'm very excited by your work, especially as a </FONT>
<BR><FONT SIZE=2>> > mechanism </FONT>
<BR><FONT SIZE=2>> > for delegation. I am </FONT>
<BR><FONT SIZE=2>> > >currently using the Trampoline object, that I think you originally </FONT>
<BR><FONT SIZE=2>> > developed, Stephen. I am unsure </FONT>
<BR><FONT SIZE=2>> > >of how the delegation mechanism would work with this forwarder, so </FONT>
<BR><FONT SIZE=2>> > please continue the ramblings at </FONT>
<BR><FONT SIZE=2>> > >the bottom. </FONT>
<BR><FONT SIZE=2>> > </FONT>
<BR><FONT SIZE=2>> > Thanks! No, I didn't do the trampoline...someone else did (can't </FONT>
<BR><FONT SIZE=2>> > remember)...but, I incorporated into a little asynchronous </FONT>
<BR><FONT SIZE=2>> messaging </FONT>
<BR><FONT SIZE=2>> > demo that I did. </FONT>
<BR><FONT SIZE=2>> Ah yes, so I did get that from you. I also have been working on an</FONT>
<BR><FONT SIZE=2>> asynchronous messaging framework, so I did get the Trampoline idea and</FONT>
<BR><FONT SIZE=2>> the asend protocol from you. I extended the contract somewhat. I</FONT>
<BR><FONT SIZE=2>> wanted to allow asynchronous message sends, with the further </FONT>
<BR><FONT SIZE=2>> constraint</FONT>
<BR><FONT SIZE=2>> that returns or exceptions from that send must return to the sending</FONT>
<BR><FONT SIZE=2>> Process. Thus I have the Trampoline with an </FONT>
<BR><FONT SIZE=2>> AsyncMessageGenerator which</FONT>
<BR><FONT SIZE=2>> creates a QueuedPromise and passes that with the AsyncMessageSend</FONT>
<BR><FONT SIZE=2>> object. Both the send and the return go through the respective queues</FONT>
<BR><FONT SIZE=2>> of the Objects communicating. This is done with secretaries, both a</FONT>
<BR><FONT SIZE=2>> global and background Secretaries. I want to embed all of </FONT>
<BR><FONT SIZE=2>> this into the</FONT>
<BR><FONT SIZE=2>> VM, along the lines of ConcurrentSmalltalk.</FONT>
<BR><FONT SIZE=2>> > >[rob - delegation hooks] </FONT>
<BR><FONT SIZE=2>> > >This is where I am a bit confused about how this may work in </FONT>
<BR><FONT SIZE=2>> > practice. </FONT>
<BR><FONT SIZE=2>> > I believe your usage was to </FONT>
<BR><FONT SIZE=2>> > >coalesce the reference to a changable object, which would be </FONT>
<BR><FONT SIZE=2>> > polymorphic in protocol, to avoid the </FONT>
<BR><FONT SIZE=2>> > >cost of a #become:. Is this right? </FONT>
<BR><FONT SIZE=2>> > </FONT>
<BR><FONT SIZE=2>> > Yes, roughly...I wouldn't think of it as coalescing...there </FONT>
<BR><FONT SIZE=2>> are still </FONT>
<BR><FONT SIZE=2>> > two distinct objects, one just delgates everything it </FONT>
<BR><FONT SIZE=2>> receives to the </FONT>
<BR><FONT SIZE=2>> > other. </FONT>
<BR><FONT SIZE=2>> Ok, but you maintain the same reference externally, even while the</FONT>
<BR><FONT SIZE=2>> implementation of the Forwardee mutates. This is extremely </FONT>
<BR><FONT SIZE=2>> interesting.</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> > >If I were to use a delegation model, or a managed object </FONT>
<BR><FONT SIZE=2>> > >model, then I think the forwardee is the delegator or manager. </FONT>
<BR><FONT SIZE=2>> > </FONT>
<BR><FONT SIZE=2>> > Actually, this is the opposite of the way I would describe </FONT>
<BR><FONT SIZE=2>> > it. I would </FONT>
<BR><FONT SIZE=2>> > describe the Forwarder as the delegator, and the forwardee as the </FONT>
<BR><FONT SIZE=2>> > delegatee (is that a word?)...I don't really remember what (if any) </FONT>
<BR><FONT SIZE=2>> > standard terminology has been established regarding delegation. </FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> :-) I don't know if that is a word, but I have the wrong idea of a</FONT>
<BR><FONT SIZE=2>> Delegator. Are you saying that it delegates method lookup? </FONT>
<BR><FONT SIZE=2>> More interesting to me are transparent proxies that maintains identity</FONT>
<BR><FONT SIZE=2>> under self reference, forward all messages, and allows me to do</FONT>
<BR><FONT SIZE=2>> management of the message send in a :before and :after sense. I don't</FONT>
<BR><FONT SIZE=2>> want to have duplicate all of the protocol in a surrogate </FONT>
<BR><FONT SIZE=2>> class for the</FONT>
<BR><FONT SIZE=2>> proxied object. This is what I was thinking with the term Managed</FONT>
<BR><FONT SIZE=2>> Objects. This management may include Security checks, faulting, async</FONT>
<BR><FONT SIZE=2>> sending/remote sending and future management.</FONT>
<BR><FONT SIZE=2>> The Trampoline object subclasses from ProtoObject and so there is an</FONT>
<BR><FONT SIZE=2>> identity problem, as well as not always forwarding all message sends.</FONT>
<BR><FONT SIZE=2>> It does this with DNU, so that is the point at which I can do the</FONT>
<BR><FONT SIZE=2>> :before and :after work. It isn't clear to me where I can </FONT>
<BR><FONT SIZE=2>> do this with</FONT>
<BR><FONT SIZE=2>> the Forwarder. I would like to configure the Forwarder with </FONT>
<BR><FONT SIZE=2>> a manager,</FONT>
<BR><FONT SIZE=2>> which could intercept the message send and transform it into </FONT>
<BR><FONT SIZE=2>> a different</FONT>
<BR><FONT SIZE=2>> type of send. </FONT>
<BR><FONT SIZE=2>> The possible solutions I know about are: </FONT>
<BR><FONT SIZE=2>> - Trampoline with a DNU, but the current version </FONT>
<BR><FONT SIZE=2>> doesn't reroute</FONT>
<BR><FONT SIZE=2>> all message sends. </FONT>
<BR><FONT SIZE=2>> - MethodWrappers, I really haven't looked at these, but it</FONT>
<BR><FONT SIZE=2>> doesn't present a new, managed reference. </FONT>
<BR><FONT SIZE=2>> - Forwarder, but I don't see how to activate the Manager </FONT>
<BR><FONT SIZE=2>> Perhaps it is a delegator model I am looking for, with your ability to</FONT>
<BR><FONT SIZE=2>> install custom lookup. This may be the managed sending that </FONT>
<BR><FONT SIZE=2>> I want. I</FONT>
<BR><FONT SIZE=2>> will have to read the Self papers and more about AOP. I can </FONT>
<BR><FONT SIZE=2>> sense that</FONT>
<BR><FONT SIZE=2>> maintenance of self and identity would be interesting in this </FONT>
<BR><FONT SIZE=2>> Delegative</FONT>
<BR><FONT SIZE=2>> model.</FONT>
<BR><FONT SIZE=2>> <snip> </FONT>
<BR><FONT SIZE=2>> > I think you've lost me...also the Forwarder would not be used </FONT>
<BR><FONT SIZE=2>> > at all in </FONT>
<BR><FONT SIZE=2>> > delegation (it can't because because no method will ever be </FONT>
<BR><FONT SIZE=2>> activated </FONT>
<BR><FONT SIZE=2>> > for any of its instances)...in my mind delegation requires </FONT>
<BR><FONT SIZE=2>> that you be</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> > able to send a message to an object, and receive any </FONT>
<BR><FONT SIZE=2>> messages that are</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> > sent to self in the target method. It's kind of like dynamically </FONT>
<BR><FONT SIZE=2>> > subclassing the target object, but it only affects the instances </FONT>
<BR><FONT SIZE=2>> > involved, it is only in effect for the duration of the </FONT>
<BR><FONT SIZE=2>> > delegated message </FONT>
<BR><FONT SIZE=2>> > send, and the two objects remain distinct (having separate </FONT>
<BR><FONT SIZE=2>> > state...unlike subclassing, in which instances reflect a </FONT>
<BR><FONT SIZE=2>> union of all </FONT>
<BR><FONT SIZE=2>> > instance variable in the class and its superclasses). </FONT>
<BR><FONT SIZE=2>> > </FONT>
<BR><FONT SIZE=2>> > DNU comes into play when a delegated method context sends a </FONT>
<BR><FONT SIZE=2>> message to</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> > self, which would get routed back to the delegator...which may not </FONT>
<BR><FONT SIZE=2>> > natively understand the message and desires to once again </FONT>
<BR><FONT SIZE=2>> > delegate (this </FONT>
<BR><FONT SIZE=2>> > is analogous to the the lookup of a method in the </FONT>
<BR><FONT SIZE=2>> superclass chain). </FONT>
<BR><FONT SIZE=2>> > Alternatively, the delegator may implement the method, and </FONT>
<BR><FONT SIZE=2>> choose to </FONT>
<BR><FONT SIZE=2>> > delegate it, optionally adding behavior of its own (this is </FONT>
<BR><FONT SIZE=2>> > analogous to </FONT>
<BR><FONT SIZE=2>> > a super send). </FONT>
<BR><FONT SIZE=2>> > </FONT>
<BR><FONT SIZE=2>> > Of course, you would need to support additional syntax to </FONT>
<BR><FONT SIZE=2>> generate a </FONT>
<BR><FONT SIZE=2>> > "delegated send" bytecode. </FONT>
<BR><FONT SIZE=2>> > </FONT>
<BR><FONT SIZE=2>> > So, having a mechanism to define a custom lookup could be </FONT>
<BR><FONT SIZE=2>> beneficial. </FONT>
<BR><FONT SIZE=2>> > You could choose to first do a normal lookup, then try one </FONT>
<BR><FONT SIZE=2>> of several </FONT>
<BR><FONT SIZE=2>> > instance variables for potential delegation, or any number of </FONT>
<BR><FONT SIZE=2>> > possibilites. I don't think calling back into Smalltalk for </FONT>
<BR><FONT SIZE=2>> > that would </FONT>
<BR><FONT SIZE=2>> > be an issue...the default case of a normal lookup has to be handled </FONT>
<BR><FONT SIZE=2>> > efficiently though. And, you have to be careful not to melt </FONT>
<BR><FONT SIZE=2>> > down into a </FONT>
<BR><FONT SIZE=2>> > infinte recursion trying to lookup the method lookup method lookup </FONT>
<BR><FONT SIZE=2>> > method lookup method lookup method lookup....you get the </FONT>
<BR><FONT SIZE=2>> idea. But, I</FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> > think if you want the real deal...you have to go all the </FONT>
<BR><FONT SIZE=2>> way to Self. </FONT>
<BR><FONT SIZE=2>> > </FONT>
<BR><FONT SIZE=2>> > I haven't experimented with the delegation aspect...so, </FONT>
<BR><FONT SIZE=2>> there may be </FONT>
<BR><FONT SIZE=2>> > something in there that blows apart my whole notion of how it might </FONT>
<BR><FONT SIZE=2>> > work. I'm going to play around with the forwarding </FONT>
<BR><FONT SIZE=2>> capability for a </FONT>
<BR><FONT SIZE=2>> > while first. </FONT>
<BR><FONT SIZE=2>> > </FONT>
<BR><FONT SIZE=2>> > - Stephen </FONT>
<BR><FONT SIZE=2>> > </FONT>
<BR><FONT SIZE=2>> - Rob </FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> </FONT>
<BR><FONT SIZE=2>> </FONT>
</P>
</BODY>
</HTML>