RoleMethod selecton and execution

7 views
Skip to first unread message

Trygve Reenskaug

unread,
Oct 3, 2011, 6:37:21 AM10/3/11
to DCI-object-evolution
I have been pondering over the execution of RoleMethods.

First how methods are executed in in Squeak. This to establish a common mindset.

    A1: The VM (virtual machine, interpreter) passes a message foo() from a sender object to a receiver object
    A2: The VM find the receiver's class and then its methodDict (message dictionary)
    A3: The VM looks up foo in the methodDict . If a hit, it executes the corresponding method.
    A4: If no hit, the VM finds the superclass methodDict and repeats...

The Role is the namespace for RMs (RoleMethods).
Solutions with Traits or similar injects the RMs into the roleplaying object or class. This is an overkill that leads namespace confusion and potential name collision problems. 
Solutions with wrappers or similar lead to dual objects with potential identity problems.

I suggest a super, lightweight, kind of subclass mechanism with a methodDict associated with the role: (The Role acts as an abstract subclass with no state?)

    B1: The VM pass a message foo() from a sender to a named Role
    B2: The VM finds the Role's methodDict.
    B3: The VM looks up foo. If a hit, it executes the corresponding RoleMethod.
    B4: If no hit, the VM finds the RolePlayer's class and then its methodDict
    B5: The VM looks up foo. If a hit, it executes the corresponding method.
    B6: If no hit, the VM finds the superclass methodDict and repeats as usual.

self.foo()  in the sender code starts searching in the current Role's methodDict.
super.foo() in the sender code starts searching in the messageDict of the RolePlayer in step B4 above. As usual, this is only necessary if there is a name collision, of course.

There are only operations on messageDicts, no intrusion into Data objects or classes. No extraneous objects, no dual identities.
Isn't  this solution is very close to what Ant and others have in mind?

I think this scheme will work, but it needs much more thinking. It seems to require a special VM? (This is just a SMOP in Squeak). Can it be faked in other languages? A master thesis?

Cheers
--Trygve

--

Trygve Reenskaug       mailto: try...@ifi.uio.no

Morgedalsvn. 5A         http://folk.uio.no/trygver/ 

N-0378 Oslo               Tel: (+47) 22 49 57 27

Norway

James O. Coplien

unread,
Oct 4, 2011, 6:14:25 AM10/4/11
to dci-ev...@googlegroups.com
Just one thing to keep in mind when reasoning about these things: make sure that none of the strategies short-circuit the kind of JIT tricks that came into Smalltalk largely from self. I'm not enough of an expert to reason about these off the top of my head, but someone who crawls around inside VMs should know this stuff.

Maybe the contextualization of DCI makes it possible to do even more with JIT tricks and trust-until-misled bindings.

Second, it's not clear that this solution solves the name collision problem. It only adopts one disambiguation convention. I think that most of the mechanisms in use by other languages already adapt this convention or that to remove the problem. C++ is an exception in this regard, and you can get a real ambiguity. Sweet thing #1 is that the compiler tells you about it. Sweet thing #2 is that you can always use qualification resolution to manually disambiguate the call. The mechanism described in the mail selects the role method over the class method, which may not be what the programmer wants all the time. This will be especially devastating if it results in a violation of self-encapsulation: i.e., if the sender and receiver are the same object, and the sender expects the class method rather than the role method to be invoked.

Rune Funch Søltoft

unread,
Oct 4, 2011, 6:33:11 AM10/4/11
to dci-ev...@googlegroups.com
If a RolePlayer is passed to a method external to the context is it then passed as an object of the "role type" or the "data type"? 
I'm not asking in the context of a specific language but what we believe the concept to be.

-Rune

2011/10/4 James O. Coplien <jcop...@gmail.com>

James O. Coplien

unread,
Oct 4, 2011, 6:39:50 AM10/4/11
to dci-ev...@googlegroups.com
My opinion:

It has a compound type (its "base data type" plus what it gets from all roles injected into it). Some methods of that compound type may or may not be accessible outside the context.

Think of type as a set mapping (a function, as you once mentioned — I don't view function as types, but I do view types as functions — as mappings).

A C++ int has type integer. Are bitwise operations part of type integer?

That is, does integer have bitwise nature?  :-)

