From: H. S. Lahman on
Responding to Adaworks...

>>>This conversation began as a discussion of delegation versus inheritance.
>>>Considering my previous paragraph, I am still wondering which programming
>>>language supports a model of delegation that does not require a call-return
>>>implementation.
>>
>>AFAIK, they all do. All one needs to do is define the delegatee, instantiate
>>a relationship to it, and navigate that relationship during collaborations.
>>For example, in the GoF Strategy pattern the delegation of Strategy is from
>>the Context entity:
>>
>> * R1 1
>>[Context] ----------------- [Strategy]
>> A
>> |
>> ...
>>
>>Once one has extracted the [Strategy] delegation from [Context], all one has
>>to do is instantiate R1 with a pointer or somesuch to access a particular
>>Strategy from a given Context during a collaboration.
>>
>>But that's too easy, so I have to conclude I don't understand your point.
>>Specifically, what do you mean by "call-return"?
>>
>
> Languages such as C++, et al, depend on member functions for the
> implementation of methods. These, in turn, involve a call-return
> mechanism where a stack entry allows the method, at completion,
> to return to the point of the call and continue execution from that
> point.

But that is just a 3GL message passing mechanism (and one of the major
compromises the OOPLs make with the hardware computational models!).
The delegation and message communication are defined at the OOA/D level,
which is at a much higher level of abstraction. For example, the
delegation could be implemented with events through an event queue just
as easily as with a direct call. Then the client can complete before
the delegatee even starts, much less return. The OOA/D delegation is
completely indifferent to that.

>
> I pure delegation, a message is passed to a method in a delegator,
> the delegator can forward that message to a method in another
> class without the need for a stack entry. It is pure message
> passing mechanism. The delegator is an agent that simply sends
> the message on to the delegatee. When the delegatee has finished
> doing its work on the message, it does not unwind through the
> stack to pass back through the delegator.

I think this is an entirely different methodological issue. Good OOA/D
practice precludes using the delegator as this sort of forwarding agent.
The original client should navigate relationships directly to the
delegatee once the delegation has taken place.

[See my most recent response to Kazakov in this subthread for why that
is a poor practice. In a nut shell the reason the agent is a problem is
because if requirements change the nature of the collaboration, the
middleman will have to be modified as well as the client and delegatee.
Since the OO paradigm is designed to minimize maintenance changes,
using this sort of agent breaks the peer-to-peer mandate of the paradigm.

BTW, I believe the GoF made a marvelous contribution but they didn't get
everything quite right. One problem was promulgating the non-OO agent
approach for communicating in their implementation examples, which was a
carry-over from pre-OO layered model infrastructure implementations.
Unfortunately, since they were among the earliest advocates of
delegation in OO contexts, they have set a very poor example for
implementing delegation. As a result I am seeing more and more of this
practice.]

Thus when

[Client]
| *
|
| R1
|
| accesses
| 1
[Context]

becomes

[Client]
| *
|
| R1
|
| is related to
| 1
[Context]
| *
|
| R2
|
| has role of
| 1
[Strategy]

The Client should navigate R1 -> R2 to talk directly to the Strategy.
[Context] no longer has the responsibility that the Client needs to
collaborate with so its only role in the collaboration is a placeholder
to constrain participation in the collaboration via the R1 and R2
relationship instantiations that restrict which Strategy the Client can
collaborate with.

Note that in the abstract action languages (AAL) for OOA/D the method in
client that generates the message would look something like this before
delegation:

ref = this -> R1 // obtain collaboration target address
GENERATE M1 ref .... // send message to collaboration target

and something like this after delegation:

ref = this -> R1 -> R2 // obtain collaboration target address
GENERATE M1 ref .... // send message to collaboration target

Note that Client needs to know nothing about who Context and Strategy
are, not even their class names. It only needs to know what message to
send (M1) and that the static relationship path exists in the OOA/D
model. Most important of all, the separation of message content (M1 and
"...") from message addressing is very clear in the AAL. That's because
all collaborations are supposed to be peer-to-peer and the relationship
navigation path may be quite complex.

>
> Consider this scenario. You are the supervisor of a group
> of people. You ask a member of your team to carry out
> some task. That team member assigns the task to one of
> his subordinates and indicates the source of the request. When
> the subordinate completes the task, s/he notifies the original
> requestor without having to first notify the foreman.

I the problem with this analogy is that it implies there is a choice.
Deciding whether there is delegation or not is a basic part of the
solution and it is reflected in the static structure of the OOA/D model.
So either the team member reassigns the task or not. Once that static
structure is "hard-wired" into the solution, the collaboration to
trigger the task is still between the supervisor and whoever actually
does the task and the collaboration will navigate the existing static
structure to properly address the message.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hir
From: Dmitry A. Kazakov on
On Sun, 03 Sep 2006 17:34:24 GMT, H. S. Lahman wrote:

