FullOO (a.k.a. DCI) Summit in Oslo

26 views
Skip to first unread message

James O. Coplien

unread,
Aug 20, 2011, 12:21:11 PM8/20/11
to object-co...@googlegroups.com, dci-ev...@googlegroups.com
Cope went to visit Trygve for about three days in the beginning of August and, as usual, there was a lot of energetic discussion. In addition to the usual fun smoke and heat, some light also came out. Here are the major upshots of the week.


Abstraction Layers and the difference between Restricted and Full OO

Alan Kay coined the term "object orientation" and likened an object system to a system having thousands and thousands of computers all hooked together by a very fast network. That perspective grounds some of what follows here. Think of computer hardware as a programming API. It provides an abstraction layer. Trygve and Cope define an abstraction layer as a shared understanding of the essential behaviors of an object as seen from a client, while the details of the implementation are hidden. We want to follow the #1 rule of software design: no surprises. That implies that the hardware can't reach up into the software and do unexpected things. If the garbage collector leaks, then the hardware doesn't implement a good abstraction layer. It also implies that the software can't do things to the hardware. You can generalize this concept to layers of software, so the operating system also provides an abstraction layer. 

Trygve is now talking about "Restricted OO" — which is OO-as-we-knew-it-before-DCI with restrictions that makes the code readable. This in contrast to "Full OO" which DCI implements. Maybe there will be other ways to implement it, too. There is a simple but stunningly powerful difference between the two and we spent much collective effort on deepening our understanding of those perspectives. The difference is in the programmer's observation point.


Restricted OO

With Restricted OO, the programmer observes the system from the inside of an object. The class defines what the programmer can and cannot see. A programmer can see:
  • The state of an instance as defined by its class attributes.
  • What messages an instance can receive.
  • The methods that will be triggered by those messages.
  • The attributes that are changed by those methods
  • The messages that are and the types of the objects that will receive those messages.
There are many things the programmer cannot see by reading the class code. Examples:
  • The sender of a received message and the purpose of this message seen within a wider context.
  • The class  of the receiver of a message sent from an observed object. 
The reason for these limitations is that this receiver lives within an abstraction boundary. The programmer cannot know, at compile time, which behavior will be invoked at runtime – by design.  A programmer can understand the program behavior only in general terms.

This is an essential part of the "power" of object orientation.

Unrestricted programming with classes — which is OO-as-we-knew-it-before-DCI – can lead to unreadable spaghetti code. We call it  “Unrestricted OO”.

We spent quite some time discussing the restrictions needed to get readable code. It appeared to have something to do with the abstraction boundary between a client and the inside of an object. Perhaps it would be illegal for an execution to cross back up across the boundary to do unpredictable things to the client. We did not conclude and the work continues. The result shall be a rule that is the “restricted” in Restricted OO. We hope that Unrestricted OO some time in the future will be relegated to history.


Full OO

With Full OO, the programmer observes the system from the space between the objects. Programmers can see several objects at once and observe the interaction messages that flow between them. They can’t see inside the objects because each lives behind its own abstraction layer boundary. They can't even know, at compile time, which behavior would be invoked at run time — by design.

DCI implements system behavior by pulling together the behavior of a system operation into several co-located roles, each representing an object. The programmer can see the roles together and reason about their end-to-end behavior. The system behavior is explicitly given by the RoleMethods that are outside any abstraction boundary. There is still an abstraction barrier: between the roles and the objects that play those roles. This barrier has the usual restriction: The object implementation can't reach up into the Interaction and do unexpected things. However, it is a very narrow abstraction layer whose operations should be viewed as primitive, and which, by design, always return. To be able to reason across a sequence of mutually invoking roles means to be able to reason about several objects at once.

Define a compression as a way to represent that information in fewer bits of data than the amount of information it contains, using contextual knowledge that makes it possible to losslessly expand that representation into the original information. In Restricted OO, a programmer cannot compress the understanding of anything: everything is an abstraction, except the current method. There is a large lack of contextualization. In Full OO, RoleMethods are compressions.

In DCI terms: Data classes are coded with Restricted OO. Interactions are coded with Full OO.

Restricted OO is very much like the Atomic Event Architecture of the Lean Architecture book (e.g., a traditional "shapes" OO program, with very simple operations); Full OO is like DCI.

We spent a lot of energy and time on these concepts and feel they will prove useful when worked out in detail.
 

Handoffs

We had a few discussions about handoffs. In Lean architecture, you want to avoid handoffs, so there should be no major (human) communication boundary between Context code and Data code. This means that the writer of the code for a Context with its roles and role methods should cooperate closely with the writer of the associated Data classes to adapt the abstractions to the needs of the system as a whole.

On the other hand, there are abstractions within abstractions and the transparency of the abstractions are reduced down the abstraction hierarchy. (There is no hard-and-fast rule; the developers of the first Smalltalk runtime system created private microcode for their Alto computer to optimize their system). Theoreticians will claim that any interface to an object must be supported by precise definitions of its operations with preconditions, postconditions etc.

In some sense, the whole purpose behind the DCI encapsulation of roles is that they are all in one place where they can be considered together without going across an abstraction boundary. But with a role method saying self–>something, we cross an abstraction boundary and must rely on it being implemented correctly. (Otherwise, the code of the RoleMethod would be unreadable).

Abstraction boundaries, therefore, are an agreement based on mutual trust. They are maybe a way of encapsulating change at some level. But that isn't a reason to really "hide" the changes. Everybody, all together, from early on — on everything.

So abstraction boundaries, rather than being viewed as "don't look here" fences, draw attention as key points of agreement around crucial architectural issues that the abstraction boundaries bring into focus.

 
Context / Role Integration

We agreed it would be a good idea if every Context could play some kind of Context role. That would make it possible to view the Context as a role from inside itself, and as an ordinary object from outside itself, thereby providing a smoother impedance match across the Context abstraction layer boundary. The Context could be a repository for state common to the whole interaction and visible to  RoleMethods through its role name, standardized at e.g., CurrentContext. This idea needs more work. For example an implementation — the true killer of good ideas.

 
DCI and Systems Complexity

We talked a little about simple, complicated, complex and chaotic systems (Snowden's taxonomy). DCI is interesting because it can implement an adaptive system. It responds to changes in its environment, implementing an open system that has a degree of self-organization. While Restricted OO systems are also open systems, they aren't adaptive.

DCI does this by effectively implementing a weak form of reflection.

 
Articles

Trygve gave Cope comments on his Elephant article, first suggesting that it be re-written from scratch with more precisely defined concepts. He has later withdrawn the suggestion since he realized that the entertainment value of the current form would be lost with very little gain. Cope continues to refine the article, and won't do a major upheaval.


Web Site

We have bought FullOO.info on a Norwegian web hosting site. Cope is supposed to set that up but is a bit lost right now, partly because their setup is a bit mysterious. (They already sold us oo.info and after a week of not being able to make it work they admitted a bug in their system that allowed them to sell us a URL that had previously been allocated to someone else.) The main issue seems to be that though he purchased a URL and 8 gigabytes of storage, we still don't appear to have anything with an IP address. There is something wrong with the hosting site. Trygve will  phone them (in Norwegian) and expect they'll fix the problem quickly. Then we can get down to the much wanted Q&A section and collect other material that should go to the site.
 
 



Cevat Serkan Balek

unread,
Sep 23, 2011, 9:34:53 AM9/23/11
to dci-ev...@googlegroups.com
Dear group,

I have read the document and want to add some sociological aspects for the important facts mentioned. This way, I aim to make the current software development climate and the problems of it more clearly pictured. I hope, this helps us to see the landscape more clearly.


With Restricted OO, the programmer observes the system from the inside of an object.

Throughout all my career, I have always seen a constant debate -or fight- between managers and developers on not being able to see the big picture. Sadly, there are only a few people who really recognize our programming tools are not allowing us to hold the big picture and reason about it. This has a very strange effect, especially in team communication.

The teams now constantly communicate on the things that should be mostly handled and guaranteed by the programming system. Worse, usually the moderate truck number is so low that only project managers have a full grasp of the system on all the contexts. The team need a contextual programming environment, because what the system does usually is currently a magic, it resides in the collaborative mind of the team, and this kills that mind's creativity.

However, the main responsibility of the team should be to communicate about what the system is/does, and code it to a reliable programming environment that can hold the whole context that they intended. Consequently, by regaining the lost energy via the contextual programming system, the team can have more energy to discuss more important issues such as design, usability, evolvability, security, etc.

The other important issue which is already boldly stated in DCI frequently is that, the inability to specify what's going on in inter-object space is not acceptable to a software engineer, or to any software professional on other disciplines.

RestrictedOO is only suitable for dumb (slightly intelligent just enough to speak about themselves) data objects, because RestrictedOO is based on classification. The classification techniques works best for classifying things, that is data: what the system is. The programmer is encouraged the look from inside of an object only in this situation.

P.S. As I wrote the first long comment for the first fact depicted by Trygve&Jim, I decided to add my comments on each fact in seperate e-mails for convenience. I believe, each of these facts should bear their own subjects, if the owner of this thread decides to do so.

Best regards,

Cevat Balek

ant.ku...@gmail.com

unread,
Sep 23, 2011, 12:44:32 PM9/23/11
to dci-ev...@googlegroups.com
Hi Cevat and others,

"...because RestrictedOO is based on classification."

While not directly related to what you wrote Cevat, this phrase made me think of something.

Becaue my language of choice forces me to delare types (for parameters, arguments, variables, fields, etc), I find myself often thinking of roles in terms of their interfaces.  Implicitly, this means I am classifying roles, doesn't it?

But I don't feel this hinders anyone.  Take my Till example, where the basket can play the role of a printer in order to print receipts.

While the object Basket is playing the role of a Printer, it is a Printer; it is a type of Printer; it is of type Printer; it's type is indeed Printer - so a role is also a classification [1], just special because it never has it's own state.  In that respect, if the Basket is a printer in the context, why not declare its type, if the language requires that:

   Printer printer = basket assign Printer;

Same goes for the Account object playing the role of the source account.  In those few moments when it is inside the Transfer context, the account is a source account - note how I used "is a" - which classically describes inheritance in traditional OO, i.e. a classification.

So, back to your statement Cevat: "RestrictedOO is only suitable for dumb objects, because RestrictedOO is based on classification".

I argue that DCI too is based on classification.  But in DCI, there are many more types of objects (ie many more classifications) than in traditional OO.  A role in DCI is a classifier which describes the behaviour which an object gains by playing the role.

A second point: I like the phrase "inter-object space".  Thinking back to my Till example, the interactions going on between the printer, sales log, sales order database, payment partner, basket, till, etc. during the sales context is a classic example of this inter-object space where you see the bigger picture.  Traditionally, the steps of the use case are distributed around several classes and get lost in the blur of the entire system.  It is nice that in DCI I have a place for this inter-object view, i.e. the context.  But we need to be a little careful because  such spaces can exist in traditional OO or service orientation (both of which are RestrictedOO).  If you use the MVC pattern in OO, you stick this inter-object stuff into the controller.  If you use a process/application-layer or façade in SOA, that is the place to stick the inter-object stuff.  Fair enough that in these cases, the inter-object space is outside of the mental model which any non-techie will have.  And it is true that normally these places soon get lost amongst all the rest of the RestrictedOO system.  From that perspective, DCI works nicely by giving a "namespace" (in the loose sense of the word) to all those parts of the system which belong together for a use case.  That leaves the reader with the ability to reason about the bigger picture, as you nicely put it.  But I have seen medium complex systems built in RestrictedOO, where the reader can also reason about the bigger picture.  I wonder if a very complex system build in DCI also removes the ability for the reader to reason about the bigger picture, for other (perhaps as yet undiscovered) reasons?


Cheers,
Ant

[1] Take Figure 9.8 in the UML Infrastructure 2.3, which shows that a Classifier is associated with a set of features.  A role is a set of features, is it not?  Hence a role could be a classifier, which in turn is defined as a "Classification of instances according to their features".

rune funch

unread,
Sep 24, 2011, 3:58:17 AM9/24/11
to dci-ev...@googlegroups.com

Hi Cevat and others,

"...because RestrictedOO is based on classification."

While not directly related to what you wrote Cevat, this phrase made me think of something.

Becaue my language of choice forces me to delare types (for parameters, arguments, variables, fields, etc), I find myself often thinking of roles in terms of their interfaces.  Implicitly, this means I am classifying roles, doesn't it?

But I don't feel this hinders anyone.
Thinking of roles in terms of an explicit interface actually does hinder me at the moment. I have a side project where I'm developing an application for mobile platforms. I'm using MonoToiuch and MonoDroid. Most of the code I write is going to be platform independent but some stuff is going to be platform dependent. I can't change the interfaces the types implement, and even if I could I would want to be cause those changes would disappear with the next release of MonTouch/Droid. If the context where these objects plays a role was based on interfaces I would have to implement them once for each platform. Now I can reuse them as long as the potential roleplayers have methods signatures/properties that match. In this case method signatures that match is not very likely and I have to adapt them but for a text label to have a property called Text or similar is very likely.

I agree that DCI classifies as well but in a different manner. For lack of better terms I'd say you could talk about inhibiting and facilitating classifications. An inhibiting classification would be the classes societies a few hundred years back. Up north where I'm from we had "trælle" (kind of a slave) "bønder" (peasants) and "herremænd" (nobles). Those were classifications of the people of Scnadinavia a few hundred years back. You were born into one of those classes a with a high probability you'd die in the same. That classification inhibits you from becoming anything else.
Today we have other kinds of classifications e.g. we classify people as a pilot if they are flying a plane. We expect them to have all the required abilities to fly the plane but leave it to some one else to verify that.

To me using interfaces on data to determine what roles they can play lands in the inhibiting classification style. They can only play those roles and more importantly those types that does not implement those interfaces are inhibited from playing those roles and there's nothing you can do about it as in my example above.

Classifying objects based on what they are doing (roles) is different. As long as the object is playing the role of a pilot the object is a pilot. When implementing the class of the object you don't need to know what roles they are going to play. It won't limit which roles they can play. The abilities of the class determines what roles the objects of said class can play and if a new role comes along the same applies if the behavior is there the object can play the role, you have to change nothing. Having to change nothing is a big difference when the role player is implemented in a library you can't or won't change

-Rune

ant.ku...@gmail.com

unread,
Sep 24, 2011, 4:22:15 AM9/24/11
to dci-ev...@googlegroups.com
Yes, so for the role classification to not be inhibiting, the language (or framework?) needs to be dynamic.  We must not be forced to define a priori what roles objects will play, but rather be able to assign them dynamically at runtime.

But none of that has much to do with using a typed name to refer to a role player. In fact sometimes that can be an advantage.  For example it can assist tools in offering support like code completion and refactoring.

----- Reply message -----
From: "rune funch" <funchs...@gmail.com>
To: <dci-ev...@googlegroups.com>
Subject: FullOO (a.k.a. DCI) Summit in Oslo

rune funch

unread,
Sep 24, 2011, 4:31:13 AM9/24/11
to dci-ev...@googlegroups.com


Mvh
Rune

Den 24/09/2011 kl. 10.22 skrev "ant.ku...@gmail.com" <ant.ku...@gmail.com>:

Yes, so for the role classification to not be inhibiting, the language (or framework?) needs to be dynamic.  We must not be forced to define a priori what roles objects will play, but rather be able to assign them dynamically at runtime.

But none of that has much to do with using a typed name to refer to a role player. In fact sometimes that can be an advantage.  For example it can assist tools in offering support like code completion and refactoring.
But how are you going to bind something of a DIFFERENT type to that? Of course I know your answer. You're not. You're going to create a new object of a different type and assign that object therefor creating a need to think in terms of those types. The intellisense can be accomplished with out the type declaration we've already been there. 

Ant Kutschera

unread,
Sep 24, 2011, 8:41:31 AM9/24/11
to dci-evolution
On 24.09.2011 10:31, rune funch wrote:
> But how are you going to bind something of a DIFFERENT type to that? Of course I know your answer. You're not. You're going to create a new object of a different type and assign that object therefor creating a need to think in terms of those types. The intellisense can be accomplished with out the type declaration we've already been there.

You clearly don't know my answer, because it differs from the one you
suggested ;-)

First off, it depends what you mean by "bind something of a different
type to that"?