How about in Pascal?

It is crucial to distinguish accessibility, scope, and type. And type certainly is not class.

Trygve Reenskaug

unread,
Oct 4, 2011, 8:41:56 AM10/4/11
to dci-ev...@googlegroups.com


On 2011.10.04 12:14, James O. Coplien wrote:
Just one thing to keep in mind when reasoning about these things: make sure that none of the strategies short-circuit the kind of JIT tricks that came into Smalltalk largely from self. I'm not enough of an expert to reason about these off the top of my head, but someone who crawls around inside VMs should know this stuff.
First make it work. Then make it right. Then make it fast.
I'm after a "right" execution model. Only when at least one implementation is working comes the time for optimization. (IMO) Smalltalk was very slow initially, then people found ways to optimize it. (I believe the most effective optimization is to cash compiled binary methods....)


Maybe the contextualization of DCI makes it possible to do even more with JIT tricks and trust-until-misled bindings.
As I said above. I won't worry about optimization before I understand how it should work, conceptually.


Second, it's not clear that this solution solves the name collision problem. It only adopts one disambiguation convention. I think that most of the mechanisms in use by other languages already adapt this convention or that to remove the problem. C++ is an exception in this regard, and you can get a real ambiguity. Sweet thing #1 is that the compiler tells you about it. Sweet thing #2 is that you can always use qualification resolution to manually disambiguate the call. The mechanism described in the mail selects the role method over the class method, which may not be what the programmer wants all the time. This will be especially devastating if it results in a violation of self-encapsulation: i.e., if the sender and receiver are the same object, and the sender expects the class method rather than the role method to be invoked.
I don't see the problem. My solution is to behave as if  the roleplayer object is *temporarily* made instance of a subclass of whatever class it was before.

I do think it does solve the problem with multiple namespaces since the solution is a somewhat special subclass.
AFAICS, there is no problem  if the sender expects the instance method rather than the role method. 'super' and 'self' should take care of that just as it does in the case of super- and sub-classes.

rune funch

unread,
Oct 4, 2011, 8:55:42 AM10/4/11
to dci-ev...@googlegroups.com
Then let's stick to scope for a moment