> Responding to Kazakov...
>
>> How so? Clearly T::Foo is shared between T and S. After all, the ultimate
>> goal of delegation is re-use. How could that happen without sharing?
>
> As I illustrated in the Car example a couple of messages ago, A Drive
> Train is not a Car by any stretch of the imagination. They are quite
> different things and they share no properties. There is no relation
> between their types; there is only a logical association between objects.

You didn't say *what* you wanted to delegate and how this managed to stay
not shared.

>>>IOW, objects collaborate on a peer-to-peer basis.
>>
>> OK, that's the same disagreement between us. There is no peers at the
>> abstraction level of types. You won't get me back down to the ad-hockery of
>> individual objects... (:-))
>
> Dmitry, I got to ask it: what are you doing on an OO forum if you refuse
> to accept the most fundamental tenets of OOA/D?

As I said, we have different views on what OO is. This includes A/D.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: S Perryman on
<adaworks(a)sbcglobal.net> wrote in message
news:N7oKg.14496$%j7.3691(a)newssvr29.news.prodigy.net...

> "H. S. Lahman" <h.lahman(a)verizon.net> wrote in message
> news:ixhJg.8950$4O4.2902(a)trnddc02...

>> Responding to Adaworks...

>>> This conversation began as a discussion of delegation versus
>>> inheritance.
>>> Considering my previous paragraph, I am still wondering which
>>> programming
>>> language supports a model of delegation that does not require a
>>> call-return
>>> implementation.

>> AFAIK, they all do. All one needs to do is define the delegatee,
>> instantiate a relationship to it, and navigate that relationship during
>> collaborations. For example, in the GoF Strategy pattern the delegation
>> of Strategy is from the Context entity:
>>
>> * R1 1
>> [Context] ----------------- [Strategy]
>> A
>> |
>> ...
>>
>> Once one has extracted the [Strategy] delegation from [Context], all one
>> has to do is instantiate R1 with a pointer or somesuch to access a
>> particular Strategy from a given Context during a collaboration.

>> But that's too easy, so I have to conclude I don't understand your point.
>> Specifically, what do you mean by "call-return"?

> Languages such as C++, et al, depend on member functions for the
> implementation of methods. These, in turn, involve a call-return
> mechanism where a stack entry allows the method, at completion,
> to return to the point of the call and continue execution from that point.

> In pure delegation, a message is passed to a method in a delegator,
> the delegator can forward that message to a method in another
> class without the need for a stack entry. It is pure message
> passing mechanism.

That is how it is implemented in prog langs such as Actor etc.


> The delegator is an agent that simply sends
> the message on to the delegatee. When the delegatee has finished
> doing its work on the message, it does not unwind through the
> stack to pass back through the delegator.

This is pretty much how it works in the "prototype-based" languages
(Self etc) . And if an object cannot respond to the request, it delegates
to all its contained objects until one or none of them respond.


And I think I have indirectly answered your musings as to which prog langs
implement delegation by message passing. :-)


Regards,
Steven Perryman


From: H. S. Lahman on
Responding to Kazakov...

>>>How so? Clearly T::Foo is shared between T and S. After all, the ultimate
>>>goal of delegation is re-use. How could that happen without sharing?
>>
>>As I illustrated in the Car example a couple of messages ago, A Drive
>>Train is not a Car by any stretch of the imagination. They are quite
>>different things and they share no properties. There is no relation
>>between their types; there is only a logical association between objects.
>
>
> You didn't say *what* you wanted to delegate and how this managed to stay
> not shared.

In the original examples,

<examples>
In some problem context I may have a notion of Car. That Car will have
a drive train in the problem space. But if my problem context doesn't
need to know anything special about the drive train (e.g., the
application in an inventory control program), I can abstract the notion
of a drive train as simply properties of a [Car] abstraction
(horsepower, fuel consumption, etc.) without any delegation of
generalization.

OTOH, if my problem space is an auto assembly plant, the drive Train
exists independently of the Car until it is incorporated in the
assembly. So I need to model the Drive Train as an object independent
of Car that becomes a component of a Car. But the Drive Train is not a
Car in that context by any stretch of the imagination so no
generalization relations exists between them. All one has is a simple
conditional association between peer objects.
</examples>

The first paragraph represents Car without delegation while Drive Train
is clearly delegated from Car in the second paragraph. When that
delegation is abstracted all the properties (horsepower, fuel
consumption, etc.) that are related to a drive train are removed from
Car and allocated to the Drive Train object. There is no longer any
shared semantics; Car and Drive Train only have an association to
determine which members of their respective sets may collaborate.

>>>>IOW, objects collaborate on a peer-to-peer basis.
>>>
>>>OK, that's the same disagreement between us. There is no peers at the
>>>abstraction level of types. You won't get me back down to the ad-hockery of
>>>individual objects... (:-))
>>
>>Dmitry, I got to ask it: what are you doing on an OO forum if you refuse
>>to accept the most fundamental tenets of OOA/D?
>
>
> As I said, we have different views on what OO is. This includes A/D.

