Dynamic extension at the bottom of the class hierarchy

37 views
Skip to first unread message

Trygve Reenskaug

unread,
Dec 10, 2011, 7:50:42 AM12/10/11
to DCI-object-evolution, r...@asseco.dk
I have rocked the boat again. I have got rid of Traits. DCI gets simpler and simpler, IMO.

Traits carried a lot of excess baggage for method injection etc. I have replaced Traits with a class for each role, subclass of RuntimeRole. This class is special in many ways:
  • Its methods are RoleMethods.
  • Its methods are compiled in the context of a DCI Context as described earlier.
  • Its methods are executed in the context of a RolePlayer object. (NOT an instance of the RuntimeRole)
  • It shall never be subclassed.
It seems to me that we now have a fundamental extension of the notion of object orientation that adds runtime features to the common static features of programs. Conventionally, an object receives a message; the corresponding method is found by searching the object's class and its superclasses. The RuntimeRole acts as a very dynamic class. A Role receives a message; the corresponding method is found by searching the RuntimeRole followd by the object's class and its superclasses.

Put another way, the RuntimeRole is attached at the bottom of the class hierarchy for the purpose of method selection. This attachement is ephemeral, it only lasts as long as it takes to select the method. This mechanism is new and fundamental.

One of the brilliant aspects of Jim's Dijkstra algorithm is that its recursion exposes the dynamic nature of DCI.
I have extended the Dijkstra RoleMethods with trace statements at the beginning and end of each method. Here is the trace of an execution. It clearly illustrates that an object can be bound to play several roles at the same time. I have highlighted
    [1756] : BB7Node >> computeDistances {CurrentIntersection, Enter}
    [1756] : BB7Node >> computeDistances {CurrentIntersection, Leave}
to show that this single method execution can last almost from beginning to end.

The format of each trace is
    [object ID] object class >> RoleMethod selector (roleName, Enter/Leave)


[1750] : BB7Node >> computeDistances {CurrentIntersection, Enter}
[2736] : BB7Node >> recomputeTentativeDistance {EastNeighbor, Enter}
[1750] : BB7Node >> distanceTo: {CurrentIntersection, Enter-Leave}
[2736] : BB7Node >> recomputeTentativeDistance {EastNeighbor, Leave}
[1756] : BB7Node >> recomputeTentativeDistance {SouthNeighbor, Enter}
[1750] : BB7Node >> distanceTo: {CurrentIntersection, Enter-Leave}
[1756] : BB7Node >> recomputeTentativeDistance {SouthNeighbor, Leave}
[1756] : BB7Node >> computeDistances {CurrentIntersection, Enter}
[1210] : BB7Node >> recomputeTentativeDistance {EastNeighbor, Enter}
[1756] : BB7Node >> distanceTo: {CurrentIntersection, Enter-Leave}
[1210] : BB7Node >> recomputeTentativeDistance {EastNeighbor, Leave}
[3193] : BB7Node >> recomputeTentativeDistance {SouthNeighbor, Enter}
[1756] : BB7Node >> distanceTo: {CurrentIntersection, Enter-Leave}
[3193] : BB7Node >> recomputeTentativeDistance {SouthNeighbor, Leave}
[1210] : BB7Node >> computeDistances {CurrentIntersection, Enter}
[3139] : BB7Node >> recomputeTentativeDistance {EastNeighbor, Enter}
[1210] : BB7Node >> distanceTo: {CurrentIntersection, Enter-Leave}
[3139] : BB7Node >> recomputeTentativeDistance {EastNeighbor, Leave}
[2736] : BB7Node >> computeDistances {CurrentIntersection, Enter}
[3246] : BB7Node >> recomputeTentativeDistance {EastNeighbor, Enter}
[2736] : BB7Node >> distanceTo: {CurrentIntersection, Enter-Leave}
[3246] : BB7Node >> recomputeTentativeDistance {EastNeighbor, Leave}
[1210] : BB7Node >> recomputeTentativeDistance {SouthNeighbor, Enter}
[2736] : BB7Node >> distanceTo: {CurrentIntersection, Enter-Leave}
[1210] : BB7Node >> recomputeTentativeDistance {SouthNeighbor, Leave}
[3193] : BB7Node >> computeDistances {CurrentIntersection, Enter}
[3999] : BB7Node >> recomputeTentativeDistance {EastNeighbor, Enter}
[3193] : BB7Node >> distanceTo: {CurrentIntersection, Enter-Leave}
[3999] : BB7Node >> recomputeTentativeDistance {EastNeighbor, Leave}
[3139] : BB7Node >> computeDistances {CurrentIntersection, Enter}
[3893] : BB7Node >> recomputeTentativeDistance {SouthNeighbor, Enter}
[3139] : BB7Node >> distanceTo: {CurrentIntersection, Enter-Leave}
[3893] : BB7Node >> recomputeTentativeDistance {SouthNeighbor, Leave}
[3999] : BB7Node >> computeDistances {CurrentIntersection, Enter}
[3893] : BB7Node >> recomputeTentativeDistance {EastNeighbor, Enter}
[3999] : BB7Node >> distanceTo: {CurrentIntersection, Enter-Leave}
[3893] : BB7Node >> recomputeTentativeDistance {EastNeighbor, Leave}
[3246] : BB7Node >> computeDistances {CurrentIntersection, Enter}
[3139] : BB7Node >> recomputeTentativeDistance {SouthNeighbor, Enter}
[3246] : BB7Node >> distanceTo: {CurrentIntersection, Enter-Leave}
[3139] : BB7Node >> recomputeTentativeDistance {SouthNeighbor, Leave}
[3893] : BB7Node >> computeDistances {CurrentIntersection, Enter}
[3893] : BB7Node >> computeDistances {CurrentIntersection, Leave}
[3246] : BB7Node >> computeDistances {CurrentIntersection, Leave}
[3999] : BB7Node >> computeDistances {CurrentIntersection, Leave}
[3139] : BB7Node >> computeDistances {CurrentIntersection, Leave}
[3193] : BB7Node >> computeDistances {CurrentIntersection, Leave}
[2736] : BB7Node >> computeDistances {CurrentIntersection, Leave}
[1210] : BB7Node >> computeDistances {CurrentIntersection, Leave}
[1756] : BB7Node >> computeDistances {CurrentIntersection, Leave}
[1750] : BB7Node >> computeDistances {CurrentIntersection, Leave}