If you mean how do you bind the same role to a completely different
type of object - the answer is that this is the dynamic part I was
talking about. So long as I have the correct methods / fields in my
object, it can play the role. The list of required methods / fields
is what we called the role contract last year, if you remember. My
BehaviourInjector can do exactly this.

If you mean how do I call a method from a second role on an object,
then lets start with some code:

Cart myCart = new Cart(); //just has wheels, no functionality

Plane myPlane = myCart assign Plane;
Car myCar = myCart assign Car;

assert myCar == myPlane == myCart == true; //this should assert
true!

So I think you are saying that I need two variables (myPlane, myCar)
to refer to the same object, and that is undesirable?

Well, within a scope, in my language of choice, I must decide how I
want to use my objects. If I want to use the cart in the role of a
car, I create a variable of type car:

Car myCar = myCart assign Car;

If I want to use my cart in the role of a plane, I create a variable
of type plane:

Plane myPlane = myCart assign Plane;

If I were to write code like this, *it would surprise the reader*:

public void doSomething(var myCar){
myCar.fly(); //cars can't fly!! surprised!
}

public void doSomething(var myPlane){
myPlane.driveOnHighway(); //planes aren't allowed to do that!!
surprise!
}

public void doSomething(var myCart){
myCart.driveOnHighway(); //carts are dumb! they don't have
behaviour like this!
myCart.fly(); //carts are dumb! they don't have behaviour
like this!
}

Those three blocks of code above are *bad* code, because they
*surprise* the reader! A role is a name. You must choose the correct
name, just as you choose the correct role.

So, in answer to your question (if I understood it right), I must
*first* choose the *correct name* for my object. How about flyingCar:

public void doSomething(var myFlyingCar){
myFlyingCar.driveOnHighway();
myFlyingCar.fly();
}

The block above is a good block of code. There are *no* surprises to
the reader here, because the *name* is correct. Equally, if my
language requires me to declare the type, then I choose/create a
*suitable type*:

public interface FlyingCar extends Plane, Car{}

public void doSomething(FlyingCar myFlyingCar){
myFlyingCar.driveOnHighway();
myFlyingCar.fly();
}

That code is NO DIFFERENT from the code where there is NO type
declaration, except of course, for the type declaration.

All clear?



Now, to the other question:
How can intellisense work with this code snippet:

public void doSomething(var myObject){
... I'm editing here
}

What can code complete tell me if my cursor is on that line? Nothing
at all... even if it had access to every single line of code that will
be deployed in my final system, runtime can't be considered, so it
cannot know which roles (if any) myObject is playing! That is why
that code is illegal in C#, yet the following is legal:

var textToDisplayOnScreen = new String("Hi Rune");

And interestingly, see how I chose a suitable *name*, so that later in
the code, it becomes clear to the reader what that object is capable
of.

Cheers,
Ant

James O. Coplien

unread,
Sep 24, 2011, 9:26:19 AM9/24/11
to dci-ev...@googlegroups.com
Nice metaphor. Rune.

One sign of a dysfunctional language is that you need to know the class of an object to be able to talk to it. One common analog is that you can't talk to an object unless you created it. That amounts to prematurely binding the role to the class. It's not DCI — DCI set out explicitly to solve this problem.

James O. Coplien

unread,
Sep 24, 2011, 9:31:19 AM9/24/11
to dci-ev...@googlegroups.com
Right — the compile-time type is that of the role, not of the object. But that's a gloss that isn't central to DCI.

There has been much talk on the object-composition list of strongly typed or statically typed languages, and the relationship of that typing to DCI. I just don't get it. The first language in which we did DCI was Smalltalk. Yes, C++ followed soon afterwards, but it loses many nice advantages that the Smalltalk or Ruby versions have.

I have often suggested to Trygve that we need some good type theory research behind DCI. That has very little to do with compile-time type checking, however. As has always been known by great object-oriented programmers, compile-time typing's software engineering advantages are often offset by how it harms expressiveness. I think DCI makes that explicit for those who are using it in an informed way.

Ant Kutschera

unread,
Sep 24, 2011, 2:10:28 PM9/24/11
to dci-evolution
On Sep 24, 3:26 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:
> One sign of a dysfunctional language is that you need to know the class of an object to be able to talk to it.

Here is a Javascript object which I once created in a UI. Please name
at least one method you can call on it:

viewModel

> One common analog is that you can't talk to an object unless you created it.

That makes no sense - what languages do that?!

> That amounts to prematurely binding the role to the class. It's not DCI — DCI set out explicitly to solve this problem.

What amounts to prematurely binding the role to the class? I don't
understand. The only time I ever use a type declaration for a role is
at the point I am assigning an object a role, or thereafter.

Cheers,
Ant

Ant Kutschera

unread,
Sep 24, 2011, 2:35:46 PM9/24/11
to dci-evolution
On Sep 24, 3:31 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:
> Right — the compile-time type is that of the role, not of the object. But that's a gloss that isn't central to DCI.
>
> There has been much talk on the object-composition list of strongly typed or statically typed languages, and the relationship of that typing to DCI. I just don't get it.

Me neither! From my perspective, this all started a few weeks ago,
when you challenged us to show how wrappers could be used to implement
DCI solution like your Ruby solution for Dijkstra's Algorithm.

I presented a solution, and listed what I had to do in order to make
it work [1]. There were a number of things which were unsatisfactory
in the wrapper solution.

You criticised the wrapper solution [2] & [3]. Your criticisms partly
seemed to relate to the use of a merged-interface. I wasn't sure if
you were saying the choice of interface name (Mega) was bad, or that
having to declare the type was bad? Perhaps you could answer that
directly, to clear this up for me?

If you were criticising the name, then what I have posted above at dci-
evolution today, or what I posted at [4] should clear that up.
Today, with what I quoted just above, you seem to be saying you don't
care if one has to delcare the type? Then I ask you to read the code
I posted at [4], using a different name for the merged interface, and
highlight the exact lines which disturb you so much, because when I
compare that code, and your ruby code, I see almost exactly the same
thing. Which means wrappers are a suitable way to implement DCI!

> I have often suggested to Trygve that we need some good type theory research behind DCI. That has very little to do with compile-time type checking, however. As has always been known by great object-oriented programmers, compile-time typing's software engineering advantages are often offset by how it harms expressiveness. I think DCI makes that explicit for those who are using it in an informed way.

Oh... and now you're again saying that you don't like type
declarations. Now I don't get it :-/

Cheers,
Ant

[1] http://groups.google.com/group/object-composition/msg/28b8a5d1210d1823
[2] http://groups.google.com/group/object-composition/msg/89aaec370ab269f8
[3] http://groups.google.com/group/object-composition/msg/6598466355c7ff2c
[4] http://groups.google.com/group/object-composition/msg/aa5bfc898904410e


rune funch

unread,
Sep 24, 2011, 2:49:04 PM9/24/11
to dci-ev...@googlegroups.com
Den 24/09/2011 kl. 14.41 skrev Ant Kutschera <ant.ku...@gmail.com>:

> On 24.09.2011 10:31, rune funch wrote:
>> But how are you going to bind something of a DIFFERENT type to that? Of course I know your answer. You're not. You're going to create a new object of a different type and assign that object therefor creating a need to think in terms of those types. The intellisense can be accomplished with out the type declaration we've already been there.
>
> You clearly don't know my answer, because it differs from the one you
> suggested ;-)

Well in the rest of the code you're doing exactly that. You are not
binding your role player to the typed local. You can't Java won't let
you because the role player is not of that type. You assign an object
that has a reference to the role player.


> If I were to write code like this, *it would surprise the reader*:
>
> public void doSomething(var myCar){
> myCar.fly(); //cars can't fly!! surprised!
> }
>

I agree. You've chosen a very misleading name for something that flies :)

> Now, to the other question:
> How can intellisense work with this code snippet:
>
> public void doSomething(var myObject){
> ... I'm editing here
> }

How would I know I don't even know which language it's written in.

As I wrote the other day in F# you try to avoid type declarations.
That doesn't mean there's no intellisense. Just mean than the compiler
does a tremendous job figuring out what type each local/parameter has

> That is why
> that code is illegal in C#