An interesting Freudian Typo (A/D vs. OOA/D). B-) IMO, whatever you
are doing for A/D clearly isn't OOA/D. That's because you can't do
OOA/D if you restrict your thinking to types. One can make a strong
case for the assertion that the evolution of OOA/D since Smalltalk was
driven in no small part by the need to avoid the foot-shooting that
became apparent when people actually started using the OOPL type systems.

Types represent a major compromise with hardware models (e.g., explicit
support of procedural message passing). As a result those compromises
make it very easy to overlay procedural design techniques onto the
OOPLs. They also have nasty side effects like physical coupling.
Proper OOA/D is required to ensure that those compromises don't
introduce problems like hierarchical dependencies and physical coupling.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH



From: Dmitry A. Kazakov on
On Mon, 04 Sep 2006 15:09:16 GMT, H. S. Lahman wrote:

> Responding to Kazakov...
>
>>>>How so? Clearly T::Foo is shared between T and S. After all, the ultimate
>>>>goal of delegation is re-use. How could that happen without sharing?
>>>
>>>As I illustrated in the Car example a couple of messages ago, A Drive
>>>Train is not a Car by any stretch of the imagination. They are quite
>>>different things and they share no properties. There is no relation
>>>between their types; there is only a logical association between objects.
>>
>> You didn't say *what* you wanted to delegate and how this managed to stay
>> not shared.
>
> In the original examples,
>
> <examples>
> In some problem context I may have a notion of Car. That Car will have
> a drive train in the problem space. But if my problem context doesn't
> need to know anything special about the drive train (e.g., the
> application in an inventory control program), I can abstract the notion
> of a drive train as simply properties of a [Car] abstraction
> (horsepower, fuel consumption, etc.) without any delegation of
> generalization.
>
> OTOH, if my problem space is an auto assembly plant, the drive Train
> exists independently of the Car until it is incorporated in the
> assembly. So I need to model the Drive Train as an object independent
> of Car that becomes a component of a Car. But the Drive Train is not a
> Car in that context by any stretch of the imagination so no
> generalization relations exists between them. All one has is a simple
> conditional association between peer objects.
> </examples>
>
> The first paragraph represents Car without delegation while Drive Train
> is clearly delegated from Car in the second paragraph. When that
> delegation is abstracted all the properties (horsepower, fuel
> consumption, etc.) that are related to a drive train are removed from
> Car and allocated to the Drive Train object. There is no longer any
> shared semantics; Car and Drive Train only have an association to
> determine which members of their respective sets may collaborate.

This still does not answer the question: what does Car delegate to Drive
Train?

And "semantics" is not something you could "store", "allocate", "keep" etc.
Semantics is a relation between signs and what they represent. If a car
represents a drive train, this does not necessary mean that it physically
is a drive train. Your representative in the Congress is not you, though
you *delegated* to him some of your constitutional rights. When you
exercise your rights through him, it does not mean that he lives in your
home and wears your socks...

>>>>>IOW, objects collaborate on a peer-to-peer basis.
>>>>
>>>>OK, that's the same disagreement between us. There is no peers at the
>>>>abstraction level of types. You won't get me back down to the ad-hockery of
>>>>individual objects... (:-))
>>>
>>>Dmitry, I got to ask it: what are you doing on an OO forum if you refuse
>>>to accept the most fundamental tenets of OOA/D?
>>
>> As I said, we have different views on what OO is. This includes A/D.
>
> An interesting Freudian Typo (A/D vs. OOA/D). B-)

It was not a typo, I intentionally used it without OO. Not all A/D is OO,
and OO is not exclusively about A/D.

> IMO, whatever you
> are doing for A/D clearly isn't OOA/D. That's because you can't do
> OOA/D if you restrict your thinking to types. One can make a strong
> case for the assertion that the evolution of OOA/D since Smalltalk was
> driven in no small part by the need to avoid the foot-shooting that
> became apparent when people actually started using the OOPL type systems.
>
> Types represent a major compromise with hardware models (e.g., explicit
> support of procedural message passing). As a result those compromises
> make it very easy to overlay procedural design techniques onto the
> OOPLs. They also have nasty side effects like physical coupling.
> Proper OOA/D is required to ensure that those compromises don't
> introduce problems like hierarchical dependencies and physical coupling.

Types don't restrict anything. They just cannot do that, because type is an
abstraction. [ Proof: make each object singleton. q.e.d. ]

---------
Since you have returned to the core of our disagreement. I repeat the point
I made in our previous discussions. "Peer-to-peer collaboration" is the
*lowest* possible abstraction level. You could claim that logging is a peer
to peer collaboration between an axe and a tree, but that would impress
nobody. The problem at hand is to deal with forests and cubic kilometers of
wood. It is a way different level.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de