if I pass a RolePlayer to a method defined external to the context but executed as part of the interaction (that is the active context isn't changed) can I conceptually call a role method on the object I passed to the external method?

Cope

unread,
Oct 21, 2011, 10:50:12 AM10/21/11
to dci-evolution
I trust that you mean to invoke the method from the external function.

My answer to your question would be: No, particularly if looking at
this from the perspective of a language lacking full reflection.
Change that and my answer may be different.

The rationale is rooted in differentiating between scope, lifetime and
extent, and accessibility.



On Oct 4, 2:55 pm, rune funch <funchsolt...@gmail.com> wrote:
> Then let's stick to scope for a moment
>
> if I pass a RolePlayer to a method defined external to the context but
> executed as part of the interaction (that is the active context isn't
> changed) can I conceptually call a role method on the object I passed to the
> external method?
>
> -Rune
>
> 2011/10/4 James O. Coplien <jcopl...@gmail.com>
>
>
>
> > My opinion:
>
> > It has a compound type (its "base data type" plus what it gets from all
> > roles injected into it). Some methods of that compound type may or may not
> > be accessible outside the context.
>
> > Think of type as a set mapping (a function, as you once mentioned — I don't
> > view function as types, but I do view types as functions — as mappings).
>
> > A C++ int has type integer. Are bitwise operations part of type integer?
>
> > That is, does integer have bitwise nature?  :-)
>
> > How about in Pascal?
>
> > It is crucial to distinguish accessibility, scope, and type. And type
> > certainly is not class.
>
> > On Oct 4, 2011, at 12:33 , Rune Funch Søltoft wrote:
>
> > If a RolePlayer is passed to a method external to the context is it then
> > passed as an object of the "role type" or the "data type"?
> > I'm not asking in the context of a specific language but what we believe
> > the concept to be.
>
> > -Rune
>
> > 2011/10/4 James O. Coplien <jcopl...@gmail.com>
>
> >> Just one thing to keep in mind when reasoning about these things: make
> >> sure that none of the strategies short-circuit the kind of JIT tricks that
> >> came into Smalltalk largely from *self*. I'm not enough of an expert to
> >> reason about these off the top of my head, but someone who crawls around
> >> inside VMs should know this stuff.
>
> >> Maybe the contextualization of DCI makes it possible to do even more with
> >> JIT tricks and trust-until-misled bindings.
>
> >> Second, it's not clear that this solution solves the name collision
> >> problem. It only adopts one disambiguation convention. I think that most of
> >> the mechanisms in use by other languages already adapt this convention or
> >> that to remove the problem. C++ is an exception in this regard, and you can
> >> get a real ambiguity. Sweet thing #1 is that the compiler tells you about
> >> it. Sweet thing #2 is that you can always use qualification resolution to
> >> manually disambiguate the call. The mechanism described in the mail selects
> >> the role method over the class method, which may not be what the programmer
> >> wants all the time. This will be especially devastating if it results in a
> >> violation of self-encapsulation: i.e., if the sender and receiver are the
> >> same object, and the sender expects the class method rather than the role
> >> method to be invoked.
>
> >> On Oct 3, 2011, at 12:37 , Trygve Reenskaug wrote:
>
> >>  I have been pondering over the execution of RoleMethods.
>
> >> First how methods are executed in in Squeak. This to establish a common
> >> mindset.
>
> >>     A1: The VM (virtual machine, interpreter) passes a message *foo()*from a sender object to a receiver object
> >>     A2: The VM find the receiver's class and then its methodDict (message
> >> dictionary)
> >>     A3: The VM looks up *foo* in the methodDict . If a hit, it executes
> >> the corresponding method.
> >>     A4: If no hit, the VM finds the superclass methodDict and repeats...
>
> >> The Role is the namespace for RMs (RoleMethods).
> >> Solutions with Traits or similar injects the RMs into the roleplaying
> >> object or class. This is an overkill that leads namespace confusion and
> >> potential name collision problems.
> >> Solutions with wrappers or similar lead to dual objects with potential
> >> identity problems.
>
> >> I suggest a super, lightweight, kind of subclass mechanism with a
> >> methodDict associated with the role: (The Role acts as an abstract subclass
> >> with no state?)
>
> >>     B1: The VM pass a message *foo()* from a sender to a named Role
> >>     B2: The VM finds the Role's methodDict.
> >>     B3: The VM looks up *foo*. If a hit, it executes the corresponding
> >> RoleMethod.
> >>     B4: If no hit, the VM finds the RolePlayer's class and then its
> >> methodDict
> >>     B5: The VM looks up *foo*. If a hit, it executes the corresponding
> >> method.
> >>     B6: If no hit, the VM finds the superclass methodDict and repeats as
> >> usual.
>
> >> *self.foo()*  in the sender code starts searching in the current Role's
> >> methodDict.
> >> *super.foo()* in the sender code starts searching in the messageDict of
> >> the RolePlayer in step B4 above. As usual, this is only necessary if there
> >> is a name collision, of course.
>
> >> There are only operations on messageDicts, no intrusion into Data objects
> >> or classes. No extraneous objects, no dual identities.
> >> Isn't  this solution is very close to what Ant and others have in mind?
>
> >> I think this scheme will work, but it needs much more thinking. It seems
> >> to require a special VM? (This is just a SMOP in Squeak). Can it be faked in
> >> other languages? A master thesis?
>
> >> Cheers
> >> --Trygve
>
> >> --
>
> >> Trygve Reenskaug       mailto: tryg...@ifi.uio.no****
>
> >> Morgedalsvn. 5A        http://folk.uio.no/trygver/ ****
>
> >> N-0378 Oslo               Tel: (+47)22 49 57 27****
>
> >> Norway****

Rune Funch Søltoft

unread,
Oct 23, 2011, 8:39:56 AM10/23/11
to dci-ev...@googlegroups.com


2011/10/21 Cope <jcop...@gmail.com>

I trust that you mean to invoke the method from the external function.