Nope that's not why it's illegal. Depending on how you write. Code
it's entirely possible to write a compiler that can figure out the
type in most cases and let you specify the type if it can't that's
_exactly_ what the F# compiler does.
The C# team decided that the type should be decidable from the
statement declaring the storage location and not from later usage
(which is what F# allows). Similar you can't use var on fields. That's
not because you can't write a compiler that infers the type. It's a
choice made to make it easier to write the C# compiler


>
> Cheers,
> Ant

rune funch

unread,
Sep 24, 2011, 3:06:51 PM9/24/11
to dci-ev...@googlegroups.com
What if the role didn't have a type. What if the name of the role and
role methods was all there was to it?

role SourceAccount{
requires void decreaseBalance(decimal amount);
requires void log(string message);

transaction void transfer(decimal amount){
SourceAccount.decreaseBalance(amount);
SourceAccount.log("decreased balance with " + amount);
DestinationAccount.increaseBalance(amount);
}
}

The role has no type. Any type that has the to methods defined in the
require clauses can be used as role player and intellisense is able to
tell you which members are available on the role and the role player.
The role method is marked as transaction which goes to the discussion
about removing tech stuff from the UC code

-Rune

Ant Kutschera

unread,
Sep 24, 2011, 5:27:01 PM9/24/11
to dci-evolution
On Sep 24, 8:49 pm, rune funch <funchsolt...@gmail.com> wrote:
> Well in the rest of the code you're doing exactly that. You are not
> binding your role player to the typed local. You can't Java won't let
> you because the role player is not of that type. You assign an object
> that has a reference to the role player.

You mean you don't like this:

Plane aPlane = myCart assign Plane;

Because you would rather have this:

myCart assign Plane;

Well, then you have a problem, because often, the name will be wrong.
You'll write code like this:

myCart.fly(); // surprise! I didnt know carts could fly

Sure, sometimes you can get away with it, if the name is alright in
the first place. Let's say you were a millionaire football player and
had a garage full of carts, into which you could inject motors, and
you liked naming your cars after the ladies in your life:

jessie = getCartOutOfGarage();
sarah = getCartOutOfGarage();
mary = getCartOutOfGarage();

jessie assign Plane;
sarah assign Plane;
mary assign Car;

mary.ride();

I am simply not convinced that it really makes such a huge difference
to the code that it means I cannot do DCI if I have to do such type
declarations like I do in Java. Are you really saying that in order
to gain DCI certification, languages must not be allowed to require
type declaration unless it is absolutely necessary?


> Depending on how you write. Code
> it's entirely possible to write a compiler that can figure out the
> type in most cases and let you specify the type if it can't

Exactly, so there will be times when type declarations might be
required. Does that mean that a language requiring them (whether its
always, or sometimes) does not support DCI? I don't think so at all.

Ant Kutschera

unread,
Sep 24, 2011, 5:39:36 PM9/24/11
to dci-evolution
On Sep 24, 9:06 pm, rune funch <funchsolt...@gmail.com> wrote:
> What if the role didn't have a type. What if the name of the role and
> role methods was all there was to it?
>
> role SourceAccount{
>    requires void decreaseBalance(decimal amount);
>    requires void log(string message);
>
>    transaction void transfer(decimal amount){
>           SourceAccount.decreaseBalance(amount);
>           SourceAccount.log("decreased balance with " + amount);
>           DestinationAccount.increaseBalance(amount);
>     }
>
> }
>
> The role has no type. Any type that has the to methods defined in the
> require clauses can be used as role player and intellisense is able to
> tell you which members are available on the role and the role player.

It's not the role implementation that we are talking about here. It
is how you assign the role to an object, and whether you need to
create a second line of code, so you end up with two variable names
for the same object.

Thinking about it, OT/J doesn't have this problem, because it casts
the role as the object enters the context. In plain Java, I could do
almost the same thing:

public void transfer(Account accountToBeSource, Account
accountToBeDestination, Decimal amountToTransfer){
sourceAccount = assign(accountToBeSource).role(Source.class);
destinationAccount =
assign(accountToBeDestination).role(Destination.class);
}

Alright, I do have to find a name for the parameter, but does that
really ruin the code and make it non-DCI? Come on... be honest.

(note I have not type declaration here, because the sourceAccount and
destinationAccount are fields in the context, so the type declaration
occurs elsewhere - does that help you?)


> The role method is marked as transaction which goes to the discussion
> about removing tech stuff from the UC code

Exactly as we do in Java with @annotations. Probably C# has something
similar?

rune funch

unread,
Sep 24, 2011, 8:18:19 PM9/24/11
to dci-ev...@googlegroups.com
Den 24/09/2011 kl. 23.39 skrev Ant Kutschera <ant.ku...@gmail.com>:

> On Sep 24, 9:06 pm, rune funch <funchsolt...@gmail.com> wrote:
>> What if the role didn't have a type. What if the name of the role and
>> role methods was all there was to it?
>>
>> role SourceAccount{
>> requires void decreaseBalance(decimal amount);
>> requires void log(string message);
>>
>> transaction void transfer(decimal amount){
>> SourceAccount.decreaseBalance(amount);
>> SourceAccount.log("decreased balance with " + amount);
>> DestinationAccount.increaseBalance(amount);
>> }
>>
>> }
>>
>> The role has no type. Any type that has the to methods defined in the
>> require clauses can be used as role player and intellisense is able to
>> tell you which members are available on the role and the

>> It is how you assign the role to an object.
I might be the confused one here but I don't assign a role to an
object I bind and object to a role. All the code you wrote in your
mail, I thought that was about binding an object to a role

-Rune

James O. Coplien

unread,
Sep 24, 2011, 8:49:23 PM9/24/11
to dci-ev...@googlegroups.com
On Sep 24, 2011, at 1:10 , Ant Kutschera wrote:

> On Sep 24, 3:26 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:
>> One sign of a dysfunctional language is that you need to know the class of an object to be able to talk to it.
>
> Here is a Javascript object which I once created in a UI. Please name at least one method you can call on it:
>
> viewModel

That is not an object. That is potentially an identifier.


>> One common analog is that you can't talk to an object unless you created it.
>
> That makes no sense - what languages do that?!

Just about all of them. To be able to operate on an object you either have to have created it or received a token to the object from the one one who did create it. DCI is different, in that I can describe the operations on objects in terms of operations of roles. Those operations, and their mutual invocations, have nothing to do with the class of the created object.

So it does make sense.


>> That amounts to prematurely binding the role to the class. It's not DCI — DCI set out explicitly to solve this problem.
>
> What amounts to prematurely binding the role to the class?

Inheritance would be one way of prematurely binding roles to classes, because it depends on the compile-time type system. That is thinking in classes rather than thinking in objects, as is most thinking in terms of compile-time type checking.


> I don't understand.

I know. This is hard. But it's fundamental to what differentiates DCI from class-oriented programming, a.k.a. Restricted OO.

> The only time I ever use a type declaration for a role is
> at the point I am assigning an object a role, or thereafter.

I said nothing about type declarations for roles. My comment was about classes.

> Cheers,
> Ant

James O. Coplien

unread,
Sep 24, 2011, 9:03:06 PM9/24/11
to dci-ev...@googlegroups.com
I intuit either that there are too many misconceptions about DCI, or my total misunderstanding of your point, for me to succinctly clarify the misunderstanding with a few corrections. Perhaps the dialog has finally come to a DCI fundamental that you haven't had to face before.

Rune, maybe you can help, as you seem to be able to cut to the quick with your comments.


On Sep 24, 2011, at 1:35 , Ant Kutschera wrote:

> On Sep 24, 3:31 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:
>> Right — the compile-time type is that of the role, not of the object. But that's a gloss that isn't central to DCI.
>>
>> There has been much talk on the object-composition list of strongly typed or statically typed languages, and the relationship of that typing to DCI. I just don't get it.
>
> Me neither! From my perspective, this all started a few weeks ago, when you challenged us to show how wrappers could be used to implement DCI solution like your Ruby solution for Dijkstra's Algorithm.
>
> I presented a solution, and listed what I had to do in order to make it work [1]. There were a number of things which were unsatisfactory in the wrapper solution.

Yes, that's right.

> You criticised the wrapper solution [2] & [3]. Your criticisms partly seemed to relate to the use of a merged-interface.

Yes.


> I wasn't sure if you were saying the choice of interface name (Mega) was bad, or that having to declare the type was bad? Perhaps you could answer that directly, to clear this up for me?

Let's start with the name. Think of a good name. What would you have named it, given another chance? Much of DCI is about supporting readable code. By that, I don't mean indentation, but semantics and hermeneutics. Your code fails at the hermeneutic level because of the limitations of the technology you chose.


> If you were criticising the name, then what I have posted above at dci-evolution today, or what I posted at [4] should clear that up.


> Today, with what I quoted just above, you seem to be saying you don't care if one has to delcare the type?

The type of what?

> Then I ask you to read the code I posted at [4], using a different name for the merged interface, and
> highlight the exact lines which disturb you so much,

"Lines"? It isn't about individual lines. It's about a mental model.


> because when I compare that code, and your ruby code, I see almost exactly the same thing. Which means wrappers are a suitable way to implement DCI!

No, the last statement is too much of a leap: that one condition is necessary but certainly not sufficient.


>> I have often suggested to Trygve that we need some good type theory research behind DCI. That has very little to do with compile-time type checking, however. As has always been known by great object-oriented programmers, compile-time typing's software engineering advantages are often offset by how it harms expressiveness. I think DCI makes that explicit for those who are using it in an informed way.
>
> Oh... and now you're again saying that you don't like type
> declarations. Now I don't get it :-/

Did I say that? I don't remember saying that. And I can see that you don't get it.

This discussion depends on issues far more subtle than the arguments address here. That is why I am at a loss as how to respond. Addressing the questions on the table here doesn't go to the core issues of DCI. I don't think this is the right level of discussion to be having. I think I can show, at a lower level of discourse, why these issues are problematic, but I am concerned that it would be talking at cross-purposes to your line of argumentation.

As I have pleaded before, the only concrete arguments that can be persuasive in the end must be in program code. I am not eager to tool up for any Java environment on my machine as I want to keep it as free from any Java code as possible. At such time as I have the funds and time available to buy a machine and start a research program on why these solutions don't work, I'll announce it. In the mean time it's important that the arguments here proceed with more academic rigour than they have so far. So if you want to demonstrate that wrapper solutions work, convince me with a proof using retract theory.

James O. Coplien

unread,
Sep 24, 2011, 9:07:23 PM9/24/11
to dci-ev...@googlegroups.com

On Sep 24, 2011, at 1:49 , rune funch wrote:

>> If I were to write code like this, *it would surprise the reader*:
>>
>> public void doSomething(var myCar){
>> myCar.fly(); //cars can't fly!! surprised!
>> }
>>
> I agree. You've chosen a very misleading name for something that flies :)

Yes, that's right. I find Ant's argument in this case to be specious. I can just as easily say:

Airplane *chevrolet = new Boeing747;
chevrolet.fly(); // car's can't fly! suprised!

That is, the arguments I've seen here are not at the level of computational semantics but of syntax. While DCI supports a good syntax, it does so at the level of computational semantics — not just syntax for its own sake. There can be a link between a name and its semantic in DCI that is difficult or impossible in Restricted OO. If you try to simulate it in Restricted OO you end up with names like "Mega."

There is a rich compile-time type model, and richer run-time type model, behind these semantics. With regard to DCI, that is where the interesting arguments lie.

The above argument is not one of them.

Ant Kutschera

unread,
Sep 25, 2011, 4:00:06 AM9/25/11
to dci-evolution
On Sep 25, 2:18 am, rune funch <funchsolt...@gmail.com> wrote:
> I might be the confused one here but I don't assign a role to an
> object I bind and object to a role. All the code you wrote in your
> mail, I thought that was about binding an object to a role

What do you mean by binding as opposed to assigning?

Is this what you mean by binding:

object.extend(Role);

and this what you mean by assigning:

newVariableName = object assign Role;

Ant Kutschera

unread,
Sep 25, 2011, 4:47:44 AM9/25/11
to dci-evolution
On Sep 25, 2:49 am, "James O. Coplien" <jcopl...@gmail.com> wrote:
> >    viewModel
>
> That is not an object. That is potentially an identifier.

OK I entirely agree. So I in my role as a programmer I want to use
that identifier in my code - where do I go look to see what methods I
can call? What I do today in OO is go look at it's class, and perhaps
super classes.

But if I am using DCI, I go look at the roles which it is playing, as
well as the class of the plain object.

Maybe I am kidding myself, but I seem to be able to do this in Java,
which means Java is not a dysfunctional language.

> >> One common analog is that you can't talk to an object unless you created it.
>
> > That makes no sense - what languages do that?!
>
> Just about all of them. To be able to operate on an object you either have to have created it or received a token to the object from the one one who did create it. DCI is different, in that I can describe the operations on objects in terms of operations of roles. Those operations, and their mutual invocations, have nothing to do with the class of the created object.

Yes, the operations you find on an object playing a role do not come
from the class of the object, but from the class AND the roles it is
playing. I can do that in Java too.

> >> That amounts to prematurely binding the role to the class. It's not DCI — DCI set out explicitly to solve this problem.
>
> > What amounts to prematurely binding the role to the class?
>
> Inheritance would be one way of prematurely binding roles to classes, because it depends on the compile-time type system. That is thinking in classes rather than thinking in objects, as is most thinking in terms of compile-time type checking.

*most* is the important word here. In the wrapper solution I posted,
I do not prematurely bind roles. The type declarations used in the
compile-time type checking are also not premature.

> > The only time I ever use a type declaration for a role is
> > at the point I am assigning an object a role, or thereafter.
>
> I said nothing about type declarations for roles. My comment was about classes.

And so not relevant to any code I have posted.

rune funch

unread,
Sep 25, 2011, 4:50:57 AM9/25/11
to dci-ev...@googlegroups.com

The difference I was pointing out was not about assigning/binding as
much as about the direction but now that you point it out I find I
don't like assigning. To me assigning is the operation of assigning a
value to a storage location not attaching (aka binding) some value to
another value. So rephrasing what you said "binding the role to the
object" I think it turns things upside down. You should bind the
object to the role. The object is the one restricted to play one or
more specific roles at a given time in a given context. The role
doesn't even need to know of the object.

rune funch

unread,
Sep 25, 2011, 5:10:06 AM9/25/11
to dci-ev...@googlegroups.com
A little kind reminder. This list is about evolving DCI not how can I
come closest in my language of choice.

Den 24/09/2011 kl. 23.27 skrev Ant Kutschera <ant.ku...@gmail.com>:

> On Sep 24, 8:49 pm, rune funch <funchsolt...@gmail.com> wrote:
>> Well in the rest of the code you're doing exactly that. You are not
>> binding your role player to the typed local. You can't Java won't let
>> you because the role player is not of that type. You assign an object
>> that has a reference to the role player.
>
> You mean you don't like this:
>
> Plane aPlane = myCart assign Plane;
>
> Because you would rather have this:
>
> myCart assign Plane;
>
> Well, then you have a problem, because often, the name will be wrong.
> You'll write code like this:
>
> myCart.fly(); // surprise! I didnt know carts could fly

Why on earth would you call the role myCart if it's a plane? Looks
like you're mixing up a name that refers to the data outside the plane
context and the role name. The former is not valid inside the context.

> I am simply not convinced that it really makes such a huge difference
> to the code that it means I cannot do DCI if I have to do such type
> declarations like I do in Java.

I'm not talking about declarations. I'm saying I think it makes a l
LOT of a difference if you need to think of role players in respect to
types. To me it seems as if you are thinking in terms of data types
(cart) and role types (plane) I don't believe that to be DCI. We have
classifications of data in what-the-system is. Types are good for
that. We have a different kind of classification in
what-the-system-does.

Limiting this classification to what can be done with a type system
that was created to support the former classification just seem
unfortunate. If all you have is a hammer, well that doesn't make
everything a nail

> Are you really saying that in order
> to gain DCI certification, languages must not be allowed to require
> type declaration unless it is absolutely necessary?

Nope I'm saying this list is not about language but about DCI and no
language was build to support DCI so if we constrain the discussion to
a language discussion we are unnecessarily constraining the
discussion.


>
>> Depending on how you write. Code
>> it's entirely possible to write a compiler that can figure out the
>> type in most cases and let you specify the type if it can't
>
> Exactly, so there will be times when type declarations might be
> required.

Yes data.


> Does that mean that a language requiring them (whether its
> always, or sometimes) does not support DCI? I don't think so at all.

Yes that's what I'm saying the current classification is
"pre-renesance" it classifies objects as slaves/peasants/nobles which
is exactly what we need for data and is ill-suited (read can't) to
classify based on capabilities.

-Rune

Ant Kutschera

unread,
Sep 25, 2011, 5:18:28 AM9/25/11
to dci-evolution
On Sep 25, 3:03 am, "James O. Coplien" <jcopl...@gmail.com> wrote:
> > I wasn't sure if you were saying the choice of interface name (Mega) was bad, or that having to declare the type was bad?  Perhaps you could answer that directly, to clear this up for me?
>
> Let's start with the name. Think of a good name. What would you have named it, given another chance? Much of DCI is about supporting readable code. By that, I don't mean indentation, but semantics and hermeneutics. Your code fails at the hermeneutic level because of the limitations of the technology you chose.

I gave myself another chance, in that I posted the code again [4], and
replaced the name Mega with "Node" (albeit a different namespace,
which is basically what qi4J does [5]).

> This discussion depends on issues far more subtle than the arguments address here.

Yes, I see that we (I or you or many of us?) are making a mountain out
of a mole hill. It is a shame that forums are such a poor
communication mechanism.


[4]http://groups.google.com/group/object-composition/msg/
aa5bfc898904410e
[5] http://groups.google.com/group/object-composition/msg/7d7db80921de8694
- 3rd or 4th paragraph from the bottom

rune funch

unread,
Sep 25, 2011, 5:19:39 AM9/25/11
to dci-ev...@googlegroups.com
Den 25/09/2011 kl. 10.47 skrev Ant Kutschera <ant.ku...@gmail.com>:
> Yes, the operations you find on an object playing a role do not come
> from the class of the object, but from the class AND the roles it is
> playing. I can do that in Java too.
Interesting can you show how you've gotten method injection to work in
Java? Or did you mean one of the two below

• My wrapper object is of a type that has the methods from the role
and from the wrapped object
• In the definition of my role type I can find the role methods and
on the type of my data I can find the methods of the data class.

I wish we could discus DCI and not how various language build for
restrictedOO suck at it. We would discus how cars are worthless as the
foundation for a plain if this group was about inventing the airplane.

Ant Kutschera

unread,
Sep 25, 2011, 6:07:03 AM9/25/11
to dci-evolution
On Sep 25, 10:50 am, rune funch <funchsolt...@gmail.com> wrote:
> The difference I was pointing out was not about assigning/binding as
> much as about the direction but now that you point it out I find I
> don't like assigning. To me assigning is the operation of assigning a
> value to a storage location not attaching (aka binding) some value to
> another value. So rephrasing what you said "binding the role to the
> object" I think it turns things upside down. You should bind the
> object to the role. The object is the one restricted to play one or
> more specific roles at a given time in a given context. The role
> doesn't even need to know of the object.

The tricky part of binding is to have the right name on the object,
before you bind a role.

As an example:

basket = ... //a plain object with data like a list of products
basket.extend(Printer);
basket.print(); //I personally don't like that. during analysis
and design, and in the mental model, it is not the basket which
prints, but the printer

"assignment" as we have called it above solves that problem (if you
have the problem, like I do), because it forces you to start using the
role name, rather than the object name. This seems to tie in nicely
with collaborations and UML, where within a collaboration you use role
names.

In fact, isn't a methodless role, the variable name "printer", in the
following role assignment:

basket = //a plain object with data like a list of products
printer = assign(Printer).to(basket);
printer.print();

If we don't use "assignment" and just use "binding", then we don't
have methodless roles anymore...

rune funch

unread,
Sep 25, 2011, 6:20:17 AM9/25/11
to dci-ev...@googlegroups.com
Den 25/09/2011 kl. 12.07 skrev Ant Kutschera <ant.ku...@gmail.com>:

> On Sep 25, 10:50 am, rune funch <funchsolt...@gmail.com> wrote:
>> The difference I was pointing out was not about assigning/binding as
>> much as about the direction but now that you point it out I find I
>> don't like assigning. To me assigning is the operation of assigning a
>> value to a storage location not attaching (aka binding) some value to
>> another value. So rephrasing what you said "binding the role to the
>> object" I think it turns things upside down. You should bind the
>> object to the role. The object is the one restricted to play one or
>> more specific roles at a given time in a given context. The role
>> doesn't even need to know of the object.
>
> The tricky part of binding is to have the right name on the object,
> before you bind a role.

An object doesn't have a name. What do you mean?

>
> As an example:
>
> basket = ... //a plain object with data like a list of products
> basket.extend(Printer);
> basket.print(); //I personally don't like that. during analysis
> and design, and in the mental model, it is not the basket which
> prints, but the printer

I can't see how this relates to the discussion.
You either have a very bad name for your role (basket seems very odd
if the role is printer) or you are accessing an identifier that
shouldn't be available internally in you context. Binding is a
responsibility of the context so what is "basket" doing there? I'm
very confused about the code above. It look's like code from outside
the context based on the basket identifier and from inside because you
bind.

>
> "assignment" as we have called it above solves that problem (if you
> have the problem, like I do), because it forces you to start using the
> role name,

No DCI force you to use the role name in the context that's the only
valid identifier for the RolePlayer


> If we don't use "assignment" and just use "binding", then we don't
> have methodless roles anymore...

The term was bind when I first encountered DCI and we indeed had
methodless roles at that time.

Ant Kutschera

unread,
Sep 25, 2011, 6:26:23 AM9/25/11
to dci-evolution
On Sep 25, 11:10 am, rune funch <funchsolt...@gmail.com> wrote:
> A little kind reminder. This list is about evolving DCI not how can I
> come closest in my language of choice.

It might at times sound like I am trying to force you all to believe
that Java is 100% DCI certifiable, but I know it is not. But I do
find it useful to look at where languages fail to be DCI certifiable,
in order to see how languages must evolve, or how new languages must
be written, in order to be DCI conform.

I realise that just like there is no OO certification for languages,
there will also never be a DCI certification :-)

> Den 24/09/2011 kl. 23.27 skrev Ant Kutschera <ant.kutsch...@gmail.com>:
> Why on earth would you call the role myCart if it's a plane? Looks
> like you're mixing up a name that refers to the data outside the plane
> context and the role name. The former is not valid inside the context.

I haven't called any role "myCart". Where did I do that?

> > I am simply not convinced that it really makes such a huge difference
> > to the code that it means I cannot do DCI if I have to do such type
> > declarations like I do in Java.
>
> I'm not talking about declarations. I'm saying I think it makes a l
> LOT of a difference if you need to think of role players in respect to
> types. To me it seems as if you are thinking in terms of data types
> (cart) and role types (plane) I don't believe that to be DCI. We have
> classifications of data in what-the-system is. Types are good for
> that. We have a different kind of classification in
> what-the-system-does.

Yes, I entirely agree - they are different kinds of classification.
But classifications, nonetheless - that's why I replied to Cevat in
the first place :-)

> Limiting this classification to what can be done with a type system
> that was created to support the former classification just seem
> unfortunate. If all you have is a hammer, well that doesn't make
> everything a nail

When I replied to Cevat, I had no language in mind at all. I was
simply saying that roles are a type of classification which means DCI
is also about classification.