'Shortest path from #a to #i in BB7ManhattanTest1 is: '
     #a #d #g #h #i

My Dijkstra Squeak code is at   http://fulloo.info/Examples/SqueakExamples/BB7Dijkstra/BB7Dijkstra.html

Serge Beaumont

unread,
Dec 10, 2011, 9:38:28 AM12/10/11
to dci-ev...@googlegroups.com, DCI-object-evolution, r...@asseco.dk
Trygve,

What you describe seems to be the mechanism that "my" Python DCI implementation does. I'd like it if you take a look at the code I posted recently (on obj-comp I believe). If you need some help to understand or setting up Python I'd be glad to help.

Sent from my iPhone

Trygve Reenskaug

unread,
Dec 10, 2011, 9:57:00 AM12/10/11
to dci-ev...@googlegroups.com
Serge,
I'm not familiar with Python and doubt I can easily read it to the depth required here. But if you are really able to do this, it is really deeply interesting as well as surprising.:
"RuntimeRole is attached at the bottom of the class hierarchy for the purpose of method selection. This attachment is ephemeral, it only lasts as long as it takes to select the method."
Note: This is truly dynamic. There is no change to the object or the object's class at any time. There is never any Role instance (i.e. no wrapper of any kind)
--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 Coplien

unread,
Dec 10, 2011, 10:42:41 AM12/10/11
to dci-ev...@googlegroups.com

On Dec 10, 2011, at 2:57 , Trygve Reenskaug wrote:

I'm not familiar with Python and doubt I can easily read it to the depth required here. But if you are really able to do this, it is really deeply interesting as well as surprising.:
"RuntimeRole is attached at the bottom of the class hierarchy for the purpose of method selection. This attachment is ephemeral, it only lasts as long as it takes to select the method." 
Note: This is truly dynamic. There is no change to the object or the object's class at any time. There is never any Role instance (i.e. no wrapper of any kind)


This was also my superficial understanding of how the Python code worked.

Trygve Reenskaug

unread,
Dec 10, 2011, 12:52:10 PM12/10/11
to dci-ev...@googlegroups.com
I've looked at your three files for the money transfer example in your message to objectComposition on 2011.12.04 20:15.  Sorry I didn't look at this code earlier; I didn't realize its importance.

The example looks very nice indeed. It will be interesting to see how your framework handles the Dijkstra example with its recursion and many-to-many relationships between role and object.

Cheers
--Trygve

Serge Beaumont

unread,
Dec 10, 2011, 4:17:40 PM12/10/11
to dci-ev...@googlegroups.com
I'll look into it and see if I can implement Dijkstra's algorithm. In the end my strong points are thinking in structures and abstraction, not so much deep math stuff. But I'll give it a try, good to flex that part of my brain again (my current day job is agile consultancy :-) ).

Trygve Reenskaug

unread,
Dec 10, 2011, 4:49:43 PM12/10/11
to dci-ev...@googlegroups.com
There's no deep math there. Just a plain and simple algorithm. There are both Jim's and my implementation you can look at.
Reply all
Reply to author
Forward
0 new messages