My answer to your question would be: No, particularly if looking at
this from the perspective of a language lacking full reflection.
Change that and my answer may be different.
I'm looking at this from the perspective of a compiler/language writer. It's a question I had to answer when looking at type checking of roles.

I personally feel that the scope of the role is exited when the calling a method external to the context and hence don't view the RoleMethos to be accessible in the above scenario. Your answer seems to partly support that view I would however be interested in knowing the reasoning behind "No, particularly if looking at
this from the perspective of a language lacking full reflection.
Change that and my answer may be different"
Why and how would the capabilities of language impact the concepts of DCI? 

-Rune

James O. Coplien

unread,
Oct 23, 2011, 10:04:34 AM10/23/11
to dci-ev...@googlegroups.com

On Oct 23, 2011, at 2:39 , Rune Funch Søltoft wrote:

Why and how would the capabilities of language impact the concepts of DCI? 


Because in a language with full reflection, one expects tricks like this to be an acceptable part of the rules of engagement. That has nothing to do with DCI. It's just that, by accident of coincidence, this functionality overlaps something DCI is concerned with.

As with any such use of reflection it may cause surprises. Here, it will cause surprises with respect to some code reader's expectations about the code having DCI properties. And it will not. But, again: that is the price of using the flexibility of a reflection API.

In the terms that Trygve and I developed during our last meeting, this is violating the abstraction layer.

I'm happy to report that Trygve and I have another meeting in a little less than a week.

rune funch

unread,
Oct 23, 2011, 10:11:54 AM10/23/11
to dci-ev...@googlegroups.com
Den 23/10/2011 kl. 16.04 skrev "James O. Coplien" <jcop...@gmail.com>:

> In the terms that Trygve and I developed during our last meeting, this is violating the abstraction layer.

So a language that supports reflection but makes invocation of
RoleMethods outside the implementing context even through reflection
is in accordance with the ideas of DCI right?

-Rune

Trygve Reenskaug

unread,
Oct 23, 2011, 12:17:38 PM10/23/11
to dci-ev...@googlegroups.com
Rune,
Please look at http://fulloo.info/t-files/BB7DijkstraNoInjection.pdf.
See the method BB7CalculateShortestPathCTX::send: selector to: roleName withArguments: argArray.

This fix leads to what I consider clean DCI behavior. An  Interaction is triggered by a message to its Context. The Interaction does its work, and then exits. There are no spurious traces left from the Interaction. In particular, there is no added object behavior anywhere. My particular mechanism is irrelevant. It is a proof of concept, no more. Other implementations can fake it and make various compromises. I would consider it a flaw if an implementation adds functionality that is not part of clean DCI. (An example could be using role methods outside their Context).

The concept of DCI should not depend on implementation language. The fact that something can be done doesn't mean that we want to do it.

--Trygve

rune funch

unread,
Oct 23, 2011, 12:21:32 PM10/23/11
to dci-ev...@googlegroups.com
Hi Trygve,
Thanks for the clarification. With the comments from both you and Jim I now feel confident that I can write the type checker I envision for strongly typed languages. When I get so time I'll try and draft it and post here on evolution. 

Mvh
Rune

Den 23/10/2011 kl. 18.17 skrev Trygve Reenskaug <try...@ifi.uio.no>:

Rune,
Please look at http://fulloo.info/t-files/BB7DijkstraNoInjection.pdf.
See the method BB7CalculateShortestPathCTX::send: selector to: roleName withArguments: argArray.

This fix leads to what I consider clean DCI behavior. An  Interaction is triggered by a message to its Context. The Interaction does its work, and then exits. There are no spurious traces left from the Interaction. In particular, there is no added object behavior anywhere. My particular mechanism is irrelevant. It is a proof of concept, no more. Other implementations can fake it and make various compromises. I would consider it a flaw if an implementation adds functionality that is not part of clean DCI. (An example could be using role methods outside their Context).

The concept of DCI should not depend on implementation language. The fact that something can be done doesn't mean that we want to do it.

--Trygve

On 2011.10.23 14:39, Rune Funch Søltoft wrote:
Reply all
Reply to author
Forward
0 new messages