> > Does that mean that a language requiring them (whether its
> > always, or sometimes) does not support DCI?  I don't think so at all.
>
> Yes that's what I'm saying the current classification is
> "pre-renesance" it classifies objects as slaves/peasants/nobles which
> is exactly what we need for data and is ill-suited (read can't) to
> classify based on capabilities.

OK, so there is an important point here: while objects and roles are
classifications, they are very different kinds of classification. For
me, that statement is a keeper.

rune funch

unread,
Sep 25, 2011, 6:37:18 AM9/25/11
to dci-ev...@googlegroups.com
Mvh
Rune

Den 25/09/2011 kl. 12.26 skrev Ant Kutschera <ant.ku...@gmail.com>:
> I haven't called any role "myCart". Where did I do that?

myCart.fly(). If myCart is not the role then fly() (a role method as I
read your code) is out of scope.

>>> Does that mean that a language requiring them (whether its
>>> always, or sometimes) does not support DCI? I don't think so at all.
>>
>> Yes that's what I'm saying the current classification is
>> "pre-renesance" it classifies objects as slaves/peasants/nobles which
>> is exactly what we need for data and is ill-suited (read can't) to
>> classify based on capabilities.
>
> OK, so there is an important point here: while objects and roles are
> classifications, they are very different kinds of classification. For
> me, that statement is a keeper.

I'm sure you meant "while _types_ and roles are classifications"

Ant Kutschera

unread,
Sep 25, 2011, 6:49:55 AM9/25/11
to dci-evolution
On Sep 25, 12:20 pm, rune funch <funchsolt...@gmail.com> wrote:
> Den 25/09/2011 kl. 12.07 skrev Ant Kutschera <ant.kutsch...@gmail.com>:
> > The tricky part of binding is to have the right name on the object,
> > before you bind a role.
>
> An object doesn't have a name. What do you mean?

Oops, I mean:

"The tricky part of binding is to have the right name *for* the
object, before you bind a role

> > As an example:
>
> >    basket = ... //a plain object with data like a list of products
> >    basket.extend(Printer);
> >    basket.print(); //I personally don't like that.  during analysis
> > and design, and in the mental model, it is not the basket which
> > prints, but the printer
>
> I can't see how this relates to the discussion.
> You either have a very bad name for your role (basket seems very odd
> if the role is printer) or you are accessing an identifier that
> shouldn't be available internally in you context. Binding is a
> responsibility of the context so what is "basket" doing there? I'm
> very confused about the code above. It look's like code from outside
> the context based on the basket identifier and from inside because you
> bind.

That code is code you find inside a context.

The first line:

> > basket = ... //a plain object with data like a list of products

That is my me saying that my context knows about a plain object and
hasn't yet cast any roles. Typically the context is given this
object, or the context looks it up based on a given ID. Then:

> > basket.extend(Printer);

That is the context binding the role. Finally:

> > basket.print();

That is "starting the interaction", or a use case step. It is the
context using the object which plays a role.

Is that clearer?

Ant Kutschera

unread,
Sep 25, 2011, 6:53:24 AM9/25/11
to dci-evolution
On Sep 25, 12:37 pm, rune funch <funchsolt...@gmail.com> wrote:
> I'm sure you meant "while _types_ and roles are classifications"

Yes thanks!

Ant Kutschera

unread,
Sep 25, 2011, 7:20:12 AM9/25/11
to dci-evolution
On Sep 25, 12:37 pm, rune funch <funchsolt...@gmail.com> wrote:
> myCart.fly(). If myCart is not the role then fly() (a role method as I
> read your code) is out of scope.

Aha, well it depends on how you implement the context, and your
language of choice.

Take James' example of the shortest path context from
http://groups.google.com/group/object-composition/msg/32ab037625b9acb2.
In the initialise method of that context he has:

rebind(origin_node, geometries)

and then a few lines later:

origin_node.set_tentative_distance_to(0)

That method is a role method. So it is indeed *not* out of scope.


OT/J on the other hand does the binding of roles as the object is
passed into the context, under the hood. So the original object is
out of scope, as you wrote.

James O. Coplien

unread,
Sep 25, 2011, 9:25:57 AM9/25/11
to dci-ev...@googlegroups.com
In DCI, a set of objects are associated with a set of roles. Except for kicking things off, all use case operations take place on roles.

The code below looks like the decorator pattern rather than DCI.

Having "the right name for the object" is kind of imprecise. It is neither sufficient nor necessary. From the Scala example in the Lean Architecture book,

val source = new SavingsAccount with TransferMoneySource
    val sink = new CheckingAccount with TransferMoneySink

Notice that the roles here are the only names for their associated objects. There is no need for any other name. There is no need for "the right name on the object, before you bind the role." I can't see why it's unnecessary: only that it might be convenient in the event that one is binding one object to several roles.

Can anyone explain any other fundamental reason why I need a name for the object between the instantiation of the data class and its association with a role? Is there some fundamental problem or lapse in clarity of the above Scala code? I guess I can see the need in primitive languages lacking garbage collection, but that's not germane to DCI.

To focus on the basket name in one's design seems like a slope towards class-oriented thinking.

James O. Coplien

unread,
Sep 25, 2011, 9:38:45 AM9/25/11
to dci-ev...@googlegroups.com
On Sep 25, 2011, at 11:18 , Ant Kutschera wrote:

On Sep 25, 3:03 am, "James O. Coplien" <jcopl...@gmail.com> wrote:
I wasn't sure if you were saying the choice of interface name (Mega) was bad, or that having to declare the type was bad?  Perhaps you could answer that directly, to clear this up for me?

Let's start with the name. Think of a good name. What would you have named it, given another chance? Much of DCI is about supporting readable code. By that, I don't mean indentation, but semantics and hermeneutics. Your code fails at the hermeneutic level because of the limitations of the technology you chose.

I gave myself another chance, in that I posted the code again [4], and
replaced the name Mega with "Node" (albeit a different namespace,
which is basically what qi4J does [5]).

I posted the original Manhattan Dijkstra code as an example of an implementation of an explicit, specific mental model where the primary roles are the current intersection, the West neighbor, and the South neighbor. There is no role called "Node." "Node," in fact, is a generic term reminiscent of the data architecture rather than the role architecture. It has no sense of action with respect to the algorithm, whereas the Neighbors correspond to explicit actions between objects in the given algorithm.

At the very least, introducing a Node role implements a different mental model. The original challenge, I think, was to express the original mental model in several different languages for sake of comparison. Neither the Mega implementation nor the Node implementation do that. Renaming Mega to Node is, I think, only putting lipstick on a pig.

If it's a different mental model then I'd like to see what the code looks like for the same mental model. But we seem to have been struggling in that direction for quite a while without success. I don't think it can be done in a way that both uses this technology and meets the design goals of DCI.

There is something profound lurking here:

Reflecting on this example produced a possible new insight for me. Note that "Node" as a name connotes no sense of relationship. It is about a thing rather than what happens between things. West Neighbor and South Neighbor, on the other hand, are about relationships. You can't define a Neighbor except in the Context of some other object that anchors that identity. The same happens to be true for SourceAccount and DestinationAccount: they are defined in terms of each other.

Roles in normal English seem to also have this property. The Father role is defined in terms of the Child role. The Waiter role is defined in terms of the Clients and the Kitchen. The Chef role is defined in terms of kitchen gadgets and so forth. A Node just is: it doesn't do. This, perhaps not coincidentally, takes us straight into the what-the-system-is versus what-the-system-does dichotomy. Data classes are about what the system is, and the important names there are class names rather than handles. Roles are about what-the-system-does, and seem to have this sense of action, relationship, and in-between-ness. Node and Mega seem to be in the data space: as mentioned in a previous mail, they are accidents of the implementation that are superfluous for the fundamental communication of the code semantics. They're certainly not roles.

Is this in-between-ness an essential, fundamental property of good roles?

James O. Coplien

unread,
Sep 25, 2011, 9:40:08 AM9/25/11
to dci-ev...@googlegroups.com

On Sep 25, 2011, at 12:20 , rune funch wrote:

> An object doesn't have a name. What do you mean?


Technically, it does: its address. But that isn't germane to DCI.

In the bigger picture, this is a different way of saying what I said in my longer mail. Interesting that we both came to the same conclusion from different angles.

James O. Coplien

unread,
Sep 25, 2011, 9:42:46 AM9/25/11
to dci-ev...@googlegroups.com

On Sep 25, 2011, at 12:26 , Ant Kutschera wrote:

> It might at times sound like I am trying to force you all to believe
> that Java is 100% DCI certifiable, but I know it is not. But I do
> find it useful to look at where languages fail to be DCI certifiable,
> in order to see how languages must evolve, or how new languages must
> be written, in order to be DCI conform.

Regarding Java, I think we have a pretty clear picture of that in Qi4j.

If you are serious about this paragraph, let me challenge you to define a longitudinal research program that measured indicators such as coupling and cohesion in your implementation, as compared with the Qi4j results. Such analyses skirt syntactic details. That would make a good result suitable for peer review outside this community as well.

rune funch

unread,
Sep 25, 2011, 9:46:30 AM9/25/11
to dci-ev...@googlegroups.com
Den 25/09/2011 kl. 12.07 skrev Ant Kutschera <ant.ku...@gmail.com>:

> In fact, isn't a methodless role, the variable name "printer", in the
> following role assignment:

I believe this to be a statement of thoughts constraint by how you are
trying to do DCI in java using wrappers forcing you to creat a new
object instead of simply binding one to a role. Who says that there's
a role variable at all. A variable is a named storage location and a
role is an identifier. If the identifier is an alias for the name of a
variable why would you need another variable?
That of course ties in with the discussion of identity and wrappers
just as the classification discussion does

James O. Coplien

unread,
Sep 25, 2011, 9:48:08 AM9/25/11
to dci-ev...@googlegroups.com
On Sep 25, 2011, at 10:47 , Ant Kutschera wrote:

> OK I entirely agree. So I in my role as a programmer I want to use
> that identifier in my code - where do I go look to see what methods I
> can call? What I do today in OO is go look at it's class, and perhaps
> super classes.
>
> But if I am using DCI, I go look at the roles which it is playing, as
> well as the class of the plain object.

I don't know how this paragraph relates to the next one.

> Maybe I am kidding myself, but I seem to be able to do this in Java,
> which means Java is not a dysfunctional language.

Java does well what Java does well. It is Turing complete. Dysfunctional is relative to a context, comparing the other languages to which it is compared and the purpose to which it is applied.

DCI entails more than the ability of objects to play roles.

I have yet to see evidence that it functionally supports DCI, while most other contemporary languages support it in large degree

Ant Kutschera

unread,
Sep 25, 2011, 10:08:41 AM9/25/11
to dci-evolution
On Sep 25, 3:25 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:

>         val source = new SavingsAccount with TransferMoneySource

> To focus on the basket name in one's design seems like a slope towards class-oriented thinking.

"Basket" has nothing to do with class-oriented thinking.

The basket is an object in my mental model, which contains, amongst
other things, a list of products, which have been scanned by the sales
person. The sale isn't complete, but the basket holds those
products. Its just data.

Long before I considered code or even classes, I considered how I
would print a receipt, and the obvious object for doing that was a
printer.

The printer doesnt do much else than print. To do the printing, it
uses data like that held in the basket, so that it can prepare lines
of text which it can then send to a hardware interface to physically
print that text to paper.

So during analysis and design, I needed to determine where that
printing algorithm which prepares the lines of text belongs.

I decided to stick it in a role called "Printer", which the basket can
play. I did it that way, because I searched the use cases for actors
and then searched the collaboration-use diagrams for hints as to which
roles I had in my mental model. Printer was indeed a role. Or do you
disagree?

So, long before any context starts, my system contains a basket - its
purely a data object.

It is passed to the "complete sale context" which is the collaboration
used to finish a sale after a sales person completes scanning products
and is ready to take money from the customer.

One of the first things the context does is bind roles: it adds
printer behaviour (ie. the ability to prepare lines of text to send to
a low level API which prints lines to paper, as well as the ability to
call that low level API). It adds that behaviour to the basket.

Now, I decided that within the context, I would call that object a
printer, because it would be used to do printing. That isn't wrong is
it?

The exact same object was also given the role "sales log" in order for
it to have the ability to create audit logs. Again, instead of
referring to that object as "basket" I prefer to refer to it as
"salesLog".

So, the context is passed the basket in it's constructor. Thereafter,
until the context completes, I never ever use the name "basket" to
refer to that object.

Your Scala example is flawed, because you are creating the object at
the same time as you assign a role to it. In my Till example, the
basket lives long before any contexts need to use it. It is part of
my model which gets instantiated as soon as the system is started,
long before any use cases are run.

Now note: I have an object playing several roles. But each role is
thought of seperately, unlike the Dijkstra example. So each role is
referred to by its own name.


Perhaps my design is wrong - but since no one here suggested any roles
to me in that thread, I am hardly to blame if I did it wrong ;-)

Ant Kutschera

unread,
Sep 25, 2011, 10:17:28 AM9/25/11
to dci-evolution
On Sep 25, 3:38 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:
> Renaming Mega to Node is, I think, only putting lipstick on a pig.

I hope you aren't suggesting Miss Piggy is ugly... she won't like
that!

More seriously, I see what you mean - that merging a set of roles into
an interface, because the language requires it, is ugly, because you
need to find a name for that merged interface, and it is not something
that is found in the mental model.

In my usual "fire from the hip" style, I shall prematurely conclude
that DCI does not like languages which require unnecessary type
declarations. And in order that tooling support DCI languages to the
fullest extent, compilers written for languages that support DCI must
do their very best, like F# does, to help the programmer be
efficient. That too is a keeper for me - two in one day - how
productive!


> Roles in normal English seem to also have this property. The Father role is defined in terms of the Child role. The Waiter role is defined in terms of the Clients and the Kitchen. The Chef role is defined in terms of kitchen gadgets and so forth. A Node just is: it doesn't do. This, perhaps not coincidentally, takes us straight into the what-the-system-is versus what-the-system-does dichotomy. Data classes are about what the system is, and the important names there are class names rather than handles. Roles are about what-the-system-does, and seem to have this sense of action, relationship, and in-between-ness. Node and Mega seem to be in the data space: as mentioned in a previous mail, they are accidents of the implementation that are superfluous for the fundamental communication of the code semantics. They're certainly not roles.
>
> Is this in-between-ness an essential, fundamental property of good roles?

So, in my Till example, I think this property is missing when I think
of things such as Printer - although I am not sure. What do you think?

rune funch

unread,
Sep 25, 2011, 10:29:30 AM9/25/11
to dci-ev...@googlegroups.com
Den 25/09/2011 kl. 16.17 skrev Ant Kutschera <ant.ku...@gmail.com>:

> So, in my Till example, I think this property is missing when I think
> of things such as Printer - although I am not sure. What do you think?

Ask yourself does my context display the interobject activities? By
making the basket a printer does you show the relation and interaction
between the items bought and the receipt? Or would roles such as line
item and receipt make that more visible within a print context where
each item in the basket is in turn bound to line item?

rune funch

unread,
Sep 25, 2011, 10:32:49 AM9/25/11
to dci-ev...@googlegroups.com
Den 25/09/2011 kl. 15.39 skrev "James O. Coplien" <jcop...@gmail.com>:

> Is this in-between-ness an essential, fundamental property of good roles?

I think you're on to something here. It does conflict with another
Idea I have for a more generalized application of contexts but it
feels as if it's the idea that's unfinished and that I now have an
hint to what's missing

-Rune

James O. Coplien

unread,
Sep 25, 2011, 10:42:45 AM9/25/11
to dci-ev...@googlegroups.com
A little tutorial here. You'll probably have to read this several times and let it soak in to round it out. I'm trying to convey a large number of basic concepts that, if understood, probably could block off blind alleys of discussion, including a few that have occurred here already.

The semantics of assignment in a high-level language are "sticky note" semantics. A "sticky note" has the name of an identifier (sometimes called a "variable") written on it. If we say (in C++):

Object *fred = new Car;

then there is an object sitting in memory, whose name is called fred. The object is *fred. That is, someone has put the fred sticky note on the object. With respect to the programming language the object has no other interesting name. On the other side of the programming language abstraction boundary, the object's name is its address in memory.

I use the term "binding" to designate the putting of a sticky note on an object.

Now if we say:

Object *george = fred;

we have created another sticky note with "george" written on it, and have put it on the same object where we find the fred sticky note. The object now has two names. The object's name is called *fred, but it is also called *george.

Technically, those are only what its name is called. Its name is its address.

Notice, however, that the object does not play two roles.

This is important: note that there is no intrinsic notion of copying — of anything — in high-level language assignment. The compiler is not obliged to take more memory or even generate object code to implement the second line above. It may simply hack the symbol table to make george and fred be synonyms in the same scope. Other manipulations on these identifiers may force the compiler to clone a pointer, but it is not an intrinsic property. C++ makes this explicit in an alternative form of assignment:

Object &ted = *fred;

So now the name of the object (in C++) is ted, but also *fred and also *george. This is not FORTRAN or Pascal. In those languages, assignment means copying. The ideal in an object-oriented language is that there is no implicit copying: if you want to copy an object, you apply the shallow_copy or deep_copy operator to it, and it yields a new object. In FORTRAN, if I say:

        INTEGER A, B
    A = 1

and then say

B = A

there are two objects, one whose name is B and the other whose name is A. (This is additionally confusing in FORTRAN because the literal 1 is a value rather than an object.) Actually, there were two objects before the assignment, though one of them had undefined value.

The sticky note model has interesting implications. Once you take the last sticky note from an object it is no longer reachable by any program code. That means that its memory can be reclaimed. That is often called garbage collection and it, too, is fundamental to the object programming model.

DCI takes this one step further. When it associates a new name with an object, to designate its role, it also injects code into the object to enrich its functionality. The new name is what we call a methodless role — it's just an alias, another name by which the object is called, in the good old object-oriented sense. The code that is injected into the object to enrich its functionality is called a methodful role. It is a trait in Scala, a module in Ruby, a class in C++. That's DCI.

None of these notions map to a Java interface. DCI is an attempt to separate the functionality of an object from its data representation. Java interfaces are an attempt to separate the protocol of an object from the implementation of both its behavior and data. Like other facets of any compile-time type system they fit into DCI only by happenstance.

One can create all kinds of hacks to simulate object semantics with explicit program code. Wrappers are a way to simulate identifier semantics. This is how the handle-body idiom works in C++: we use an object of a wrapper class to simulate the semantics of a true object identifier. Much of the complexity of C++ (its overloading of operators such as operator=, operator*, and operator–>) owes to the need to sustain this level of transparency. It works, but only with incredible discipline.

True object-oriented languages built in this wrapper-ness automatically. In Smalltalk, identifiers and objects are different things. The identifier is only the name by which the object is called: it is not the object. Contrast this with FORTRAN, where an identifier (called a variable) is the name of the object: you cannot separate the name of the object from the object. There is no value of talking about the object apart from its name. (By the way, there is also a way to create aliases in FORTRAN, called the EQUIVALENCE statement, so an object can have many names — but it is one set of static associations.) So Smalltalk treats identifiers like sticky notes, and it knows when the last sticky note becomes unpeeled from the object, and it can reclaim its memory. That happens on the other side of the language abstraction boundary.

DCI is similar, in that it moves the dynamic typing of an object to the other side of the language abstraction boundary and allows one to program in roles and objects rather than classes. Conveniently enough, most languages have just the mechanism that DCI needs: e.g., the extend[s] concept in Ruby and Scala; the indirect template idiom in C++. Languages are less facile in expressing the broader association semantics germane to a context, though Trygve's environment does this handily with a graphical notation. Java does not have these facilities at all, so the complexity of wrappers shows up on this side of the abstraction boundary. You can make it work 90% of the time, just like you can make reference counting in C++ (which requires wrappers) work 90% of the time. But the code is complex, and it has failure modes (for circular references, for example).

The same is likely true for any wrapper solution to DCI. I have conceived of another example that straddles the abstraction boundary in an uncomfortable way that is sure to break wrappers in a hard way, and that's Knuth's buddy system algorithm. I'll work up an example (though I'm sure it's going to be painful in Ruby...)

Good programming practice in DCI provides that one declare suitably named identifiers that communicate the functional intent of an object. In the Dijkstra example, almost every object has three names at some time or another: the current intersection, being a west neighbor, or being a south neighbor. But this is just a gentlemanly agreement written by convention, and is not the focus of DCI. The focus of DCI is that objects are suitably injected with the logic necessary to perform those named roles. The named roles are just convenient ways to express the intent. So if I have a seaplane, I can say:

    seaplane = new Boat
    Airplane extends seaplane // inject Airplane role into the object
    boat = seaplane // create an alias
    boat.sail() // O.K., within DCI, and good coding style
    boat.fly() // O.K., within DCI, questionable coding style

It's important to note that the stylistic questions are a matter of taste and are neither an ipso facto matter of the domain nor of DCI:

    sue = new Female
    Mother extends sue
    jeff = new Male
    Father extends jeff
    joey = new Male
    Child extends joey
    Nurturer extends jeff
    WageEarner extends sue
    jeff.nurture(joey)

is perfectly meaningful and representative of a configuration within the domain, though it violates stereotypes — just as a seaplane violates the stereotype of a boat being able to fly. That is, there is nothing wrong with a boat flying if it has the capability of playing the role. It's a bit unusual, but the world is full of unusual things. It is this unusualness that changes classification from a hierarchy to a DAG. If everything were subject to our expectations, we would need only classes. DCI recognizes that the world is messier than that, so we need roles and role-to-object mappings to capture the complexity.

Lewis Carroll said it well:

    “The name of the song is called`Haddock's Eyes’.”

    “Oh, that's the name of the song, is it?” Alice said, trying to feel interested.

    “No, you don't understand,” the Knight said, looking a little vexed.  “That's what the name is called. The name really is `The Aged, Aged Man.'”

    “Then I ought to have said, 'That's what the song is called'?” Alice corrected herself.

    “No, you oughtn't;  that's quite another thing! The song is called `Ways and Means'; but that's only what it's called, you know!”

    “Well, what is the song, then?” said Alice, who was by this time completely bewildered.

    “I was coming to that,” the Knight said. “The song really is `A-sitting on a Gate'; and the tune's my own invention.''

    “But the tune isn't his own invention,” she said to herself; “it's `I give thee all, I can no more.'”

James O. Coplien

unread,
Sep 25, 2011, 10:46:53 AM9/25/11
to dci-ev...@googlegroups.com

On Sep 25, 2011, at 4:08 , Ant Kutschera wrote:

> "Basket" has nothing to do with class-oriented thinking.
>
> The basket is an object in my mental model, which contains, amongst
> other things, a list of products, which have been scanned by the sales
> person. The sale isn't complete, but the basket holds those
> products. Its just data.

That, by definition, is class-oriented thinking.

Role-oriented thinking is about:

- behavior (not data)
- relationships (not a thing in its own right)

If you have to say "contains" you are thinking data (as you say). Data are represented in classes — NOT in roles.

Your statement clarifies to me, irrefutably, that this reflects what I view as class-oriented thinking.


James O. Coplien

unread,
Sep 25, 2011, 10:50:32 AM9/25/11
to dci-ev...@googlegroups.com

On Sep 25, 2011, at 4:17 , Ant Kutschera wrote:

> So, in my Till example, I think this property is missing when I think
> of things such as Printer - although I am not sure. What do you think?

To me, at least at first blush, a Printer is not a role played by something. If someone says "Printer" to me in conversation I think of a specific object. There are many kinds of Printers in the world, by many manufacturers, that do many things, but those just form a CLASS hierarchy. I usually think of a Printer without thinking of the thing printed.

Objects of that class may play some role, and you have me thinking here, because I have a hard time thinking of any other name of that role other than "Printer." I guess that a Printer as a role prints something that is given to it... But there is some kind of confusion in my mind about this.

Thoughts?

James O. Coplien

unread,
Sep 25, 2011, 10:51:13 AM9/25/11
to dci-ev...@googlegroups.com
I love it when ideas cascade...

Ant Kutschera

unread,
Sep 25, 2011, 1:35:44 PM9/25/11
to dci-evolution
Aha! Yes, when thinking about the *data* in the system, I do think in
terms of classes. But dumb classes. Is that wrong?

When thinking about behaviour and relationships (other than data
relationships), I switch to think in terms of roles.

So you are correct - seeing the word "basket" in a context is wrong.
But like I said, it's only there, so that the context can then cast
the basket into a role player. It's the way the language works -
which I am sure you will say is a sign that the language doesn't
support DCI.

Ant Kutschera

unread,
Sep 25, 2011, 1:52:35 PM9/25/11
to dci-evolution
Yes. I was out swimming and something occurred to me.

In the banking example, SourceAccount and DestinationAccount are
*types* of Account. With "type" I mean that one could imagine
creating a subclass of Account which contains the behaviour needed for
SourceAccount.

In the Dijkstra Algorithm example, an Intersection, Neighbour, etc.
are all *types* of Node.

Even in the front loader example, the FrontLoader is a type of plan,
and the Activity is a type of Task.

So in every case, I could say that there is an "is a" relationship,
between the object and the role.

Let's test that in my Till example: "a printer is a basket"... hmmm...
That sounds as crazy as a box of frogs.

In a way that indicates to me, that I have definitely chosen the wrong
roles. In fact, none of the roles I chose are roles at all, if this
is a good test of a role.

Perhaps my choice of roles comes from my background in SOA? For
example, a PrinterService would definitely be a thing which would
prepare a print. Same goes for a SalesLogService, or
SalesOrderService.

But Rune wrote something enlightening above - that I should consider a
Product (data) as a LineItem - the role would be a LineItem - and
would give the product the ability to create the text that should be
printed. Perhaps "PrintableProduct" might even be a better name?
Regardless, I find this extremely interesting, because I can see how
in OO one would just create a subclass.

I thought DCI was (partly) about separating behaviour from data. I
didn't realise it was about reducing the inheritance hierarchy my
pushing specialised behaviour into roles.

So perhaps my current design for a Till is not DCI at all, because it
has no roles which pass the "is a" test.

Then again, at least it uses objects found in the use case, rather
than specialisations of objects which are not in the mental model...

Thoughts please - I find this really really really interesting!

Cheers,
Ant

rune funch

unread,
Sep 25, 2011, 2:46:37 PM9/25/11
to dci-ev...@googlegroups.com
At a first impression I like the idea of your test. From a didactic
point of view I find it challenging that it's the same test as taught
is common for many when teaching inheritance 101 but that a side I
think you might have found a third keeper of the day. There's
something that feels right. In more generalized algorithms as the
convection model/water wheel I think it's going to be tough however.

Funny that you brought service up. When I wrote the about line items I
had exactly the same thought that basket/printer had a service feel to
it.

-Rune

rune funch

unread,
Sep 25, 2011, 2:50:07 PM9/25/11
to dci-ev...@googlegroups.com
As a further comment "is a" is still class thinking. It does not
ensure that the role is based on behavior.
"Human is a slave" so you are still classifying in only one dimension.

Mvh
Rune

Den 25/09/2011 kl. 19.52 skrev Ant Kutschera <ant.ku...@gmail.com>:

Ant Kutschera

unread,
Sep 25, 2011, 3:12:28 PM9/25/11
to dci-evolution
On Sep 25, 8:46 pm, rune funch <funchsolt...@gmail.com> wrote:
> I think you might have found a third keeper of the day.

The only problem is, I'm supposed to find roles in use cases and / or
collaborations.

It didn't occur to me to have a "line item", so it's not in my mental
model.

In fact, no where in any of my mental model, use cases or
collaborations, do I find any "is a" relationships - there is nothing
which would classically be put into an inheritance tree at all.

So I am back to square one when it comes to identifying roles in the
first place... Bad end to a successful day :-|

Ant Kutschera

unread,
Sep 25, 2011, 3:15:08 PM9/25/11
to dci-evolution
On Sep 25, 4:42 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:
> A little tutorial here. You'll probably have to read this several times and let it soak in to round it out. I'm trying to convey a large number of basic concepts that, if understood, probably could block off blind alleys of discussion, including a few that have occurred here already...

James, I haven't finished reading this yet, I'm going to have the
night off.

But so far, it looks really excellent - it is a very good start to a
low level definition of what languages needs to be capable of, in
order to allow programmers to do DCI implementations. And it's
written to a level which I can understand :-)

Thanks!
Ant

James O. Coplien

unread,
Sep 25, 2011, 3:15:34 PM9/25/11
to dci-ev...@googlegroups.com


Hint: Think of roles in terms of their relationships to other roles and see if that helps. I am getting a hunch that there is something really key to that.

Give it a try after a good night's sleep :-)

Ant Kutschera

unread,
Sep 26, 2011, 3:14:05 AM9/26/11
to dci-evolution
Hi,

@James: you hinted that I should think of roles in terms of their
relationships to other roles. But I am struggling to even identify
the roles to start with...


Here is a conversation I had this morning with a colleague I have
worked with for a long time:

Myself: Let's talk about identifying roles again, because things like
printer and sales log don't pass the "is a" test.

I: OK. Well, Rune had a good idea - he said we should think of
the product, and when it needs specialising, the specialisation could
go into a role.

Myself: Yes indeed. So a Product could play the role "LineItem" which
would have the ability to give us the line of text which needs to be
printed on a receipt. The basket could be a "PrintableBasket" so that
it can provide us with the header and footer which get printed on the
receipt.

I: "LineItem" isn't the best role name. If we go down this
route, we would also need roles for creating the SalesOrder (played by
basket), SalesOrderItem (played by Product) and the SalesLogRecord
(played by product). So what names could we use?

Myself: You just said the role names! "SalesOrder", "SalesOrderItem",
"SalesLogRecord"!

I: No, those are entities. They are dumb data. Think about when
we export the sales log to the back office. We will load a list of
SalesLogRecords from the database - they are our data. The behaviour
will then be loading, formatting and writing them to a place where the
back office can access them. They also have state like "timeOfSale"
and because roles are stateless, they can't be roles. Nice idea, but
doesn't quite work for me.

Myself: Hmmm... Maybe we need to think how other orientations model
stuff. Let's start from the beginning. I have a product, sitting in
a basket. Should the product provide the text which get's put on a
receipt? Or should the printer decide what text it will print, based
on the product's attributes?

I: Well, if you sold different types of product, and one type
needed a simple receipt, but a different type additionally needed a 2D
bar code which served as a voucher in a coffee shop, then you would
use inheritance and polymorphism to handle the problem. So it would
be the product which would provide the text to the printer. The
algorithm you would write to prepare the receipt and send it to the
printer wouldn't care about the details of how each product needed to
be printed.

Myself: That's great - that sounds like the "is a" relationships which
we need to find in order to test our roles.

I: Yes, but let's say we create a role called "PrintableProduct"
which gives us a line of text like this:

The Joys of DCI: 18.99

Then, in a year, the business decides they want products which
include services which you get at a later time, like getting a cup of
coffee from the coffee shop. In RestrictedOO, I would simply have a
subclass of Product called "ProductWithVoucher" which would override
the "getReceiptText" method. How would you do that DCI?

Myself: I would create a role which subclassed the "PrintableProduct"
role.

I: Oh no you wouldn't because you would be relying on
polymorphism, and that leads to surprises and on the object-
composition forum we have explicitly disallowed polymorpism, in a
least roles!

Myself: OK, so I'd create two roles "PrintableProduct" and
"PrintableProductWithVoucher" and I would use an "if" statement.

I: An "if" statement? That would look like Miss Piggy. That is
a classic case where you would use inheritance! Besides, where are
you going to put that "if" statement?

Myself: In the code of course.

I: In what code?

Myself: The code I write you idiot.

I: Aha, but which code that you write? A role? The context?

Myself: Why in the erm... hmmm... let me think. It wouldn't be in
the role called "PrintableProduct". The "if" statement to decide if I
called the "PrintableProduct" or "PrintableProductWithVoucher" would
need to be outside that role. So I guess it would be in a different
role, or in the context... But I'm not sure. I'd have to write some
code and see.

I: OK, let's go do that. But one last question: how does the
"if" statement decide which role to use?

Myself: Oh that's easy. It erm... hmm... It check's the Product's
type (class)? Or it erm... check's a field on the product called
"hasVoucher"?

I: Dude, you just removed Miss Piggy's make up and risked
blinding me because she is so ugly.

Myself: Hey, but you're a SOA guy - what would you do there?

I: I'm pretty sure I'd use polymorphism, as much as I dislike OO.

Myself: Hey, thinking about it, a method like "getReceiptText" is so
simple, why not just add it to the Product class? Then we wouldn't
have these problems.

I: No. Two reasons. First of all, it's only relevant in the
context of printing which is only relevant in the context of
completing a sale. So we don't want to have that in the Product which
might be reviewed in all other possible use-cases because it would
confuse the reader when they are reviewing other use cases where there
is no printing. Second of all, if we don't have this polymorphism
problem in the Product, because we push that method to the data class,
we will just encounter the problem later, when we consider the
basket. Imagine random customers were presented with a coffee voucher
that was printed in the header of the receipt? Basket is a more
complex object than Product, and preparing a receipt for the entire
basket is definitely something that goes in a role inside a context
which knows about printing.

Myself: Wait a second. You might want to print a receipt for a stock
take. Yeah, that's functionality which is used in several contexts!
It's a habit!

I: No, a stock take receipt would look different. We won't model
that as a habit, just to skirt around the issues here.

Myself: OK, let's go write some code and see what happens. Then we
can continue.

Some time later, after myself and I pair programmed some code...

I: OK, that was useful. The place where the ugly "if" statement
goes is in the role played by the basket, say "PrintableBasket". When
it is preparing the entire text for the receipt, it iterates of each
product and casts each one into the role of LineItem.

Myself: Yes, and LineItem isn't just for the receipt text, but would
also provide us with the sales order item, and the sales order records
for that product (product to sales log record is a 1 to 1..n
relationship, because if the product is discounted, you get two
records - the second record is for the discount). So we only need two
roles in total: one for the basket and one for the product.

I: And we found another interesting point. We have behaviour in
objects which are not roles, nor are they contexts.

Myself: Yeah, you mean the "PaymentPartner" which makes the web
service call to the payment partner to get an authorisation ID for
electronic payments, or the "Printer" which makes low level API calls
to the physical printer, or the "SalesOrderDatabase" which is where
the ORM (SQL) is, which writes the "SalesOrder" and "SalesOrderItem"
to the physical database, or the "SalesLog" which is where the ORM is,
which writes the "SalesLogRecords" to the physical database.

I: Yup.

Myself: I have to be blunt. I'm feeling like DCI is falling a part at
the seams a little. It's not like I had originally thought. These
are our problems:

1) We think we found a role called "LineItem", but until
now it was never mentioned in any of the mental models, use cases or
collaborations in the design. Same for "SellableBasket", which is the
role which prepares the entire receipt for the basket, the entire
sales order and all the sales log records.

2) We have a problem if "Product" (ie. the data) is
subclassed to handle a special kind of product, that say includes a
voucher. The problem here is that we would like to create a subclass
of the role "LineItem", but are not allowed to do that. And then we
would have an ugly "if" statement when doing the role casting.

3) We have code relevant to the context, outside of roles,
which we would like to place in objects called "Printer", "SalesLog"
and "SalesOrderDatabase". Is that allowed? We thought all behaviour
went into the context and roles.

I: Don't be so negative! There is definitely something here
worth persuing. I'm thinking it is time to return to dci-evolution,
and see what those clever people think...

Rune Funch Søltoft

unread,
Sep 26, 2011, 3:37:18 AM9/26/11
to dci-ev...@googlegroups.com
Hi Ant,
I must admit I didn't read all the of the transscript but some thing striked me. Where's the behavior? The discussion is focused on entities not their interactions.
To me printing feels like a part of a use case not a use case on it's own right. Is it possible in your system to go back x days later only to print the receipt?

A first remark would be I never said "he said we should think of
the product, and when it needs specialising, the specialisation could
go into a role" specialization and roles are to me ortogonal concepts. That's part of what I took away from our talk on classifications.

A pilot is not a specialization of human. He's no more no less human than you and I and he hasn't got any human capabilities (as in genes) that makes him a special human. He's got behavior that can be utilized when playing a certain role. On top of those skills we can build a role "Pilot".

If you look at what's interacting in your printing case I've already said I see to objects working together. There's the receipt (let's forget about header and footer for now and just assume they are already there) and a line being printed. The interaction between those two can be described as "a line item is printed on receipt". Back in primary I learned a lot of fancy word I could use to classify the parts of a statement. How ever they are all in Danish and I probably forgot half of them any way. I do however have a hunch (brought to life thanks to James yesterday) that if we do a grammatical analyses of the above we realize that the subject of the sentence is "line item" that the object is "receipt" and the main verb is print. I think this is a better "is a" test for interactions.
We have two potential roles "line item" and "receipt" and a name for the interaction "print". That feels right. 

I can now do:
//role method
void print(){
    var lineItemText = lineItem.Name + " " + lineItem. Quantity + " " + lineItem.TotalSum
    recepit. //what ever is needed to print the above text to paper 
}

My first guess would be that the product is playing line item and that the HAL representation of the actual hardware (if that's an object) is playing the receipt

-Rune

2011/9/26 Ant Kutschera <ant.ku...@gmail.com>

Cevat Serkan Balek

unread,
Sep 26, 2011, 10:35:11 AM9/26/11
to dci-ev...@googlegroups.com
Is this in-between-ness an essential, fundamental property of good roles?

I extremely think so :) We are in the inter-space!

It is unnatural to think about the roles alone. Just look at the way how we talk about roles in  even the current definition of FullOO. It is natural to think about them together.

DCI implements system behavior by pulling together the behavior of a system operation into several co-located roles, each representing an object. The programmer can see the roles together and reason about their end-to-end behavior.

If, with Full OO, the programmer observes the system from the space between the objects, there should be at least two objects. Here we have two alternatives:

1. One role alone use the domain objects to accomplish a given rather independent task.
2. Two or more roles interact with each other in a context which are already generated by them.

If, things were always as simple as the first alternative, we were not here to talk about the need for DCI at all.

I boldy think so roles and contexts are generating each other, neither of them are present in the current form of object (class) orientation. If a role is alone, it is rather an entity (data).

Best regards,

Cevat Balek

James O. Coplien

unread,
Sep 26, 2011, 12:08:59 PM9/26/11
to dci-ev...@googlegroups.com
Forget the software for the moment. Can you describe the scenarios, and how they compose into a use case?

Ant Kutschera

unread,
Sep 26, 2011, 2:34:11 PM9/26/11
to dci-evolution
On Sep 26, 6:08 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:
> Forget the software for the moment. Can you describe the scenarios, and how they compose into a use case?

Yes - I started this entire exercise with as little software in my
head as possible!

Here is the use case. This use case only focuses on completing a
sale. While I could expand it to include adding products to the
basket, that will just complicate things at the moment, so let's leave
it as it is. There is enough interaction going on that it's a good
example without more stuff.

In answer to your observation Rune, printing is just a tiny step in
the use case.
While I didn't list behavior in the transcript, it is in the use case
steps below.

--- start of use case ---

Use Case: 3 Serviced Sale – Complete Sale
Code: SS-3
Related Requirements: I.5, I.6, IV.1, IV.2
Extends: None
Depends on: "SS-1 Add items to basket", because items must be in the
basket in order to sell them
Includes: None
Assumptions: None
Description: Deals with the sales agent completing the sale after
scanning all books which the customer has brought them.

Goal: To complete the sale of all items in the basket, such that the
sales order and sales log records are created, the payment partner has
authorized the sale if the payment type is electronic, and the receipt
is printed.

Steps
=====
Actor: Sales Agent. Triggers the completion after scanning the last
product
1. Check if the basket contains items. If not, just show an error.
2. Check the printer has paper. If not, just show an error.
3. If the payment type is electronic, then:
a. Get authorization from the payment partner
b. If no authorization is given, just show an error.
4. Create the sales order in the sales order database (auditing)
5. Create the sales log records in the sales log (accounting)
6. Print the receipt on the printer
7. Update till's cash balance, if it was a cash sale
8. Empty basket
9. Open Cashbox if payment type is cash

Pre-Conditions: The till is running and awaiting a command. It
already contains items in the basket. Optional Customer Loyalty card
has been scanned, and any relevant discounts have been applied.
Triggers: User types the “C” key in order to complete the sale.
Post-Conditions: The till is ready to service the next customer.

Actors:Sales Agent (primary), Customer (off stage), Printer
(hardware), Payment Partner (external)
Objects: Till, Keyboard, Screen, Basket, Printer, Payment Partner,
Sales Log, Sales Log Records, Sales Order Database, Sales Order and
Sales Order Items

--- end of use case ---

Here is the data / model I have:

Class Till
BigDecimal cashBalance
ErrorInformation errorInfo
boolean showHelp
String tillNumber
String status

Class Basket
PaymentType paymentType
List<Product> productsInBasket //< and > are generics: its a list
containing products
Customer customer

Class ErrorInformation
String error

Class Customer
Long customerNumber;
BigDecimal loyaltyDiscount;
String name;

Those are all pretty dumb classes, with basically just getter and
setter methods.

PaymentType is an enumeration which can have value "cash" or
"electronic"

--- end of model ---

Here are some of the functional requirements (some written badly, just
like businesses write them):

The system must create a sales order for each sale.
A sales order must contain the following information:
+ a unique id sometimes called a sales reference
+ the authorization ID from the payment partner, if the payment type
was electronic
+ the timestamp of the sale (to the millisecond)
+ the customer number if known
+ the amount of customer discount applied, if relevant
+ the till number
+ the payment type

Additionally, for each item in a sales order, the following
information must be available:
+ the product title
+ the product code
+ the price at which it was sold
+ the amount of discount applied to that item
+ the sales reference of the parent sales order
+ the index of the item in the order

The system must deliver the sales orders for the month into the back
office auditing department at month end.

The system must create sales log records for each item that is sold,
as follows:
For each item, the following attributes must be stored:
+ a generated unique id
+ accountNumber = 100045
+ credit = the price paid for the item
+ debit = 0.0
+ the product code of the item
+ sales reference from the sales order
+ the index used for this product in the sales order
+ the authorization ID from the payment partner, if the payment
type was electronic
+ the timestamp of the sale, identical to that in the sales order
+ the payment type

Additionally, for each item that is discounted a record as follows
must be created:
+ a generated unique id
+ accountNumber = 100097
+ credit = 0.0
+ debit = the discount as an amount
+ the product code of the item
+ sales reference from the sales order
+ the index used for this product in the sales order
+ the authorization ID from the payment partner, if the payment
type was electronic
+ the timestamp of the sale, identical to that in the sales order
+ the payment type

Finally, for each item that is discounted a record as follows must
be created:
+ a generated unique id
+ accountNumber = 140451
+ credit = 0.0
+ debit = the customer discount as an amount
+ the product code of the item
+ sales reference from the sales order
+ the index used for this product in the sales order
+ the authorization ID from the payment partner, if the payment
type was electronic
+ the timestamp of the sale, identical to that in the sales order
+ the payment type

The system must communicate with the payment partner of choice in
order to get authorisation IDs for electronic payments

The system must print a receipt as follows for every sale made:

+------------------------+
| Nozama Limited |
| VAT Number 234-345-456 |
| 29/02/2011 12:34 |
| Till 2344545 |
| SalesRef E493DA332D |
| |
| The Joys of DCI 18.99 |
| discount -5.0% -0.95 |
| How Java Sucks 9.49 |
| |
| TOTAL 29.43 |
| (VAT @4.00% 1.18) |
| |
| Thanks for your custom |
+------------------------+

The system must keep track of the amount of cash (the balance) stored
in the till.

Here is a non-functional requirements which our friends in the
enterprise-architecture department have set us, just to make life
interesting. This has very little to do with DCI:

- the auditing database must be a separate physical database from the
accounting database to fulfil government requirements on traceability
and audability. Additionally, it must be filled at the time of sale
in case there are any system outages later which would lead to data
loss.

--- end of requirements ---

Ant Kutschera

unread,
Sep 26, 2011, 2:41:43 PM9/26/11
to dci-evolution
On Sep 26, 6:08 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:

Now, thinking along the lines of english sentences, I tried to create
some like this:

There is an interaction between A and B.

Or

A <does blah blah> to B.


Where A and B could be any of:

Payment Partner
Sales Order Database (auditing)
Sales Log (accounting)
Printer
Till
Basket

Here are my attempts:

- The till calls the payment partner to get an electronic payment
authorisation.
- The till creates a sales order in the sales order database.
- The till writes the sales log.
- The till prints the receipt.
- The till empties the basket.
- There is an interaction (collaboration) between the till and the
payment partner, if the payment type is electronic.
- There is a collaboration between the till, the sales order
dataase, the sales log and the printer.


"The till" is more like the subject of the use case in those
sentences, that is, the software being written, rather than the till
as in the data model.

So I have come to realise that my mental model isn't really object
oriented. What do I have to do to make it more object oriented?

Maybe then I will see the roles more clearly...

Please help!

Cheers,
Ant

James O. Coplien

unread,
Sep 26, 2011, 3:06:49 PM9/26/11
to dci-ev...@googlegroups.com
This reads more like a system requirement than a use case. "The system checks if the basket contains items" is the implicit translation of the first step. The problem here is that the verb has no explicit noun. Such nouns, in use-case-speak, are called actors. It is exactly these actors that are the the roles.

Pretend there is no computer: just people, things for sale, and pieces of paper. Good computer programs automate manual processes that work well. The computer isn't part of the problem space: it's part of the solution space. I don't want it as an actor in the use case. Given that, identify the actors. Write steps of the form:

Actor: action
Actor2: action2
. . .

Once that's done we can shape it into a use case scenario.

Then we'll figure out where the computer fits in.

Then the roles should just fall out of the wash.

James O. Coplien

unread,
Sep 26, 2011, 3:09:44 PM9/26/11
to dci-ev...@googlegroups.com
Adding texture to my previous mail:

On Sep 26, 2011, at 8:41 , Ant Kutschera wrote:

> - The till calls the payment partner to get an electronic payment
> authorisation.

That it is electronic is a low-level implementation detail, and that the till does the calling is, too. What human agent (role) initiates this?

Then we can use the till as a data object to implement that role.


> - The till creates a sales order in the sales order database.

Would a till create a sales order, or would a person (in some role) use a till (a machine) to create a sales order?


> - The till writes the sales log.

Probably a person, some kind of clerk or checkout person, who uses the till to do this.

> - The till prints the receipt.

But probably only at the behest of some human agent, who appears to be missing here.


> - The till empties the basket.

Do tills empty baskets?

Ant Kutschera

unread,
Sep 26, 2011, 5:03:54 PM9/26/11
to dci-evolution
So, I should pretend its 1935 and computers don't exist?

James O. Coplien

unread,
Sep 26, 2011, 5:17:39 PM9/26/11
to dci-ev...@googlegroups.com
For the use case, yes.

Risto Välimäki

unread,
Sep 27, 2011, 2:11:07 AM9/27/11
to dci-ev...@googlegroups.com

Yes, that prevents you thinking about technical details in use case definition.

Furthermore, it clearly shows that your use case is not complete, but more like user story or a part of a use case.

How often did you go to the shop just either for completing payment or for picking up goods? Back in 1935 or 2011, only shoplifters go to shop just for picking things up. Also who goes to the shop just for payment?

I suggest that the whole "buy books from the bookstore" is the whole use case.

Btw. Does "add books into basket" use case have a business value? As a shopkeeper I would go nuts with "customers" just picking up books and never completing the sale either by paying things and leaving or returning books due to insufficient funds or other reason. I am unsure here, but my answer to that question is that "add books into basket" does not have business value and therefore isn't a use case, but maybe a habit.

-Risto

Ant Kutschera

unread,
Sep 27, 2011, 4:05:04 AM9/27/11
to dci-evolution
OK, it's late 1935. Woody Allen was born a few weeks ago. There is
talk of Carl von Ossietzky winning the Nobel peace prize after
publishing details of Germany's alleged violation of the Treaty of
Versailles, and earlier this year, Amelia Earhart flew from Hawaii to
California, becoming the first person to do so.

Nozama Books is one tiny book shop in the sleepy town of Marbach,
situated on a beautiful lake in the centre of Europe.

In that book shop, Henry, the shop's founder, sells books. It works
like this (this time the full use case, as Risto suggests):

-----
1. A customer approaches Henry, the sales agent, with a basket full of
books
2. Henry reads the price and book number of each book, from it's price
tag on the back cover. He looks the book number up in a catalogue from
his supplier, to check the price is the same as that printed on the
price tag.
3. If the price differs, he informs the customer that he made a
mistake, and checks that the customer still wants to purchase that
book.
4. Henry, the sales agent, types the price of the book in to his aging
mechanical cash register, inherited from his father's clothes shop.
5. If the customer present's their loyalty card, Henry looks them up
in his little black book of customers, to see if they are to be given
a discount. If so, he enters the discount after having entered all
the books prices into the till.
6. When Henry, the sales agent, has finished typing all the prices
into the cash register, he asks the customer if they want to pay by
cash, or if he should call up Fred's Bank (down the street), who will
bill the customer at the end of the month and transfer the money to
Henry.
7a. If the customer wants to use that service provided by Fred's bank,
Henry calls them up and checks the customer has enough credit at the
bank to carry out the payment at the end of the month.
7b. During the call, Henry, the sales agent, writes the payment
reference number onto a slip of paper.
7c. After the call, Henry hits the "CREDIT" button on his till which
opens the cash drawer and he puts the piece of paper into it.
8a. If the customer doesn't want to use the banks service, Henry, the
sales agent, hits the "SALE" key on the till followed by the amount of
cash that the customer gives him.
8b. The till tells Henry how much change to return to the customer,
which Henry does.
9. Henry, being a pedantic shop keeper, turns to the table behind him
and quickly fills in this accounting book (ledger) and makes entries
for each item he sold, together with extra entries for any discounts
he gave. While doing this he contemplates buying a more modern till
which could do this step for him as it prints the receipt.
10. Henry then turns to his left and fills in the auditing forms which
Marbach requires he keep in case his company is audited.
11. Henry closes the cash drawer, causing a receipt to be printed,
which Henry hands to the customer.
12. Henry bags up the books, chats for a few minutes with the customer
talking mostly about the weather and they say their goodbyes as the
customer leaves the shop with their books.
-----

I have added a *lot* of detail to each step - I am sure I will be
criticised for doing so, but I don't want to miss any of the potential
objects or roles.

I would say, having read the above, that the actors are the customer,
the sales agent, and the bank. Potentially, the catalogue, the
accounting book, black book of customers and audit forms are actors
too?

So, the interactions are as follows. I will ignore the interactions
with the customer, because those are not part of the system to be
built - the customer is an off stage actor.

1) The sales agent interacts with the catalogue to check the price.
2) The sales agent interacts with the till to enter the price into
the till.
3) The sales agent interacts with his little black book of customers
to look the customer up.
4) The sales agent interacts with the bank to check the customers
credit.
5) The sales agent interacts with the with the till to put cash in
and take change out.
6) The sales agent interacts with the accounts book, to create
accounting records.
7) The sales agent interacts with the auditing forms.
8) The till interacts with the mechanical printer within it, to
print the receipt as it goes

The roles, like James said, seem to fall out:

1) The sales agent plays the role of a price checker while reading
the catalogue and informing the customer of a wrong price.
2) The sales agent plays the role of a sales agent while typing the
price into the till.
3) The sales agetn plays the role of a customer looker upper by
checking the black book to see if the customer deserves a discount.
4) The sales agent plays the role of a credit checker by calling the
bank.
5) The sales agent plays the role of a sales agent by taking the
cash and putting it into the till.
6) The sales agent plays the role of an accountant.
7) The sales agent plays the role of an auditor.
8) The till plays the role of a printer.

The roles are:

a) Sales Agent (general interaction with the till)
b) Price Checker (access to the catalogue and raising an error when
the price is wrong)
c) Customer Checker (access to the customer records to determine if
they get a discount)
d) Credit Checker (calling the bank)
e) Accountant (creating account records)
f) Auditor (creating audit records)
g) Printer (while printing lines on a receipt)

That first role "sales agent" doesn't appear to need implementing in
our modern solution, because we are not building a robot to replace
the sales agent. Everything else is being replaced by the modern
system, so will be built in software.

So, a very interesting exercise. I have the same roles which I had
before Rune suggested LineItem.

But, this time, they are almost all played by the sales agent so they
pass the "is a" test:

The price checker is a sales agent
The credit checker is a sales agent
The accountant is a sales agent
The auditor is a sales agent
The printer is a till - hmmmm.... not sure about that. More like
the till is a printer! But if you think about it, the specific
printer in question is a type of till.

Myself and I continued our discussion:

-----
Myself: Great - we have the roles!

I: Yeah, but they are played by the sales agent. In terms of
DCI, that means we need a sales agent as an object which holds a load
of data.

Myself: OK, let's try modelling the data in the use case:

Till
BigDecimal cashBalance
String tillNumber

Basket
List<Product> productsInBasket //< and > are generics:
its a list containing products
Customer customer //the customer is associated to the
basket by holding it

Sales Transaction
PaymentType paymentType

Customer
Long customerNumber
BigDecimal loyaltyDiscount
String name

I: That's great... but you haven't modelled the sales agent.

Myself: Oh yeah... well, hmmm... OK here:

Sales Agent
String name //like Henry

I: Yes, but none of those attributes are relevant to anything in
the interactions.

Myself: Actually, Henry is the actor and is human. Sales Agent is a
role he plays while interacting with the till, which is why we don't
need to create software to do that, because we aren't building a
robot.

I: Interesting observation. So is this: none of the objects
"Basket", "Sales Transaction" or "Customer" are playing any roles in
the use case.
-----

An interaction is communication between two or more objects, right?
This is leading me to the conclusion, that this system has no
interactions, other than those between the sales agent and the
individual parts like Printer, Sales Log, Sales Order Database,
Customer Database and Payment Partner.

It seems that the parts of this use case which I am required by my
customer to build, only interact with the system itself. I am loathed
to create an object called "System" as that seems entirely non-OO.

More help please...

Thanks,
Ant

James O. Coplien

unread,
Sep 27, 2011, 4:25:14 AM9/27/11
to dci-ev...@googlegroups.com
This is not a use case. It is a user narrative. That is even better — it is the "raw stuff" from which we derive scenarios and use cases!

Having even more of these (that explore different contexts, variants of behavior, etc.) is even better.

I'm in a class right now but when I break free I'll take a crack at giving you some guidance to distill this into a use case.

Risto Välimäki

unread,
Sep 27, 2011, 4:25:34 AM9/27/11
to dci-ev...@googlegroups.com
Ant, just nitpicking, but:

"(this time the full use case, as Risto suggests):

-----
1. A customer approaches Henry, the sales agent, with a basket full of
books"


I'm afraid I disagree with that. You can't start buying books by suddenly walking to a sales agent with a basket full of books. Are customers born with a basket full of books? A very important part of use case "buy books from bookstore" is first picking up books.

-Risto 


2011/9/27 Ant Kutschera <ant.ku...@gmail.com>

Cevat Serkan Balek

unread,
Sep 27, 2011, 4:41:04 AM9/27/11
to dci-ev...@googlegroups.com
Yes, we are no longer hearing or studying that kind of narratives :(

These are the essential parts of creating good software, i.e. generating as much contexts/roles and alternative paths as possible in natural language before, during and after coding takes place.

Unfortunately, when someone starts to talk like this, or even insist on others to collaborate on the though process -like in CRC(RRR) sessions-, s/he is usually marginalized by the coders. Coders always expect the flourishing of the narrative with handy keywords like widget, HTML, controller, etc. :)

Risto Välimäki

unread,
Sep 27, 2011, 4:46:00 AM9/27/11
to dci-ev...@googlegroups.com
I'd like to add that in your user narrative (thanks Jim, it's definitely a narrative) you did personate Henry, the shopkeeper, but your customer is impersonated.

Who is the User, customer or Henry? Who is then more important in user narrative (and later in use case), "a customer" or Henry?

User narratives tend to personate the User, which is in this case "a customer".

So the story -- user narrative -- would begin somehow like this:

"Harry, an avid bookworm has just found out that he has already read all books from his bookshelf at least twice. Harry likes the easygoing atmosphere of a tiny book shop, Nozama Books and heads there to buy some good books he hasn't read yet."

Another user narrative leading to bit different scenario, but within same use case as above would begin:

"Susan, 7-year-old schoolgirl is interested in Alice in Wonderland, and she approaches Nozama Books in order to find it and buy it if it's not too expensive for her."

-Risto

2011/9/27 Risto Välimäki <risto.v...@gmail.com>

Risto Välimäki

unread,
Sep 27, 2011, 4:56:53 AM9/27/11
to dci-ev...@googlegroups.com
Good short video on the power of user narratives:

http://www.youtube.com/watch?v=acMXhhdWylQ

Trygve Reenskaug

unread,
Sep 27, 2011, 9:57:41 AM9/27/11
to dci-ev...@googlegroups.com
Experience from OOram role modeling was that interfaces tended to be very small. And there were many of them.
--Trygve

On 2011.09.24 10:22, ant.ku...@gmail.com wrote:
Yes, so for the role classification to not be inhibiting, the language (or framework?) needs to be dynamic.  We must not be forced to define a priori what roles objects will play, but rather be able to assign them dynamically at runtime.

But none of that has much to do with using a typed name to refer to a role player. In fact sometimes that can be an advantage.  For example it can assist tools in offering support like code completion and refactoring.

----- Reply message -----
From: "rune funch" <funchs...@gmail.com>
To: <dci-ev...@googlegroups.com>
Subject: FullOO (a.k.a. DCI) Summit in Oslo
Date: Sat, Sep 24, 2011 09:58


2011/9/23 ant.ku...@gmail.com <ant.ku...@gmail.com>
Hi Cevat and others,

"...because RestrictedOO is based on classification."

While not directly related to what you wrote Cevat, this phrase made me think of something.

Becaue my language of choice forces me to delare types (for parameters, arguments, variables, fields, etc), I find myself often thinking of roles in terms of their interfaces.  Implicitly, this means I am classifying roles, doesn't it?

But I don't feel this hinders anyone.
Thinking of roles in terms of an explicit interface actually does hinder me at the moment. I have a side project where I'm developing an application for mobile platforms. I'm using MonoToiuch and MonoDroid. Most of the code I write is going to be platform independent but some stuff is going to be platform dependent. I can't change the interfaces the types implement, and even if I could I would want to be cause those changes would disappear with the next release of MonTouch/Droid. If the context where these objects plays a role was based on interfaces I would have to implement them once for each platform. Now I can reuse them as long as the potential roleplayers have methods signatures/properties that match. In this case method signatures that match is not very likely and I have to adapt them but for a text label to have a property called Text or similar is very likely.

I agree that DCI classifies as well but in a different manner. For lack of better terms I'd say you could talk about inhibiting and facilitating classifications. An inhibiting classification would be the classes societies a few hundred years back. Up north where I'm from we had "trælle" (kind of a slave) "bønder" (peasants) and "herremænd" (nobles). Those were classifications of the people of Scnadinavia a few hundred years back. You were born into one of those classes a with a high probability you'd die in the same. That classification inhibits you from becoming anything else.
Today we have other kinds of classifications e.g. we classify people as a pilot if they are flying a plane. We expect them to have all the required abilities to fly the plane but leave it to some one else to verify that.

To me using interfaces on data to determine what roles they can play lands in the inhibiting classification style. They can only play those roles and more importantly those types that does not implement those interfaces are inhibited from playing those roles and there's nothing you can do about it as in my example above.

Classifying objects based on what they are doing (roles) is different. As long as the object is playing the role of a pilot the object is a pilot. When implementing the class of the object you don't need to know what roles they are going to play. It won't limit which roles they can play. The abilities of the class determines what roles the objects of said class can play and if a new role comes along the same applies if the behavior is there the object can play the role, you have to change nothing. Having to change nothing is a big difference when the role player is implemented in a library you can't or won't change

-Rune

--

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

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

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

Norway

Cevat Serkan Balek

unread,
Sep 27, 2011, 10:34:15 AM9/27/11
to dci-ev...@googlegroups.com
Dear Trygve,

Can you be more specific about the experiments, if possible can you share them with us?

Can we conclude that, since there are many small interfaces, it is not practical or fruitful to classify / typify them using static language constructs?

By the way, OORAM is a great thought tool. Until today -just seen a link by chance-, I didn't know that there was a professional OORAM modeller which was built by Taskon :)

Cheers,

Cevat

Trygve Reenskaug

unread,
Sep 27, 2011, 11:22:51 AM9/27/11
to dci-ev...@googlegroups.com
'Printer', to me, is a good role name. RolePlayer classes could be 'Device' with subclass  'PrintingDevice' and then numerous subclasses.

IMO, it is very confusing to give the Basket the capability to print. Some role method somewhere can take data from the Basket and send them to the Printer (probably after some transformation.)  (Is basket a class or a role. I can't remember.)

BTW: I see no reason why a programmer  can't add helper roles that are not part of the user's mental model. See my many examples if you can find the time and energy.

--Trygve


On 2011.09.25 16:50, James O. Coplien wrote:
On Sep 25, 2011, at 4:17 , Ant Kutschera wrote:

  
So, in my Till example, I think this property is missing when I think
of things such as Printer - although I am not sure.  What do you think?
    
To me, at least at first blush, a Printer is not a role played by something. If someone says "Printer" to me in conversation I think of a specific object. There are many kinds of Printers in the world, by many manufacturers, that do many things, but those just form a CLASS hierarchy. I usually think of a Printer without thinking of the thing printed.

Objects of that class may play some role, and you have me thinking here, because I have a hard time thinking of any other name of that role other than "Printer." I guess that a Printer as a role prints something that is given to it... But there is some kind of confusion in my mind about this.

Thoughts?

James O. Coplien

unread,
Sep 28, 2011, 6:07:57 AM9/28/11
to dci-ev...@googlegroups.com
I don't think the goal is to create as many roles (or anything) as possible. An important part of mental modeling is chunking. We have engineering rules like Occam's Razor, the 5 +/– 2 rule of short-term memory, and other heuristics that help make code understandable.

In any given context you want only one locus of attention (a term from psychology that relates to what you are conscious of at a given moment) at any given point of reasoning, and you want no more than 7 total concepts that you need to reason about together. Anything else defies human comprehension. To understand more complex designs requires higher-order chunking. We do that by forming hierarchies of algorithm, and it seems like Context stacking has become a common DCI technique to handle that.

I'm not saying that there shouldn't be many roles. I'm saying that you need a higher order organizing principle to be able to understand the system if the number of roles gets too high.

James O. Coplien

unread,
Sep 28, 2011, 6:09:18 AM9/28/11
to dci-ev...@googlegroups.com

On Sep 27, 2011, at 10:46 , Risto Välimäki wrote:

User narratives tend to personate the User, which is in this case "a customer".


Furthermore, good ones don't call it "User," but give it a crisp name. In User Story speak, this name is called — curiously enough — a Role.

James O. Coplien

unread,
Sep 28, 2011, 6:44:20 AM9/28/11
to dci-ev...@googlegroups.com

On Sep 27, 2011, at 8:11 , Risto Välimäki wrote:

How often did you go to the shop just either for completing payment or for picking up goods? Back in 1935 or 2011, only shoplifters go to shop just for picking things up. Also who goes to the shop just for payment?

I suggest that the whole "buy books from the bookstore" is the whole use case.


Really good insight. This gives the story a business goal, thereby making it into a use case. Otherwise, without a goal, it's just a habit.

Risto Välimäki

unread,
Sep 28, 2011, 8:15:09 AM9/28/11
to dci-ev...@googlegroups.com
2011/9/28 James O. Coplien <jcop...@gmail.com>

I don't think the goal is to create as many roles (or anything) as possible. An important part of mental modeling is chunking. We have engineering rules like Occam's Razor, the 5 +/– 2 rule of short-term memory, and other heuristics that help make code understandable.

+2

I mean, it's magical number 7 +/- 2 ;-) 


"If you all you have is the DCI, everything looks like a Role"?

-Risto

James O. Coplien

unread,
Sep 28, 2011, 8:49:43 AM9/28/11
to dci-ev...@googlegroups.com
The 7 +/1 2 number is one of the most widely promulgated myths in psychology, based largely on web-assisted mass propagation of research dating from the mid-1950s. Even if you stretch the original research to believe in the popular number 7, that result applies to letters rather than to higher-order concepts, for which the number is much lower. And even then, there are newer research results using better research methods, and those conclude that the magic number is closer to 5 +/- 2. See, for example, http://www.mdjunction.com/forums/bipolar-type-ii-discussions/general-support/3021312-short-term-memoryhttp://tastyresearch.com/2006/08/30/debunking-the-seven-plus-or-minus-two-myth/http://en.wikipedia.org/wiki/George_Armitage_Millerhttp://www.usc.edu/CSSF/History/2003/Projects/S0309.pdf.

These myths tend to propagate in part because they take on social mythological proportions. But they also propagate because of poorly Shepherdized citation in academia — also one of the main reasons that the object community was never able to shed many of the myths that came in the early days of OO and persisted, even though subsequent research debunked them. For that reason people still believe that object-orientation is all about polymorphism, productivity and reuse. The fundamental notions of mental models and object identity become lost in the ignorance of modern publication. This is probably the greatest enemy of DCI today.

But so it is with any paradigm shift.

Cevat Serkan Balek

unread,
Sep 28, 2011, 9:07:31 AM9/28/11
to dci-ev...@googlegroups.com
Dear James,

WOW :)

I especially liked this one: "People still believe that object-orientation is all about polymorphism, productivity and reuse. The fundamental notions of mental models and object identity become lost in the ignorance of modern publication."

It is really hard to convince even the earnest software professional that "object orientation" is totally a different thing than what the old school teached us :)

Therefore, I insist that, we -the members of DCI evolution group- should try to define the new landscape, at least at the current collective experimentation level.

For this reason, although it is so basic&fruitful to discuss about them, I suggest that the discussions around how to write a good user narrative and good use case, and even some tutorials should go in object-composition group where they may get much more audience.

Best regards,

Cevat Balek

Risto Välimäki

unread,
Sep 28, 2011, 10:23:10 AM9/28/11
to dci-ev...@googlegroups.com
2011/9/28 James O. Coplien <jcop...@gmail.com>
The 7 +/1 2 number is one of the most widely promulgated myths in psychology, based largely on web-assisted mass propagation of research dating from the mid-1950s. Even if you stretch the original research to believe in the popular number 7, that result applies to letters rather than to higher-order concepts, for which the number is much lower. And even then, there are newer research results using better research methods, and those conclude that the magic number is closer to 5 +/- 2. See, for example, http://www.mdjunction.com/forums/bipolar-type-ii-discussions/general-support/3021312-short-term-memoryhttp://tastyresearch.com/2006/08/30/debunking-the-seven-plus-or-minus-two-myth/http://en.wikipedia.org/wiki/George_Armitage_Millerhttp://www.usc.edu/CSSF/History/2003/Projects/S0309.pdf.

True, I remember we discussed about that in our HCI studies at university. It's not clear where the magical number 7 came up, but even in Millers original studies numbers varied between 4 and 10 depending on the subject. But anyhow, the idea of our limited short term processing capacity is important and I usually tend to use "about 5" as an rule of thumb. 

These myths tend to propagate in part because they take on social mythological proportions. But they also propagate because of poorly Shepherdized citation in academia — also one of the main reasons that the object community was never able to shed many of the myths that came in the early days of OO and persisted, even though subsequent research debunked them. For that reason people still believe that object-orientation is all about polymorphism, productivity and reuse. The fundamental notions of mental models and object identity become lost in the ignorance of modern publication. This is probably the greatest enemy of DCI today.

Very well put. I would like to add that developers also believe that object-orientation is about classes. 

But so it is with any paradigm shift.

Paradigm shifts are hard, but very good learning experiences. As soon as I have time (year 2020 I suppose...), I'll try to make paradigm shift into functional programming (with Scala).

Ps. painfully slow, but again writing my bachelors thesis on "DCI and an example implementation for the Web" in Finnish. Masters thesis will be in English for better feedback from (and hopefully even for benefit to) DCI community.

-Risto

rune funch

unread,
Sep 28, 2011, 11:05:16 AM9/28/11
to dci-ev...@googlegroups.com
The number 7 +/-2 could very well be from an Ericson and Chase study where almost All subjects landed in the 5-9 range.  The test was the recall a series of numbers. Later test such as recalling a chess board have shown non chess players to be able to recall on average 5 pieces and chess pros to be able to recall 5 groupings if the pieces was placed in a plausible game position whereas they were able to only recall 5-6 pieces is placed randomly on the board

Mvh
Rune

Risto Välimäki

unread,
Sep 28, 2011, 11:46:40 AM9/28/11
to dci-ev...@googlegroups.com
I was a bit unclear. The 7 +/- 2 definitely is from George A. Millers paper (1956) entitled "The Magical Number Seven, Plus or Minus Two: Some Limits on Our Capacity for Processing Information", but allegedly in the paper (I have not read it myself) the limit changes from 4 to 10 depending the subject. 

-Risto

2011/9/28 rune funch <funchs...@gmail.com>

Ant Kutschera

unread,
Sep 29, 2011, 3:19:01 AM9/29/11
to dci-evolution
On Sep 27, 5:22 pm, Trygve Reenskaug <tryg...@ifi.uio.no> wrote:
> 'Printer', to me, is a good role name. RolePlayer classes could be
> 'Device' with subclass  'PrintingDevice' and then numerous subclasses.
>
> IMO, it is very confusing to give the Basket the capability to print.
> Some role method somewhere can take data from the Basket and send them
> to the Printer (probably after some transformation.)  (Is basket a class
> or a role. I can't remember.)


Hi Trygve,

"Device" as an object is unsatisfactory, because it is the device
(i.e. the Till) which I am building. As such, I could swap "device"
with "system".

In OO, there is no "god object", and if I did choose to use one, I
might as well continue and implement services, because services (the
way I define them) are part of "the system".

Then again, perhaps if "device" is the correct role player, and
"device" is the Till I am building, then the role player should be
"Till"? That is what I originally though.

Basket is a class (i.e. an instance of it is a domain object). As
such it is a candidate to be a role player. But the question is,
which role?

Cheers,
Ant



> BTW: I see no reason why a programmer  can't add helper roles that are
> not part of the user's mental model. See my many examples if you can
> find the time and energy.
>
> --Trygve
>
> On 2011.09.25 16:50, James O. Coplien wrote:
>
> > On Sep 25, 2011, at 4:17 , Ant Kutschera wrote:
>
> >> So, in my Till example, I think this property is missing when I think
> >> of things such as Printer - although I am not sure.  What do you think?
>
> > To me, at least at first blush, a Printer is not a role played by something. If someone says "Printer" to me in conversation I think of a specific object. There are many kinds of Printers in the world, by many manufacturers, that do many things, but those just form a CLASS hierarchy. I usually think of a Printer without thinking of the thing printed.
>
> > Objects of that class may play some role, and you have me thinking here, because I have a hard time thinking of any other name of that role other than "Printer." I guess that a Printer as a role prints something that is given to it... But there is some kind of confusion in my mind about this.
>
> > Thoughts?
>
> --
>
> Trygve Reenskaug       mailto: tryg...@ifi.uio.no
>
> Morgedalsvn. 5A        http://folk.uio.no/trygver/
>
> N-0378 Oslo               Tel:(+47) 22 49 57 27begin_of_the_skype_highlighting            (+47) 22 49 57 27      
>
> Norway

Ant Kutschera

unread,
Sep 29, 2011, 3:20:11 AM9/29/11
to dci-evolution
On Sep 27, 10:25 am, "James O. Coplien" <jcopl...@gmail.com> wrote:
> This is not a use case. It is a user narrative. That is even better — it is the "raw stuff" from which we derive scenarios and use cases!
>
> Having even more of these (that explore different contexts, variants of behavior, etc.) is even better.
>
> I'm in a class right now but when I break free I'll take a crack at giving you some guidance to distill this into a use case.

Hi James,

I would very much appreciate you doing this - thanks for the offer! I
look forward to the results. I would like to take this thread to the
end, and really see the roles and role players being identified with
strong arguments as to why each is a role or role player.

Thanks,
Ant

Ant Kutschera

unread,
Sep 29, 2011, 5:18:26 AM9/29/11
to dci-evolution
What I just posted on object-composition (about how I've extended
Java) fits your description of injecting methods here very well.

On Sep 25, 4:42 pm, "James O. Coplien" <jcopl...@gmail.com> wrote:
> A little tutorial here. You'll probably have to read this several times and let it soak in to round it out. I'm trying to convey a large number of basic concepts that, if understood, probably could block off blind alleys of discussion, including a few that have occurred here already.
>
> The semantics of assignment in a high-level language are "sticky note" semantics. A "sticky note" has the name of an identifier (sometimes called a "variable") written on it. If we say (in C++):
>
>         Object *fred = new Car;
>
> then there is an object sitting in memory, whose name is called fred. The object is *fred. That is, someone has put the fred sticky note on the object. With respect to the programming language the object has no other interesting name. On the other side of the programming language abstraction boundary, the object's name is its address in memory.
>
> I use the term "binding" to designate the putting of a sticky note on an object.
>
> Now if we say:
>
>         Object *george = fred;
>
> we have created another sticky note with "george" written on it, and have put it on the same object where we find the fred sticky note. The object now has two names. The object's name is called *fred, but it is also called *george.
>
> Technically, those are only what its name is called. Its name is its address.
>
> Notice, however, that the object does not play two roles.
>
> This is important: note that there is no intrinsic notion of copying — of anything — in high-level language assignment. The compiler is not obliged to take more memory or even generate object code to implement the second line above. It may simply hack the symbol table to make george and fred be synonyms in the same scope. Other manipulations on these identifiers may force the compiler to clone a pointer, but it is not an intrinsic property. C++ makes this explicit in an alternative form of assignment:
>
>         Object &ted = *fred;
>
> So now the name of the object (in C++) is ted, but also *fred and also *george. This is not FORTRAN or Pascal. In those languages, assignment means copying. The ideal in an object-oriented language is that there is no implicit copying: if you want to copy an object, you apply the shallow_copy or deep_copy operator to it, and it yields a new object. In FORTRAN, if I say:
>
>         INTEGER A, B
>     A = 1
>
> and then say
>
>         B = A
>
> there are two objects, one whose name is B and the other whose name is A. (This is additionally confusing in FORTRAN because the literal 1 is a value rather than an object.) Actually, there were two objects before the assignment, though one of them had undefined value.
>
> The sticky note model has interesting implications. Once you take the last sticky note from an object it is no longer reachable by any program code. That means that its memory can be reclaimed. That is often called garbage collection and it, too, is fundamental to the object programming model.
>
> DCI takes this one step further. When it associates a new name with an object, to designate its role, it also injects code into the object to enrich its functionality. The new name is what we call a methodless role — it's just an alias, another name by which the object is called, in the good old object-oriented sense. The code that is injected into the object to enrich its functionality is called a methodful role. It is a trait in Scala, a module in Ruby, a class in C++. That's DCI.
>
> None of these notions map to a Java interface. DCI is an attempt to separate the functionality of an object from its data representation. Java interfaces are an attempt to separate the protocol of an object from the implementation of both its behavior and data. Like other facets of any compile-time type system they fit into DCI only by happenstance.
>
> One can create all kinds of hacks to simulate object semantics with explicit program code. Wrappers are a way to simulate identifier semantics. This is how the handle-body idiom works in C++: we use an object of a wrapper class to simulate the semantics of a true object identifier. Much of the complexity of C++ (its overloading of operators such as operator=, operator*, and operator–>) owes to the need to sustain this level of transparency. It works, but only with incredible discipline.
>
> True object-oriented languages built in this wrapper-ness automatically. In Smalltalk, identifiers and objects are different things. The identifier is only the name by which the object is called: it is not the object. Contrast this with FORTRAN, where an identifier (called a variable) is the name of the object: you cannot separate the name of the object from the object. There is no value of talking about the object apart from its name. (By the way, there is also a way to create aliases in FORTRAN, called the EQUIVALENCE statement, so an object can have many names — but it is one set of static associations.) So Smalltalk treats identifiers like sticky notes, and it knows when the last sticky note becomes unpeeled from the object, and it can reclaim its memory. That happens on the other side of the language abstraction boundary.
>
> DCI is similar, in that it moves the dynamic typing of an object to the other side of the language abstraction boundary and allows one to program in roles and objects rather than classes. Conveniently enough, most languages have just the mechanism that DCI needs: e.g., the extend[s] concept in Ruby and Scala; the indirect template idiom in C++. Languages are less facile in expressing the broader association semantics germane to a context, though Trygve's environment does this handily with a graphical notation. Java does not have these facilities at all, so the complexity of wrappers shows up on this side of the abstraction boundary. You can make it work 90% of the time, just like you can make reference counting in C++ (which requires wrappers) work 90% of the time. But the code is complex, and it has failure modes (for circular references, for example).
>
> The same is likely true for any wrapper solution to DCI. I have conceived of another example that straddles the abstraction boundary in an uncomfortable way that is sure to break wrappers in a hard way, and that's Knuth's buddy system algorithm. I'll work up an example (though I'm sure it's going to be painful in Ruby...)
>
> Good programming practice in DCI provides that one declare suitably named identifiers that communicate the functional intent of an object. In the Dijkstra example, almost every object has three names at some time or another: the current intersection, being a west neighbor, or being a south neighbor. But this is just a gentlemanly agreement written by convention, and is not the focus of DCI. The focus of DCI is that objects are suitably injected with the logic necessary to perform those named roles. The named roles are just convenient ways to express the intent. So if I have a seaplane, I can say:
>
>     seaplane = new Boat
>     Airplane extends seaplane   // inject Airplane role into the object
>     boat = seaplane             // create an alias
>     boat.sail()                 // O.K., within DCI, and good coding style
>     boat.fly()                  // O.K., within DCI, questionable coding style
>
> It's important to note that the stylistic questions are a matter of taste and are neither an ipso facto matter of the domain nor of DCI:
>
>     sue = new Female
>     Mother extends sue
>     jeff = new Male
>     Father extends jeff
>     joey = new Male
>     Child extends joey
>     Nurturer extends jeff
>     WageEarner extends sue
>     jeff.nurture(joey)
>
> is perfectly meaningful and representative of a configuration within the domain, though it violates stereotypes — just as a seaplane violates the stereotype of a boat being able to fly. That is, there is nothing wrong with a boat flying if it has the capability of playing the role. It's a bit unusual, but the world is full of unusual things. It is this unusualness that changes classification from a hierarchy to a DAG. If everything were subject to our expectations, we would need only classes. DCI recognizes that the world is messier than that, so we need roles and role-to-object mappings to capture the complexity.
>
> Lewis Carroll said it well:
>
>     “The name of the song is called`Haddock's Eyes’.”
>     “Oh, that's the name of the song, is it?” Alice said, trying to feel interested.
>     “No, you don't understand,” the Knight said, looking a little vexed.  “That's what the name is called. The name really is `The Aged, Aged Man.'”
>     “Then I ought to have said, 'That's what the song is called'?” Alice corrected herself.
>     “No, you oughtn't;  that's quite another thing! The song is called `Ways and Means'; but that's only what it's called, you know!”
>     “Well, what is the song, then?” said Alice, who was by this time completely bewildered.
>     “I was coming to that,” the Knight said. “The song really is `A-sitting on a Gate'; and the tune's my own invention.''
>     “But the tune isn't his own invention,” she said to herself; “it's `I give thee all, I can no more.'”
>
> On Sep 25, 2011, at 10:00 , Ant Kutschera wrote:
>
>
>
> > On Sep 25, 2:18 am, rune funch <funchsolt...@gmail.com> wrote:
> >> I might be the confused one here but I don't assign a role to an
> >> object I bind and object to a role. All the code you wrote in your
> >> mail, I thought that was about binding an object to a role
>
> > What do you mean by binding as opposed to assigning?
>
> > Is this what you mean by binding:
>
> >    object.extend(Role);
>
> > and this what you mean by assigning:
>
> >    newVariableName = object assign Role;

Trygve Reenskaug

unread,
Sep 29, 2011, 5:19:14 AM9/29/11
to dci-ev...@googlegroups.com
Unfortunately, the Taskon company no longer exists, the OOram program has not survived in a changing world, and even the model files are gone.

OOram controlled which messages a role was permitted to send. to another role. The communication structure was specified through directed connectors between roles. The sending end of a connector was called a port. A port contained one or more interfaces. An interface specified the messages permitted to be sent through the port to the adjacent receiver.  The required behavior of the receiver was derived as the union of all sender interfaces.

An example illustrates why the interfaces were small and many.  A service role offered full CRUD access for each of its apparent states. Only one other role was permitted the full CRUD access. All other roles were only given Read-access to the service. Two interfaces for each interesting state.

The DCI Interaction tells a complete story and makes interfaces between roles unnecessary. Interfaces from roles to roleplayers are still important. They should only contain the messages that are actually permitted through that port.

Cheers
--Trygve

Cevat Serkan Balek

unread,
Sep 30, 2011, 4:08:26 AM9/30/11
to dci-ev...@googlegroups.com
Dear Trygve -and group-,


"The DCI Interaction tells a complete story and makes interfaces between roles unnecessary."

Yes, that's the point!

With DCI, we are freed from unnecessary interfaces and use them only where they are required. I believe, clearly understanding this fact is one of the hardest challanges in grasping DCI. We want the code which descibes the interaction between the choosen objects to be clearly readable/compressable -in the way Trygve&James described-. If that code is readable and understandable even in user's perspective, there is no need for interfaces: we just use the object directly.

Cheers,

Cevat
Reply all
Reply to author
Forward
0 new messages