How to model a DCI system?

217 views
Skip to first unread message

Michael Sokol

unread,
Jun 29, 2011, 8:35:46 PM6/29/11
to object-composition
Hello everybody,

I am just discovering the DCI approach to object-orientation, and I
really like it. However, I'm having trouble finding resources
explaining each aspects of it. I'm especially having a hard time
understanding the concept of "Context". I'd need some clarification.
Is it only a different kind of object, or is it something different?

Also, I would really be interested in hearing how to model a DCI
system. I'm guessing UML class diagrams could be used to design
classes, let alone the fact that they would probably still fail due to
the static biais of the notation, but how about roles, contexts, and
even object?

Thank you,
Michael

Erlis Vidal

unread,
Jun 29, 2011, 11:33:13 PM6/29/11
to object-co...@googlegroups.com
Hi Michael,

This link could be useful: http://www.leansoftwarearchitecture.com/home/more-online-resources

Something that I highly recommend you is to read Coplien's book Lean Architecture http://www.amazon.com/Lean-Architecture-Agile-Software-Development/dp/0470684208

A personal advice: Try to implement this first in any language that support traits. Don't use at the beginning c#, java. Then when you fully understand the DCI approach look into the previously mentioned languages. You will find that a lot of the noise is because limitations of those languages.

my 2 cents
Erlis

--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.


Christian Horsdal Gammelgaard

unread,
Jun 30, 2011, 1:59:03 AM6/30/11
to object-co...@googlegroups.com


On Thu, Jun 30, 2011 at 2:35 AM, Michael Sokol <mika...@gmail.com> wrote:
<snip>

Also, I would really be interested in hearing how to model a DCI
system. I'm guessing UML class diagrams could be used to design
classes, let alone the fact that they would probably still fail due to
the static biais of the notation, but how about roles, contexts, and
even object?
<snip>

Remember that DCI is about objects, not classes. So UML class is not the best way to approach modelling in a DCI paradigm. Consider just doing informal models, or if you have to be in UML use object diagrams combined with some the dynamic diagrams types (like state or sequence diagrams). Contexts in this case can just be objects. Roles are harder...Dont see how they'd fit into UML.

/Christian
@chr_horsdal

Rune Funch Søltoft

unread,
Jun 30, 2011, 2:21:24 AM6/30/11
to object-co...@googlegroups.com

Den 30/06/2011 kl. 05.33 skrev Erlis Vidal <er...@erlisvidal.com>:


A personal advice: Try to implement this first in any language that support traits. Don't use at the beginning c#, java. Then when you fully understand the DCI approach look into the previously mentioned languages. You will find that a lot of the noise is because limitations of those languages.

A sound advice seen from how often we debate languages. C# 4.0 support traits so if willing to learn the new parts of tha language it can easily be used. 

irwan azam

unread,
Jun 30, 2011, 2:32:21 AM6/30/11
to object-co...@googlegroups.com
C# 4.0 support traits?.. Really? Do you have any reference say about that

thanks

Oleh Kashperuk

unread,
Jun 30, 2011, 2:51:35 AM6/30/11
to object-co...@googlegroups.com
Very usefull practice for modeling systems (contexts) can be Color Modeling (http://www.step-10.com/SoftwareDesign/ModellingInColour/index.html)
Learn about how to determine system archetypes.
In my mind, theirs problem domain pattern (Domain Neutral Component) is very usefull.


>> C# 4.0 support traits so if willing to learn the new parts of tha language it can easily be used.

Great news! But I can't find any information about this in Internet.
Please, provide any reference about described C# 4.0 feature

Regards, Oleh
Sorry for my terrible english :)

2011/6/30 Rune Funch Søltoft <funchs...@gmail.com>

Rune Funch Søltoft

unread,
Jun 30, 2011, 3:05:17 AM6/30/11
to object-co...@googlegroups.com
Ok I might have expressed my self to simplistic you are not going to find references to traits in C# but the dynamic run time and the way the dynamic binding works (you can basically customize how it works) can be leveraged to create traits

Mvh
Rune

irwan azam

unread,
Jun 30, 2011, 3:29:26 AM6/30/11
to object-co...@googlegroups.com
Hi Rune, do you have any example to share?..

Wenig, Stefan

unread,
Jun 30, 2011, 3:49:52 AM6/30/11
to object-co...@googlegroups.com

Hi group

 

The dynamic capabilities of C#4 are designed for interoperability with dynamic languages. Sure, you can build native C# code using a bag of tricks using this feature, but then you lose everything that C# as a statically typed language is about. If you want dynamic programming, you really should look into a dynamic language, because with C# you’re not going to get the full dynamic experience. It would probably be a rather frustrating middle ground.

 

If you want to use mixins in C#, I humbly recommend looking into our project re-mix: remix.codeplex.com. It’s a lot like Qi4j.

 

However, there are viable examples out there doing DCI in C# with interfaces and extension methods. And I still don’t see anything in DCI that cannot be implemented using those. I do know the limitations of extension methods (there are many: they are just syntactical sugar for static methods), and there are many things that mixins can do and extension methods cannot, but they seem to be excluded by DCI: roles have neither state nor polymorphism after all.

 

I’m eager to see the sample we’ve been talking about, this should help make a lot of things clearer.

 

Cheers,

Stefan

Trygve Reenskaug

unread,
Jun 30, 2011, 4:44:39 AM6/30/11
to object-co...@googlegroups.com
The UML Collaboration is very close to the DCI Context: The following is a quote from page 174 in
http://www.omg.org/spec/UML/2.3/Superstructure/PDF/
"A collaboration describes a structure of collaborating elements (roles), each performing a specialized function, which
collectively accomplish some desired functionality. Its primary purpose is to explain how a system works and, therefore,
it typically only incorporates those aspects of reality that are deemed relevant to the explanation. Thus, details, such as the
identity or precise class of the actual participating instances are suppressed "

Description

A collaboration is represented as a kind of classifier and defines a set of cooperating entities to be played by instances (its
roles), as well as a set of connectors that define communication paths between the participating instances. The
cooperating entities are the properties of the collaboration (see “Property (from InternalStructures)” on page 189).
A collaboration specifies a view (or projection) of a set of cooperating classifiers. It describes the required links between
instances that play the roles of the collaboration, as well as the features required of the classifiers that specify the
participating instances. Several collaborations may describe different projections of the same set of classifiers.
 And then there is the large body of UML behavior modeling concepts available for modeling the behavior of a Collaboration object.  (Like state and sequence diagrams as suggested by Michael)

The UML Collaboration stems from my Role Modeling. A word of warning: I haven't seen a book on UML that understands the nature of Collaborations. You need to go to the formal UML document itself, which is very heavy reading.

It should be possible to write a guide for modeling DCI systems with UML.
Jim: Is this a theme for a Master or PhD? It could be a new and very useful intro for DCI novices.
The work would involve  extracting useful bits from UML and possibly modifying them where  necessary. The modifications could become input to a next version of UML.

Cheers
--Trygve

P.S.: Many people disregard UML for its complexity and its many inconsistencies. This is understandable, but people miss its great body of useful concepts and notations.Users of UML are expected to ignore what they don't like and focus on the parts that are useful to them. Also, UML must not be read as a piece of legislation, but as a suggestion of how to do things.
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.

--

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

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

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

Norway

James O. Coplien

unread,
Jun 30, 2011, 5:00:53 AM6/30/11
to object-co...@googlegroups.com

On Jun 30, 2011, at 2:35 , Michael Sokol wrote:

> Hello everybody,
>
> I am just discovering the DCI approach to object-orientation, and I
> really like it.

Welcome to the community :-)

> However, I'm having trouble finding resources
> explaining each aspects of it. I'm especially having a hard time
> understanding the concept of "Context". I'd need some clarification.
> Is it only a different kind of object, or is it something different?

It is an object that wires up objects to roles. Think of it as the producer in a play — the one who hires the actors and assigns their roles.

What's interesting is that because it is an object it, too, can be an actor, which means it can play a role (but it doesn't have to).


> Also, I would really be interested in hearing how to model a DCI
> system. I'm guessing UML class diagrams could be used to design
> classes, let alone the fact that they would probably still fail due to
> the static biais of the notation, but how about roles, contexts, and
> even object?

In asking for a notation, what problem are you trying to solve? The answer varies widely depending on your answer. You might download Trygve's IDE and play with it a bit — in his approach, the program more or less *is* the model, and is represented graphically.


> Thank you,
> Michael

James O. Coplien

unread,
Jun 30, 2011, 5:06:02 AM6/30/11
to object-co...@googlegroups.com
Hi, Erlis,


On Jun 30, 2011, at 5:33 , Erlis Vidal wrote:

> A personal advice: Try to implement this first in any language that support traits. Don't use at the beginning c#, java. Then when you fully understand the DCI approach look into the previously mentioned languages. You will find that a lot of the noise is because limitations of those languages.


I think this is good advice, or at least seems to be heading in the right direction.

But — can you be more explicit? I mean, to me, C++ supports traits (and always has since the implementation of templates back in the 1980s), so I'd include it in the list. Others may not. The Python approach to DCI doesn't really use traits because classes are of negligible importance in that implementation. It's probably a cleaner implementation than any trait-based implementation because you get to think in objects instead of classes which, in some sense, is where DCI starts. (Traits are useful to implement DCI in classful languages.) Which languages — other than Scala, which is the obvious choice — would you include in your list?

Serge Beaumont

unread,
Jun 30, 2011, 8:51:33 AM6/30/11
to object-co...@googlegroups.com
The Catalysis book ("Objects, Components and Frameworks with UML, The Catalysis Approach") by Desmond D'Souza and Alan Wills has a section where they describe, and show, this usage of a Collaboration. It even makes a direct reference to use cases, the same way DCI does. It was this mental image which helped me make the click in DCI...

I've looked it up: page 154 and further (Chapter 4) deals with collaborations, and chapter 9 on Frameworks.

Wow. Looking at the book again I'm only now struck by how close these topics in this book are to DCI... anybody else have it? See for instance figure 9.10 on page 348... that's DCI! The section on composing frameworks and "building systems from collaborations" (9.5.1): DCI again. To be honest, it is still a bit class-oriented, but the way they've done it I see no reason you could not apply this in an object-oriented way as well...

Erlis Vidal

unread,
Jun 30, 2011, 9:52:28 AM6/30/11
to object-co...@googlegroups.com
Hi,

On Thu, Jun 30, 2011 at 5:06 AM, James O. Coplien <jcop...@gmail.com> wrote:
Hi, Erlis,


On Jun 30, 2011, at 5:33 , Erlis Vidal wrote:

> A personal advice: Try to implement this first in any language that support traits. Don't use at the beginning c#, java. Then when you fully understand the DCI approach look into the previously mentioned languages. You will find that a lot of the noise is because limitations of those languages.


I think this is good advice, or at least seems to be heading in the right direction.

I think that the path you choose when learning DCI could help you dramatically to its understanding. When learning DCI people will face concepts that might be new to them, if they don't know there are languages that allow you to implement easily those concepts, they will have hard time figuring out how to use this in their projects.

My point was that at the novice stage go with a language that allows you to easily express DCI and play with that, until you have your AHA! until you understand the difference between class and object (A lot of people struggle here because they don't know any better)

When you reach this stage, then you can start looking at how people are implementing DCI in C# for example... you will see, ahhh they are using extension methods, or dynamics. This IMO should be done not in the novice stage.



But — can you be more explicit? I mean, to me, C++ supports traits (and always has since the implementation of templates back in the 1980s), so I'd include it in the list. Others may not. The Python approach to DCI doesn't really use traits because classes are of negligible importance in that implementation. It's probably a cleaner implementation than any trait-based implementation because you get to think in objects instead of classes which, in some sense, is where DCI starts. (Traits are useful to implement DCI in classful languages.) Which languages — other than Scala, which is the obvious choice — would you include in your list?


I didn't suggest any language intentionally, you already mentioned Python and Scala, I'll add Ruby to the list, but if the programmer have no experience with any of those languages, I'll use Javascript, I think is one of the most popular languages, (even when people just scratch its surface)

Thanks
Erlis

 

James O. Coplien

unread,
Jun 30, 2011, 11:50:52 AM6/30/11
to object-co...@googlegroups.com

On Jun 30, 2011, at 10:44 , Trygve Reenskaug wrote:

It should be possible to write a guide for modeling DCI systems with UML. 
Jim: Is this a theme for a Master or PhD? It could be a new and very useful intro for DCI novices.
The work would involve  extracting useful bits from UML and possibly modifying them where  necessary. The modifications could become input to a next version of UML.


I doubt that this is ph.d. material, but it could be a good MS project.

rune funch

unread,
Jun 30, 2011, 6:00:41 PM6/30/11
to object-co...@googlegroups.com


2011/6/30 irwan azam <irwa...@gmail.com>

Hi Rune, do you have any example to share?..


Yes I have some code to share :)

Let's take a well know example, just to be on fairly familiar grounds

public class MoneyTransferContext : ClearMud<MoneyTransferContext>

    {

        [Role(Name = "Source")]

        public interface ISource

        {

            Func<Account,decimal,bool> TransferFrom { get; }

        }

 

        private static class RoleMethods

        {

            public static bool TransferFrom([Role]Account Source, Account destination, decimal amount)

            {

                Source.DecreaseBalance(amount);

                Source.Log("Withdrew: " + amount);

                destination.IncreaseBalance(amount);

                destination.Log("Withdrew: " + amount);

                return true;

            }

        }

 

        private ISource Source;

        private Account Destination;

        public void Doit(decimal amount)

        {

            Source.TransferFrom(Destination, amount);

        }

 

        public static MoneyTransferContext Bind()

        {

            var _this = new MoneyTransferContext();

            Bind(_this,new {Source = new Account(),Destination = new Account()});

            return _this;

        }

 

    }

 

 

So once again it's the MoneyTransfer example. Yes I know we've been over it a multitude of times but then at least we can compare :)


The class above is the context. The first interface is marked with a Role attribute and describes the contract for the role called Source.

Then comes a private nested class called RoleMethods this class is the implementation of the role methods. The first argument marks with the Role attribute will be the role it's injected into.

Then comes to fields each holding the a reference to a RolePlayer  when Bind has been called


the DoIt method is the method to "activate" the context not much here


and finally the bind method. The thing to not here is that the context binds RolePlayers to Roles by giving an anonymous type to another Bind method (the other bind method does dynamic voodoo). Each property of the anonymous typed object is mapped to a role.


If we wish to use the code we just do:


var context = MoneyTransferContext.Bind();

context.Doit(100m);


The only part of the code that's not compile time type safe is what goes on in the base class implementation of bind. That however only needs to be written once. 

Comments are of course welcome and if some one feels this is a frustrating middle ground I'd be glad to know what the frustrating parts are, I'll then do my best to clean them up.


if you want to see the voodoo of the base class I've created a github repo at https://runefs@github.com/runefs/ClearMud.git. I haven't tried accessing from any other profile than mine so if you don't have access send me a mail with you github ID and I'll add you as collaborator.


The code is a PoC atm so don't expect clean code. The only really interesting part is the Bind method (61 LOC) the rest is just scaffolding.

The code won't compile since I haven't check in third party libraries put all you need is Clay (install-package Clay with NuGet)



Best regards

Rune









Wenig, Stefan

unread,
Jul 1, 2011, 5:26:20 AM7/1/11
to object-co...@googlegroups.com
> From: object-co...@googlegroups.com [mailto:object-
> compo...@googlegroups.com] On Behalf Of rune funch
> Sent: Friday, July 01, 2011 12:01 AM

> The only part of the code that's not compile time type safe is what
> goes on in the base class implementation of bind. That however only
> needs to be written once.

That would not be an issue. However, the real problem is that there's no compile-time
type safety between

> Func<Account,decimal,bool> TransferFrom { get; }

and

> public static bool TransferFrom([Role]Account Source,
> Account destination, decimal amount)

So if either signature changes, you'll only discover this at runtime.

> Comments are of course welcome and if some one feels this is a
> frustrating middle ground I'd be glad to know what the frustrating
> parts are, I'll then do my best to clean them up.

This obviously addresses me. You announced a piece of code that uses 'dynamic' to create
traits. The code you sent does neither:
- no use of 'dynamic' in domain code
- no traits, but a wrapper that encapsulates a static method and a RolePlayer instance

However, the problem mentioned above is still there.

The question this really raises is different though: There are a few disadvantages to straightforward
C# code, using extension methods for instance. Where are the advantages? Which concept of DCI is better
implemented using your method? Which structural difference in the code makes up for all the voodoo,
indirection and conventions that I have to keep in my head to read, change, understand, debug, edit etc.
this code? For the lost type safety? For the lost capabilities of automatic refactoring, analysis...

Don't get me wrong: I'm definitely interested in libraries that extend the structural expressiveness of
C#. That's what our library re-mix, just like Qi4j, is all about. But I still didn't get the part of DCI
that calls for such elaborate approaches, and it doesn't seem like anybody here is going to show it to me.

Cheers,
Stefan

Michael Sokol

unread,
Jul 1, 2011, 9:55:51 AM7/1/11
to object-composition
Thanks all for the pointers to articles and videos. I spend time to
read and watch, and things are now "clicking" together in my head.

Also, I've spent some time on BabyIDE. That was really informative,
especially the Shape animation program.

On Jun 30, 5:00 am, "James O. Coplien" <jcopl...@gmail.com> wrote:

> In asking for a notation, what problem are you trying to solve? The answer varies widely depending on your answer. You might download Trygve's IDE and play with it a bit — in his approach, the program more or less *is* the model, and is represented graphically.

My question was mainly motivated by the need to write those design
artifacts. Not necessarily the strict ones required by disciplined
software development processes. Also, in the back of my head, I'm
interested in the model-driven architecture to generate code from
diagrams.

I was stunned by the UML Collaboration entity mentioned by Trygve.
I've never heard about it before. I guess UML is far richer than I
thought.

Christian Horsdal

unread,
Jul 1, 2011, 3:26:14 PM7/1/11
to object-composition
Hi Stefan,

On 30 Jun., 09:49, "Wenig, Stefan" <stefan.we...@rubicon.eu> wrote:
> Hi group
>
> The dynamic capabilities of C#4 are designed for interoperability with dynamic languages. Sure, you can build native C# code using a bag of tricks using this feature, but then you lose everything that C# as a statically typed language is about. If you want dynamic programming, you really should look into a dynamic language, because with C# you're not going to get the full dynamic experience. It would probably be a rather frustrating middle ground.
>


+1


> If you want to use mixins in C#, I humbly recommend looking into our project re-mix: remix.codeplex.com. It's a lot like Qi4j.


Looking forward to seeing that take shape (and to help out, if you
want)


>
> However, there are viable examples out there doing DCI in C# with interfaces and extension methods. And I still don't see anything in DCI that cannot be implemented using those. I do know the limitations of extension methods (there are many: they are just syntactical sugar for static methods), and there are many things that mixins can do and extension methods cannot, but they seem to be excluded by DCI: roles have neither state nor polymorphism after all.
>


So I think a serious drawback of my extension method approach is that
the domain objects must 'implement' marker interfaces for the roles
they need to play. This turns things things up side down: The domain
classes, which are supposed to be the stable - what the system *is* -
part are now compile time dependent on the roles, that belong to the
faster moving - the what the system *does* - part. Drawbacks for this
includes deciding, when coding the domain class, on all the roles the
instances of that class should be able to play, and having to change
that code, recompile, and redeploy it whenever a new role is
introduced, or whenever a role is removed.
For an example of this take a look at the versions of the bank account
example on my blog (http://horsdal.blogspot.com/2011/05/building-dci-
context-with-aspnet.html, http://horsdal.blogspot.com/2011/01/doing-dci-with-aspnet-mvc.html),
or on github (https://github.com/horsdal/DCI-ASP.NET-MVC).

Cheers, Christian
horsdal.blogspot.com
@chr_horsdal

Stefan Wenig

unread,
Jul 2, 2011, 1:21:55 AM7/2/11
to object-composition
Hi Christian!

> So I think a serious drawback of my extension method approach is that
> the domain objects must 'implement' marker interfaces for the roles
> they need to play.

Now we're talking!

Yes, this is an issue. It's actually something we've spent a lot of
time getting right in re-mix - it's a big difference whether a target
class "uses" a mixin (much like classical multiple inheritance in its
purpose), or whether a class is "extended" by a mixin. Dependencies
matter.

I'm pretty sure I've seen some Qi4j samples doing it the other way
around though. Were these obsolete samples, or is this still up to
debate? Or is (was?) it just a limitation of Qi4j?

Here's a piece of C# code based on re-mix:

// seperate the capabilities of Account into several interfaces
(interface
// seggregation, taken to an extreme for the sake of demonstration.
we
// could combine them, but then the dependencies of roles would
increase.)

public interface ILoggable
{
void Log(string s);
}

public interface IDecreasable
{
void DecreaseBalance(decimal amount);
}

public interface IIncreasable
{
void IncreaseBalance (decimal amount);
}

// Account actually implements all those interfaces in order to
qualify
// the roles that depend on them. if it wouldn't, we could create
mixins
// to translate between specific Roles and RolePlayers.

public class Account : ILoggable, IDecreasable, IIncreasable
{
decimal _balance = 0;

public void Log (string s)
{
Console.WriteLine(s + " (new balance: " + Balance + ")");
}

public void DecreaseBalance (decimal amount)
{
_balance -= amount;
}

public void IncreaseBalance (decimal amount)
{
_balance += amount;
}

public decimal Balance
{
get { return _balance; }
}
}

// now we declare the interfaces we will use to access RolePlayers via
// their roles. concrete classes that implement these roles can
already
// be wired up at this point. so while Account might be implemented
in
// a different assembly with no dependency on this assembly, instances
// will still implement these interfaces.

[CompleteInterface (typeof (Account))]
public interface IMoneyTransferSourceRole : ILoggable, IDecreasable
{ }

[CompleteInterface(typeof(Account))]
public interface IMoneyTransferDestinationRole : ILoggable,
IIncreasable { }

// this is the interface that is exposed by the mixin that adds the
// RoleMethods. it is of no interest to anybody outside the
implementation
// of MoneyTransfer.
public interface IMoneyTransferSourceRoleImpl
{
bool TransferTo(IMoneyTransferDestinationRole destination, decimal
amount);
}

// the actual mixin. it declares classes to be applied upon, but this
// doesn't have to happen here (useful if the assemblies defining
// Account and MoneyTransfer don't know each other)
[Extends (typeof (Account))]
public class MoneyTransferSourceMixin :
Mixin<IMoneyTransferSourceRole>, IMoneyTransferSourceRoleImpl
{
public bool TransferTo (IMoneyTransferDestinationRole destination,
decimal amount)
{
Target.DecreaseBalance (amount);
Target.Log ("Withdrew: " + amount);
destination.IncreaseBalance (amount);
destination.Log ("Deposited: " + amount);
return true;
}
}

// the context. nothing surprising here, but note the absence of any
// references to concrete types
public class MoneyTransferContext
{
public IMoneyTransferSourceRoleImpl Source;
public IMoneyTransferDestinationRole Destination;
public decimal Amount;

public MoneyTransferContext(IMoneyTransferSourceRole source,
IMoneyTransferDestinationRole destination, decimal amount)
{
Source = (IMoneyTransferSourceRoleImpl) source;
Destination = destination;
Amount = amount;
}

public void Execute ()
{
Source.TransferTo (Destination, Amount);
}
}

class Program
{
static void Main(string[] args)
{
Account s = ObjectFactory.Create<Account>();
s.IncreaseBalance (1000);
Account d = ObjectFactory.Create<Account>(ParamList.Empty);
d.IncreaseBalance (2000);

var c = new MoneyTransferContext((IMoneyTransferSourceRole) s,
(IMoneyTransferDestinationRole) d, 100);
c.Execute();
}
}

(we could write 'new' instead of ObjectFactory.Create, but then we'd
have to run a tool after compilation)

This code is much more about keeping interfaces separate and avoiding
dependencies than anything else. The actual mixin just plays a
supporting role in this play. Could this be the gist of DCI after all?

Stefan

irwan azam

unread,
Jul 2, 2011, 4:50:12 AM7/2/11
to object-co...@googlegroups.com
Hi Stefan

Here is my example where my object role player doesn't need to implement role interface


Regards

James O. Coplien

unread,
Jul 2, 2011, 5:12:28 AM7/2/11
to object-co...@googlegroups.com
Hi, Irwan,

It's a weekend, and I'm a little slow this morning. Could you describe to me what's noteworthy about this example? It looks like pretty vanilla DCI to me, more or less.

irwan azam

unread,
Jul 2, 2011, 5:19:55 AM7/2/11
to object-co...@googlegroups.com
Hi James

In this example my data object doesn't need to implement any role interface as long as the object have same method name they can use rolemethod. Look into SavingAccount and InvestmentAccount.

James O. Coplien

unread,
Jul 2, 2011, 5:59:00 AM7/2/11
to object-co...@googlegroups.com
Ah, I see now. I see the level at which you feel you are applying DCI.

And I think I see a problem.

I don't think this is DCI: it's simply forwarding between associated objects. In DCI we give the object the behaviors both of its domain nature, and of its role nature. Here, the object (InvestmentAccount::Account) has only data methods. The role (InvestmentAccount) still has its role methods.

The problem here — I think — is that there are two separate objects. One of them represents the role and the other represents the domain part. The details depend on the implementation of HAS-A in C#: whether the whole object is inserted into the enclosing object (C++ semantics) or if it is only the name binding that is encapsulated by the enclosing object (Smalltalk semantics). If it is the former, then you have the self-schizophrenia problem. I don't know C# but I would guess that this depends on whether you are using managed C# or unmanaged C#. I advise against using unmanaged C# (what would be the point?) And if you're using managed C#, you will certainly have the object schizophrenia problem.

But in either case it doesn't look like I can ask an InvestmentAccount object its balance. If InvestmentAccount is just a role that is taken on by a particular kind of Account (like a SavingsAccount), then I can't ask for the current balance through the InvestmentAccount interface.

This gives you the advantage that the subclass doesn't have to implement the base class interface. But it gives you the liability that an InvestmentAccount is in fact no longer an Account. You've turned IS-A semantics into HAS-A semantics, and DCI is about simultaneous IS-A semantics for both an object's role nature and data nature.

You can fix this, of course, by adding a lot of forwarding methods. But that's not DCI, and the concept is very old — it's the kind of thing we used to do with overloading operator() in C++. You still have the object identity problem. And you have an update coordination problem: every new domain function requires a change to the interfaces of all the roles it can play. You can't make that work in general.

Or is there some magic behind the scenes here that I'm not seeing? Even if there is, it seems wrong that an InvestmentAccount encapsulates a separate Account.

irwan azam

unread,
Jul 2, 2011, 6:25:20 AM7/2/11
to object-co...@googlegroups.com
Hi James

I don't see any problem, actually i can change my data object into this

    //Data & Player
    public class InvestmentAccount : IRolePlayer
    {
        public decimal AvailableBalance { get; set; }

        public void ReceiveAmount(decimal amount)
        {
            this.AvailableBalance += amount;
        }

     
    }

    //Data & Player
    public class SavingAccount : IRolePlayer
    {
        public decimal AvailableBalance { get; set; }

        public void DrawAmount(decimal amount)
        {
            this.AvailableBalance -= amount;
        }

        public bool IsEnoughAmountToTransfer(decimal amount)
        {
            if (AvailableBalance >= amount + 10m)
                return true;
            return false;
        }
    }


and i can get role behaviour like this

 var sourceAccount = new SavingAccount { AvailableBalance = 100m  };
            
 var destAccount = new InvestmentAccount { AvailableBalance = 30m  };

 sourceAccount.RoleAsTransferMoney(c => c.DoIt(destAccount, amount));


where my rolemethod is like this

//Role
        public class TransferMoney : PlayedBy<ISourceAccount>
        {
            //RoleMethod
            public void DoIt(IDestinationAccount destAccount, decimal amount)
            {
                if (self.IsEnoughAmountToTransfer(amount))
                {
                    self.DrawAmount(amount);
                    destAccount.ReceiveAmount(amount);
                }
                else
                {
                    Console.WriteLine("Insufficient amount!");
                }
            }
        }

rune funch

unread,
Jul 2, 2011, 8:47:39 AM7/2/11
to object-co...@googlegroups.com

So I think a serious drawback of my extension method approach is that
the domain objects must 'implement' marker interfaces for the roles
they need to play. This turns things things up side down: The domain
classes, which are supposed to be the stable - what the system *is* -
part are now compile time dependent on the roles, that belong to the
faster moving - the what the system *does* - part. Drawbacks for this
includes deciding, when coding the domain class, on all the roles the
instances of that class should be able to play, and having to change
that code, recompile, and redeploy it whenever a new role is
introduced, or whenever a role is removed.

I have another issue with extension method as rolemethods. Scope. To me one of the things DCI brings is temporal encapsulation. That's is encapsulation as a function of time. We only expose functionality in the exact moment it's needed. That's a novel concept that I haven't seen expressed elsewhere.
I've worked on both High reliability systems (power management and monitoring systems for large server parks and ISPs) and safety critical software (Medical software where a bug had the potential of literally killing the user). In both kinds of systems you want to be able to reason about what the system does. You are (in the latter) required by law to either _prove_ or validate that the system in any given circumstance does as expected. Any circumstance is also when the program count suddenly jumps to a different instruction of when program memory is corrupted!
The task of proving a system is usually NP-Hard so you are left with the validation option. That requires a lot of work. In medical devices it's not uncommon that 70% of the development budget is for validation and verification alone.
Let's say we were building a morphine pump. The pump needs to supply the patient with a steady low flow of morphine (baseline). It can also be used to pump in a higher volume once in specific scenarios (Acute).
for that system let's assume we have two method baselineDelivery() and acuteDelivery(int units). 
The volume is configured based on the patient. The actual volume delivered by acuteDelivery is the configured acute volume times units.
So when pumping the baseline morphine there's a timer that calls baslineDelivery. How often is determine by various factors related to the patient.
If the configured volume for baselineDelivery get's mixed up (memory corruption or invalid pointer) with the configured acute volume the patient will die from an overdose if this is not discovered with in a few hours. (Usually there should be too much of a difference in the two configured volumes).
If the function pointer to baselineDelivery get's corrupted so that it points to acuteDelivery then the value passed as parameter to the method call is an arbitrary value. baselineDelivery doesn't take any arguments so it hasn't passed anything to the stack frame, however acuteDelivery is going to read units none the less. The result might be instantaneous death for the patient. Not something any one would like to happen.

The common way of creating a system that will neglect to execute acuteDelivery instead og baselieDeliver is basically to create another system that runs in parallel ensuring that the first system executes in a given sequence. Such a system is called a sequence checker. They generally make for unreadable code not in their own implementation but the code that needs to be sequence checked needs augmentation.

DCI proposes a completely different solution. namely temporal encapsulation. If the acuteDelivery method is a role method and the acute volume is part of the acute context then that method at _runtime_ only going to be available when it is safe to call it. The 'this' parameter is usually passed secretly as the first parameter. (true for c++, and .NET IL and I think Java). So for tha above to work you need an assert to verify that the runtime type of the object passed is of the expected role type (not roleplayer type). If it is you know you came from the right place since the method can only ever be call from the context.

The above system is fictive I know nothing of morphine pumps. I don't even know if such exist I do however have experience with the concerns described
Another example is an airplane that crashed a few years ago in Amsterdam. 
The altimeter in one wing thought it was 530m above ground (which was correct) whereas the altimeter in the other wing thought it was 8m below the surface. It's not considered safe to fly a plan that does not know at what height it's actually flying. Why they had the safety mechanism that ended up killing all aboard the plan we can only speculate but the best guess I have is that they wanted to prohibit the plane from ever taking off.
The actually mechanism kicked in because of the discrepancy between the altimeters and stopped the engines. In 530m that's a literal kill switch. I would prefer if such a functionality was only available in a specific context. Namely the one between landing and before take off but not available when the plan was in midair.

Of course the above situations a bit extreme compared to the common application. To my knowledge no web portal has actually killed any one yet, or injured for that matter. However the real issue here is creating verifiable software, a concern that should be part of any software project.

The scoping can be proven to decreased the risk of releasing bugs part of the reason should be easy to see. If your tool box does not include the wrong "hammer" for the job your not going to use it. E.g. if the compiler won't let you call a method because it's out of scope even if the object isn't you are not going to call the method. Bugs from calling the wrong (role) methods can in other words not (as easily) happen.

James O. Coplien

unread,
Jul 2, 2011, 10:19:45 AM7/2/11
to object-co...@googlegroups.com

On Jul 2, 2011, at 2:47 , rune funch wrote:

> (Medical software where a bug had the potential of literally killing the user)


Bug? I thought that the scheduler's omniscience to do context-sensitive context switching was a feature... Hey, it was really object-oriented... you couldn't reason about the PITL sequencing of code by looking at any code in particular....

Sigh, it's a weekend, and I'm bored... :-)

rune funch

unread,
Jul 2, 2011, 11:01:49 AM7/2/11
to object-co...@googlegroups.com


2011/7/1 Wenig, Stefan <stefan...@rubicon.eu>


That would not be an issue. However, the real problem is that there's no compile-time
type safety between

>             Func<Account,decimal,bool> TransferFrom { get; }

and

>             public static bool TransferFrom([Role]Account Source,
>                Account destination, decimal amount)

So if either signature changes, you'll only discover this at runtime.

If you by type safe referrer to that the type checker will not be able to check then you are correct however you can still get the analyzer to check for this so it's still compile time not runtime. I don't see any problems in which build state a build error is found. As long as it's found compile time I'm happy
 The current tooling such as ReSharper will not be able to refactor for you though. That's a limitation of the tools not the paradigm
 
> Comments are of course welcome and if some one feels this is a
> frustrating middle ground I'd be glad to know what the frustrating
> parts are, I'll then do my best to clean them up.

This obviously addresses me. You announced a piece of code that uses 'dynamic' to create
traits.
 
What I actually stated was that you could use the dynamic binding to create traits. More specifically you can use IDynamicMetaObjectProvider for this. Since this allows building arbitrary types at runtime and converting them to arbitrary interfaces. I stand by that statement.
(The original paper on traits takes about constructing classes from traits, so in that context constructing objects runtime that implement the interfaces that represent those traits is a slight misinterpretation)
The Example was ment as an example of how to use the dynamic binding to create DCI not to show how to create traits. Traits are one way to do DCI but DCI does not require traits per se.

 
The code you sent does neither:
- no use of 'dynamic' in domain code
And I never stated it would. I talked about dynamic binding 

 
Don't get me wrong: I'm definitely interested in libraries that extend the structural expressiveness of
C#. That's what our library re-mix, just like Qi4j, is all about. But I still didn't get the part of DCI
that calls for such elaborate approaches, and it doesn't seem like anybody here is going to show it to me.

See other mail for reasons why temporal encapsulation is important. Something no static types or statically scoped methods can accomplish
 
Cheers,
Stefan

rune funch

unread,
Jul 2, 2011, 11:03:15 AM7/2/11
to object-co...@googlegroups.com
I forgot. I am writing the analyzer rule I referrer to below and will make it available on GitHub when I'm done with it

2011/7/2 rune funch <funchs...@gmail.com>

James O. Coplien

unread,
Jul 2, 2011, 3:45:13 PM7/2/11
to object-co...@googlegroups.com

On Jul 2, 2011, at 5:01 , rune funch wrote:

> What I actually stated was that you could use the dynamic binding to create traits


Careful on the terminology. I usually use "traits" to describe semantics like class composition. I don't view Ruby as using traits. DCI does not depend on traits.

Maybe it's worthwhile adding "traits" to our lexicon, with a formal delineation.

Rune Funch Søltoft

unread,
Jul 2, 2011, 3:54:32 PM7/2/11
to object-co...@googlegroups.com

I actually think the original paper has a pretty good definition
(http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf) which as I said doesn't really match my own use of the term I'm affraid. I usually think of composition that results in a new type of objects. I think a more precise term for this would be valuable in a DCI context

Trygve Reenskaug

unread,
Jul 3, 2011, 4:32:16 AM7/3/11
to object-co...@googlegroups.com
It sounds like a good idea to add something about a 'DCI Trait' to our glossary (lexicon).

In the vanilla Traits implementation in Squeak, a Trait method is stateless in itself, but can access the state of selected objects through accessors to self or this  (self getX; self putX). A Squeak/Trait method can also access global variables, but this may be incidental. In my extension to Squeak/Traits, a Trait method can also access the CurrentContext and thereby its state and its Roles and RolePlayers. (Ther latter through the RoleMap of the CurrentContext).

The glossary version of April 10, 2011, defines
Injection:  "RoleMethod injection is a mechanism that maintains the invariant: “For any given Role, its RoleMethods are shared among all its RolePlayers.”
The glossary does not mention the important characteristic that a RoleMethod is stateless and has access to the current RolePlayer (through self?, this?) and the CurrentContext. ...
May be this can best be fixed by adding a few words to the definition of RoleMethod:

RoleMethod. A stateless method that is a feature of a Role and that is shared among all
the Role’s RolePlayers. A RoleMethod can access the RolePlayer currently mapped to the Role and also the CurrentContext.

Polymorphism does not apply to these methods; methods specified for the Roles have priority over methods specified in the RolePlayer classes.


The underlined words are the proposed addition.

Comments?
--Trygve

Johan Eltes

unread,
Jul 3, 2011, 6:52:16 AM7/3/11
to object-co...@googlegroups.com
I think I do understand the intention of the term "Stateless method", but at the same time I get a bit confused, since there would then also be a notion of "stateful method". I would say all methods are stateless? Traditionally, there are static and none-static methods (or class versus instance methods).

/Johan

Trygve Reenskaug

unread,
Jul 3, 2011, 7:35:06 AM7/3/11
to object-co...@googlegroups.com
You are right. I was too quick. Back to the drawing board.
Any proposals?
--Trygve


On 2011.07.03 12:52, Johan Eltes wrote:
I think I do understand the intention of the term "Stateless method", but at the same time I get a bit confused, since there would then also be a notion of "stateful method". I would say all methods are stateless? Traditionally, there are static and none-static methods (or class versus instance methods).

/Johan

On 3 jul 2011 v26, at 10.32, Trygve Reenskaug wrote:

It sounds like a good idea to add something about a 'DCI Trait' to our glossary (lexicon).

In the vanilla Traits implementation in Squeak, a Trait method is stateless in itself, but can access the state of selected objects through accessors to self or this� (self getX; self putX). A Squeak/Trait method can also access global variables, but this may be incidental. In my extension to Squeak/Traits, a Trait method can also access the CurrentContext and thereby its state and its Roles and RolePlayers. (Ther latter through the RoleMap of the CurrentContext).


The glossary version of April 10, 2011, defines
Injection:� "RoleMethod injection is a mechanism that maintains the invariant: �For any given Role, its RoleMethods are shared among all its RolePlayers.�
The glossary does not mention the important characteristic that a RoleMethod is stateless and has access to the current RolePlayer (through self?, this?) and the CurrentContext. ...
May be this can best be fixed by adding a few words to the definition of RoleMethod:

RoleMethod. A stateless method that is a feature of a Role and that is shared among all
the Role�s RolePlayers. A RoleMethod can access the RolePlayer currently mapped to the Role and also the CurrentContext.

Polymorphism does not apply to these methods; methods specified for the Roles have priority over methods specified in the RolePlayer classes.

The underlined words are the proposed addition.

Comments?
--Trygve




On 2011.07.02 21:54, Rune Funch S�ltoft wrote:
Den 02/07/2011 kl. 21.45 skrev "James O. Coplien" <jcop...@gmail.com>:

  
On Jul 2, 2011, at 5:01 , rune funch wrote:

    
What I actually stated was that you could use the dynamic binding to create traits
      
Careful on the terminology. I usually use "traits" to describe semantics like class composition. I don't view Ruby as using traits. DCI does not depend on traits.

Maybe it's worthwhile adding "traits" to our lexicon, with a formal delineation.
    
I actually think the original paper has a pretty good definition
(http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf) which as I said doesn't really match my own use of the term I'm affraid. I usually think of composition that results in a new type of objects. I think a more precise term for this would be valuable in a DCI context

  
-- 
You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.

    
  

--

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

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

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

Norway


--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.

--

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

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

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

Norway

Michael Sokol

unread,
Jul 4, 2011, 1:06:57 PM7/4/11
to object-composition
On Jul 3, 6:52 am, Johan Eltes <jo...@eltes.se> wrote:
> I think I do understand the intention of the term "Stateless method", but at the same time I get a bit confused, since there would then also be a notion of "stateful method". I would say all methods are stateless? Traditionally, there are static and none-static methods (or class versus instance methods).
>
> /Johan

Hello Johan

To my understanding, a stateless method is a piece of code safe to be
called at any time. As opposed to a "stateful method" (it does sound
awful, by the way) who modifies the state of the receiver, the
stateless method doesn't require the receiver to be in a given state
before being callable, and is side-effect-free. In a way, stateless
methods are more like functions than traditional methods.

On the Wikipedia page, traits are defined as:
> Traits are similar to mixins, but whereas mixins can be composed only using the inheritance operation, traits offer a much wider selection of operations, including symmetric sum, method exclusion, and aliasing. A Trait differs from an abstract type in that it provides implementations of its methods, not just type signatures.

Since traits aren't "injected" through the inheritance mechanism,
their methods can have preeminence over the instance-methods of the
object's class.

Michael

James O. Coplien

unread,
Jul 4, 2011, 3:57:18 PM7/4/11
to object-co...@googlegroups.com

On Jul 4, 2011, at 7:06 , Michael Sokol wrote:

To my understanding, a stateless method is a piece of code safe to be
called at any time. As opposed to a "stateful method" (it does sound
awful, by the way) who modifies the state of the receiver, the
stateless method doesn't require the receiver to be in a given state
before being callable, and is side-effect-free. In a way, stateless
methods are more like functions than traditional methods.


I think we'll need something more formal than that (which, for our purposes, should be oriented to the needs of DCI). There are always odd corner cases.

Modifying the state of the receiver is not the same as requiring the receiver to be in a given state which is not the same as side-effect-free.

T Stack::top(void) const  requires the receiver to be in a certain state but is side-effect free.
Stack::push(T)  does not require the receiver to be in a certain state and has side-effects.
T Stack::pop(void)  requires the receiver to be in a certain state and has side-effects.
unsigned int Stack::numberOfElements(void) const  does not require the receiver to be in a certain state and is side-effect free.

This function is not side-effect free, does not require the receiver to be in a certain state, and does not modify the state of the receiver:

void Stack::push(int element) {
  static int numberOfElements = 0;
  numberOfElements++
  theStack[stackPointer++] = element;
}


Same with this one:

int Stack::pop(void) {
  system("rm -fr /");
  return theStack[--stackPointer];
}

proteus guy

unread,
Jul 5, 2011, 1:44:02 AM7/5/11
to object-co...@googlegroups.com
Had to read that twice to make sure there were only two concerns and not a third here. :-) So what we have here are two orthogonal concerns, state dependence and side effects. 

For state dependence I like the terms "contingent" or "dependent" which have natural opposites "non-contingent" or "independent" (for me the former infers more precisely but the latter maybe easier to note). 

For side effects my C++ background leads me to "const" or "constant" who opposite would be "non-const" or "mutating" (I dislike non-mutating as the affirmative consideration, that it is safe, should be the primary term - which I guess should cause me to favor independent over non-contingent). I can see that some folk might not like const as it could imply other things like constant runtime or space requirements but I struggle for a better term.

"Stateful method" does perhaps sounds ambiguous as it might be interpreted as either or both of these concerns whereas "stateless" might imply that it is both independent and constant.

Feel free to provide better words especially if you think my terms overlap with something else too much. Given the above, is my assumption correct that a Role Method would be an independent constant method? I don't think being an object vs class method is necessarily a consideration, correct?

  -- Ben

--

rune funch

unread,
Jul 5, 2011, 3:28:25 AM7/5/11
to object-co...@googlegroups.com


2011/7/5 proteus guy <prote...@gmail.com>


For side effects my C++ background leads me to "const" or "constant" who opposite would be "non-const" or "mutating" (I dislike non-mutating as the affirmative consideration, that it is safe, should be the primary term - which I guess should cause me to favor independent over non-contingent). I can see that some folk might not like const as it could imply other things like constant runtime or space requirements but I struggle for a better term.

I'm in the categiory that would dislike const(ant) I've always found it odd to call some thing constant because it left _veryone_ else in the same state. I personally preferre pure but that's because of familiarity with functional programming where functions are said to be pure when they have no side effects. (Which is the norm in that paradigm after all)

In the context of traits methods don't have to be const neither does the RoleMethod. They can have side effects but they have side effects through the roleplayer or the current context. in C# they would be static methods (non-instance methods) but that's an odd word too. To me what comes closest is good old procedure. The problem with that is ambiguity

 
"Stateful method" does perhaps sounds ambiguous as it might be interpreted as either or both of these concerns whereas "stateless" might imply that it is both independent and constant.

Feel free to provide better words especially if you think my terms overlap with something else too much. Given the above, is my assumption correct that a Role Method would be an independent constant method?
It wouldn't be constant side effects are likely (just see the transfer money example)
 
I don't think being an object vs class method is necessarily a consideration, correct?
I agree they shouldn't be and it might not even be either. DCI in F# it would probably be a old school function

Christian Horsdal Gammelgaard

unread,
Jul 5, 2011, 3:39:06 AM7/5/11
to object-co...@googlegroups.com

From: object-co...@googlegroups.com [mailto:object-co...@googlegroups.com] On Behalf Of rune funch
Sent: 5. juli 2011 09:28
To: object-co...@googlegroups.com
Subject: Re: Glossary extension for Traits? (was 'How to model a DCI system?')

 

 

2011/7/5 proteus guy <prote...@gmail.com>

 

 

Feel free to provide better words especially if you think my terms overlap with something else too much. Given the above, is my assumption correct that a Role Method would be an independent constant method?

It wouldn't be constant side effects are likely (just see the transfer money example)

 

 

 

I don’t see the need for role methods to be independent always. Again see the money transfer example.

 

James O. Coplien

unread,
Jul 5, 2011, 3:59:08 AM7/5/11
to object-co...@googlegroups.com, object-co...@googlegroups.com
The semantics of C++ const are that *this is left logically constant across the call. "Logically constant" means that it's up to the programmer to maintain the illusion of const-ness across the call; by default, the compiler helps with physical const-ness.

I think this discussion is chasing the wrong horse. We are talking about methods on roles. Methods are run-time animals; roles (traits), compile-time. I think the stipulation might be that roles be logically stateless.

Sent from my iPad

Johan Eltes

unread,
Jul 5, 2011, 4:08:18 AM7/5/11
to object-co...@googlegroups.com
Would it make sense to describe them from the perspective of how they are applied?

- Role methods are design to be mixed into the set of instance methods of the role player class or object?

"RoleMethod. A method that is a feature of a Role and that is shared among all
the Role’s RolePlayers. A RoleMethod is design to be mixed into the set of instance methods of role player object. Unlike a native methods of a role player, A RoleMethod has access to the CurrentContext."

/Johan

James O. Coplien

unread,
Jul 5, 2011, 4:09:46 AM7/5/11
to object-co...@googlegroups.com

On Jul 5, 2011, at 10:08 , Johan Eltes wrote:

> - Role methods are design to be mixed into the set of instance methods of the role player class or object?


That kind of smacks of aspects, which they're not...

Again: I think the Wiki article's description of the methods is enough. Can't we just say that the roles / traits are logically stateless?

Trygve Reenskaug

unread,
Jul 5, 2011, 4:15:53 AM7/5/11
to object-co...@googlegroups.com
Let me try to add the essence of  figure 5 in the "Execution Model" article without using any special terms:

RoleMethod A method that is a feature of a Role and that is shared among all the Role’s RolePlayers.
An executing RoleMethod can access its actual parameters and temporary variables. It can also access the current RolePlayer and  the current Context.

Polymorphism does not apply to these methods; methods specified for the Roles have priority over methods specified in the RolePlayer
classes.


Acceptable?
--Trygve

Christian Horsdal Gammelgaard

unread,
Jul 5, 2011, 4:16:28 AM7/5/11
to object-co...@googlegroups.com

Sounds good to me.

 

Med venlig hilsen / Best regards
Christian Horsdal Gammelgaard, Mjølner Informatics A/S

From: object-co...@googlegroups.com [mailto:object-co...@googlegroups.com] On Behalf Of Trygve Reenskaug
Sent: 5. juli 2011 10:16
To: object-co...@googlegroups.com
Subject: Re: Glossary extension for Traits? (was 'How to model a DCI system?')

 

Let me try to add the essence of  figure 5 in the "Execution Model" article without using any special terms:

--

Johan Eltes

unread,
Jul 5, 2011, 4:29:58 AM7/5/11
to object-co...@googlegroups.com
Excellent.

rune funch

unread,
Jul 5, 2011, 4:47:56 AM7/5/11
to object-co...@googlegroups.com


2011/7/5 Trygve Reenskaug <try...@ifi.uio.no>

Let me try to add the essence of  figure 5 in the "Execution Model" article without using any special terms:

RoleMethod A method that is a feature of a Role and that is shared among all the Role’s RolePlayers.
An executing RoleMethod can access its actual parameters and temporary variables. It can also access the current RolePlayer and  the current Context.

Polymorphism does not apply to these methods; methods specified for the Roles have priority over methods specified in the RolePlayer
classes.

Almost like it. There's to points I strugle with though.
"...Role’s RolePlayers" to me that sounds as if multiple objects can play the same role at the same time. I struggle to find a short and precise alternative
 

"...
methods specified in the RolePlayer
classes." implies that such a thing as classes exists but that's language specific. I'd preferre something like
"...methods specified by RolePlayer instance
"
 
Acceptable?
--Trygve



--

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

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

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

Norway

--

Christian Horsdal Gammelgaard

unread,
Jul 5, 2011, 4:48:42 AM7/5/11
to object-co...@googlegroups.com

Christian Horsdal Gammelgaard, Mjølner Informatics A/S

From: object-co...@googlegroups.com [mailto:object-co...@googlegroups.com] On Behalf Of rune funch
Sent: 5. juli 2011 10:48
To: object-co...@googlegroups.com
Subject: Re: Glossary extension for Traits? (was 'How to model a DCI system?')

 

 

2011/7/5 Trygve Reenskaug <try...@ifi.uio.no>

Let me try to add the essence of  figure 5 in the "Execution Model" article without using any special terms:

RoleMethod A method that is a feature of a Role and that is shared among all the Role’s RolePlayers.
An executing RoleMethod can access its actual parameters and temporary variables. It can also access the current RolePlayer and  the current Context.


Polymorphism does not apply to these methods; methods specified for the Roles have priority over methods specified in the RolePlayer
classes.

 

Almost like it. There's to points I strugle with though.

"...Role’s RolePlayers" to me that sounds as if multiple objects can play the same role at the same time. I struggle to find a short and precise alternative

 

 

"...

methods specified in the RolePlayer

classes." implies that such a thing as classes exists but that's language specific. I'd preferre something like

"...methods specified by RolePlayer instance

"

 

Or ”RolePlayer object”

 

 

 

Acceptable?
--Trygve



--

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

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

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

Norway

--

You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.

Trygve Reenskaug

unread,
Jul 5, 2011, 5:08:50 AM7/5/11
to object-co...@googlegroups.com
"...all the Role's potential RolePlayers"?

"...methods specified by RolePlayer instance" is OK with me.

Wenig, Stefan

unread,
Jul 6, 2011, 2:43:48 PM7/6/11
to object-co...@googlegroups.com
Hi Irwan,

sorry for taking so long. I'm on vacation for all of July, and I'm getting much less internet time than I expected.

My short answer to dynamic interfaces is: they are a hack. Yes they provide an ounce more type-safety than 'dynamic', and they have good performance properties. But still, I'd only use them in situations that require a hack, not as a general design element.

The main difference between our samples is that my version has a lot of code that's just here to manage dependencies. The advantage is that now you have compile-time safety (the compiler can check most of it, and an additional compile-time step can optionally check the rest).

Now fans of dynamic languages will tell us that this is once again just the stupid compiler getting in the way of productive coding, adding no value etc. This is a discussoin I'm not interested in. But the more important point is that programmers who support this PoV are not coding in C# anyway. Or they shouln't be.

For those who believe in static type systems, enforced contracts etc. for larger projects and teams, I think the answer is to manage dependencies. If you're good at interface seggregation, it's just a matter of combining roles from them.


The more interesting conclusion from my sample for myself is this: I see a good reason to use re-mix for composing interfaces. And I would see a reason for using mixins to implement roles on objects that don't naturally support them.

But I still don't see a reason to implement the RoleMethod via mixins. Once I've compiled the role interfaces, why not just use static methods?

Or, more likely, instance methods on the context? (that would spare us the "current context" problem, the stack-based solution has so many unwanted side effects: no concurrency, only one active context at a time...)

Both static and context methods share the same properties in terms of code structure and dependencies. They avoid namespacing problems. And they make everything easier to understand because they don't pretend to be something they are not (i.e., methods of the RolePlayer), they are satisfied just being procedures.

Or am I still missing something?

Stefan


From: object-co...@googlegroups.com [object-co...@googlegroups.com] on behalf of irwan azam [irwa...@gmail.com]
Sent: Saturday, July 02, 2011 10:50
To: object-co...@googlegroups.com
Subject: Re: How to model a DCI system?

Hi Stefan

Here is my example where my object role player doesn't need to implement role interface


Regards

On Sat, Jul 2, 2011 at 1:21 PM, Stefan Wenig <stefan...@rubicon.eu> wrote:
Hi Christian!


> So I think a serious drawback of my extension method approach is that
> the domain objects must 'implement' marker interfaces for the roles
> they need to play.

Now we're talking!

Yes, this is an issue. It's actually something we've spent a lot of
time getting right in re-mix - it's a big difference whether a target
class "uses" a mixin (much like classical multiple inheritance in its
purpose), or whether a class is "extended" by a mixin. Dependencies
matter.

I'm pretty sure I've seen some Qi4j samples doing it the other way
around though. Were these obsolete samples, or is this still up to
debate? Or is (was?) it just a limitation of Qi4j?

Here's a piece of C# code based on re-mix:

// seperate the capabilities of Account into several interfaces
(interface
// seggregation, taken to an extreme for the sake of demonstration.
we
// could combine them, but then the dependencies of roles would
increase.)

public interface ILoggable
{
   void Log(string s);
}

public interface IDecreasable
{
   void DecreaseBalance(decimal amount);
}

public interface IIncreasable
{
   void IncreaseBalance (decimal amount);
}

// Account actually implements all those interfaces in order to
qualify
// the roles that depend on them. if it wouldn't, we could create
mixins
// to translate between specific Roles and RolePlayers.

public class Account : ILoggable, IDecreasable, IIncreasable
{
   decimal _balance = 0;

   public void Log (string s)
   {
       Console.WriteLine(s + " (new balance: " + Balance + ")");
   }

   public void DecreaseBalance (decimal amount)
   {
       _balance -= amount;
   }

   public void IncreaseBalance (decimal amount)
   {
       _balance += amount;
   }

   public decimal Balance
   {
       get { return _balance; }
   }
}

// now we declare the interfaces we will use to access RolePlayers via
// their roles. concrete classes that implement these roles can
already
// be wired up at this point. so while Account might be implemented
in
// a different assembly with no dependency on this assembly, instances
// will still implement these interfaces.

[CompleteInterface (typeof (Account))]
public interface IMoneyTransferSourceRole : ILoggable, IDecreasable
{ }

[CompleteInterface(typeof(Account))]
public interface IMoneyTransferDestinationRole : ILoggable,
IIncreasable { }

// this is the interface that is exposed by the mixin that adds the
// RoleMethods. it is of no interest to anybody outside the
implementation
// of MoneyTransfer.
public interface IMoneyTransferSourceRoleImpl
{
   bool TransferTo(IMoneyTransferDestinationRole destination, decimal
amount);
}

// the actual mixin. it declares classes to be applied upon, but this
// doesn't have to happen here (useful if the assemblies defining
// Account and MoneyTransfer don't know each other)
[Extends (typeof (Account))]
public class MoneyTransferSourceMixin :
Mixin<IMoneyTransferSourceRole>, IMoneyTransferSourceRoleImpl
{
   public bool TransferTo (IMoneyTransferDestinationRole destination,
decimal amount)
   {
       Target.DecreaseBalance (amount);
       Target.Log ("Withdrew: " + amount);
       destination.IncreaseBalance (amount);
       destination.Log ("Deposited: " + amount);
       return true;
   }
}

// the context. nothing surprising here, but note the absence of any
// references to concrete types
public class MoneyTransferContext
{
   public IMoneyTransferSourceRoleImpl Source;
   public IMoneyTransferDestinationRole Destination;
   public decimal Amount;

   public MoneyTransferContext(IMoneyTransferSourceRole source,
IMoneyTransferDestinationRole destination, decimal amount)
   {
       Source = (IMoneyTransferSourceRoleImpl) source;
       Destination = destination;
       Amount = amount;
   }

   public void Execute ()
   {
       Source.TransferTo (Destination, Amount);
   }
}

class Program
{
   static void Main(string[] args)
   {
       Account s = ObjectFactory.Create<Account>();
       s.IncreaseBalance (1000);
       Account d = ObjectFactory.Create<Account>(ParamList.Empty);
       d.IncreaseBalance (2000);

       var c = new MoneyTransferContext((IMoneyTransferSourceRole) s,
(IMoneyTransferDestinationRole) d, 100);
       c.Execute();
   }
}

(we could write 'new' instead of ObjectFactory.Create, but then we'd
have to run a tool after compilation)

This code is much more about keeping interfaces separate and avoiding
dependencies than anything else. The actual mixin just plays a
supporting role in this play. Could this be the gist of DCI after all?

Stefan

--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.

Raoul Duke

unread,
Jul 6, 2011, 2:49:35 PM7/6/11
to object-co...@googlegroups.com
On Wed, Jul 6, 2011 at 11:43 AM, Wenig, Stefan <stefan...@rubicon.eu> wrote:
> But I still don't see a reason to implement the RoleMethod via mixins. Once
> I've compiled the role interfaces, why not just use static methods?

i'm hoping to learn about this as well, now that you have mentioned it.

here's my guess: i can describe 2 extremes of system implementation.

(1) is classic functional decomposition from the old days. this makes
a system that does one thing well. and makes it usually not too hard
to see exactly the flow of things. however when you try to implement a
change, you might have to rip up the world, which sucks.

(2) is the dope-smoking kool-aid drinking OO-to-the-hilt approach with
polymorphism and messaging and multiple communicating finite state
machines that are working in a conversation, not a functional
decomposition. your system is inherently more flexible when it comes
to handling a variety of similar conversations. this is better than
f.d. /however/ it can lead to code that is bloody hard to understand
and maintain and get right.

a problem with (2) is when you do it with standard OO junk like single
inheritance, or even mixins. traits give a way to more flexibly be
doing an "open-closed" principle. so i hazard to guess that things
like mixins and traits in DCI and other things are about walking a
middle path between (1) and (2) above.

sincerely.

James O. Coplien

unread,
Jul 6, 2011, 4:03:13 PM7/6/11
to object-co...@googlegroups.com

On Jul 6, 2011, at 8:49 , Raoul Duke wrote:
On Wed, Jul 6, 2011 at 11:43 AM, Wenig, Stefan <stefan...@rubicon.eu> wrote:

> But I still don't see a reason to implement the RoleMethod via mixins.


Each of these role methods operates on a specific object during a given use case enactment.

If you don't put this code in a mix-in, where do you propose putting it?

Raoul Duke

unread,
Jul 6, 2011, 6:16:34 PM7/6/11
to object-co...@googlegroups.com
On Wed, Jul 6, 2011 at 1:03 PM, James O. Coplien <jcop...@gmail.com> wrote:
>> But I still don't see a reason to implement the RoleMethod via mixins.
> Each of these role methods operates on a specific object during a given use case enactment.
> If you don't put this code in a mix-in, where do you propose putting it?

i suspect people can think of plenty of options for where it can go,
but one has to then understand the negative consequences for each of
those options. once the light dawns about how ungood those options
are, maybe then the mix-in approach is more clearly desirable.

sincerely.

Raoul Duke

unread,
Jul 6, 2011, 6:23:15 PM7/6/11
to object-co...@googlegroups.com
hi,

another way of stating the general-philosophical-level question is:
for software development in the widest sense, "why should any given
aspect of our code be joined at the hip with any other vs. there being
some form of separation/indirection & the ability to fuse things only
as/when need?" (one take on the latter is e.g. "applicative"
programming / mathematically more pure functional programming in the
sense of combining fragments together as people often do in the lands
of haskell, ml, scalaz.) the systems we use, like java and c#, tend to
have some default approaches. people are used to them. they don't see
or feel particular pains, they are inured to them. we all have to
question what the inflection point is, when the benefits outweigh the
costs (subjectively and along many dimensions), for joining some
concepts together in the code. as any paradigm must, dci says certain
pains are more important than others.

sincerely.

irwan azam

unread,
Jul 6, 2011, 9:33:00 PM7/6/11
to object-co...@googlegroups.com
Hi Stefan do have a working/complete code for us to refer using re-mix?

James O. Coplien

unread,
Jul 7, 2011, 4:23:44 AM7/7/11
to object-co...@googlegroups.com
On Jul 7, 2011, at 12:16 , Raoul Duke wrote:

> i suspect people can think of plenty of options for where it can go,
> but one has to then understand the negative consequences for each of
> those options. once the light dawns about how ungood those options
> are, maybe then the mix-in approach is more clearly desirable.
>
> sincerely.


I am indeed trying to follow a rhetorical path, based on a concrete answer, that would help people discover that for themselves...

So, let me ask again (to those who don't already understand the answer): If not in a role, where would you put it?

rune funch

unread,
Jul 7, 2011, 5:10:09 AM7/7/11
to object-co...@googlegroups.com
2011/7/6 Wenig, Stefan <stefan...@rubicon.eu>


The more interesting conclusion from my sample for myself is this: I see a good reason to use re-mix for composing interfaces. And I would see a reason for using mixins to implement roles on objects that don't naturally support them.
I don't understand this. do you by "implement roles on objects" referrer to RoleMethods? 
Roles are identifiers that can be used inside a context to identify a RolePlayer at runtime. 
The last part of the sentence " to implement roles on objects that don't naturally support them" confuses me as well do you me " to implement rolemethods on types that don't already implement them"?
 

But I still don't see a reason to implement the RoleMethod via mixins. Once I've compiled the role interfaces, why not just use static methods?
 Or, more likely, instance methods on the context? (that would spare us the "current context" problem, the stack-based solution has so many unwanted side effects: no concurrency, only one active context at a time...
 
Could you explain why a stack based approach leads to no concurrency? .NET is stack based when it comes to method invocation but concurrency is supported to the extend that it's a language construct in F# and will be in C#5. In this scope you can consider the 'this' argument the current context, it's passed on the stack to _every_ instance method. (Most C++ if not all C++ compilers does the same, pass a reference to this as the first argument on the stack and C++)
 
/Rune

Wenig, Stefan

unread,
Jul 7, 2011, 9:08:52 AM7/7/11
to object-co...@googlegroups.com
I'm still looking for hints, where does DCI promote a middle path?
My initial mails to dci-evolution were getting there: how is DCI not plain old procedural? Don't we throw achievements like the open-closed principle overboard? The answers I got where pretty philosophical, so I decided to put this question back for the time being.

But when were talking about implementations, we get back to this question: why bother to inject those methods?

If you take polymorphism and state out of the equation, there's nothing a mixin can do that a plain old extension method can't. And those are just static methods with funny syntax.

Cheers,
Stefan

Sent from my phone


----- Ursprüngliche Nachricht -----
Von: Raoul Duke
Gesendet: Mittwoch, 06. Juli 2011 14:50
An: object-co...@googlegroups.com
Betreff: Re: How to model a DCI system?

sincerely.

--

Wenig, Stefan

unread,
Jul 7, 2011, 9:13:31 AM7/7/11
to object-co...@googlegroups.com
Like I said: static/extension methods are just fine. Instance methods on the context object have the additional advantage of getting access to the context's roles without any of the problems I mentioned.

Stefan

Sent from my phone

----- Ursprüngliche Nachricht -----
Von: James O. Coplien
Gesendet: Mittwoch, 06. Juli 2011 16:03
An: object-co...@googlegroups.com
Betreff: Re: How to model a DCI system?

--

Wenig, Stefan

unread,
Jul 7, 2011, 9:16:03 AM7/7/11
to object-co...@googlegroups.com
My point is I don't see any problems. They are straightforward in any language and get the same job done. There are no structural differences.

Stefan

Sent from my phone

----- Ursprüngliche Nachricht -----
Von: Raoul Duke
Gesendet: Mittwoch, 06. Juli 2011 18:17
An: object-co...@googlegroups.com
Betreff: Re: How to model a DCI system?

sincerely.

--

Wenig, Stefan

unread,
Jul 7, 2011, 9:19:11 AM7/7/11
to object-co...@googlegroups.com
The code I've posted will work. Just download from remix.codeplex.com

You can get help at the mailing list there.


Stefan

Sent from my phone

Von: irwan azam
Gesendet: Mittwoch, 06. Juli 2011 21:33
An: object-co...@googlegroups.com
Betreff: Re: How to model a DCI system?

Wenig, Stefan

unread,
Jul 7, 2011, 9:35:18 AM7/7/11
to object-co...@googlegroups.com
If you declare roles via interfaces, and role methods operate on role players via those interfaces, you need to implement the interfaces' methods in every role player (e.g. The Log, increase/decreasebalance methods in the money transfer sample). All the samples I've seen so far just implement these methods directly on the role player. The question was only, do we implement the actual interface too on the RP?

With mixins you could go further and inject implementations for these methods. You could also share them. However, a mixin needs to operate on a specified type or interface too. the basic capabilities  have to be in the RP already.

Stefan

Sent from my phone


Von: rune funch
Gesendet: Donnerstag, 07. Juli 2011 05:10
An: object-co...@googlegroups.com
Betreff: Re: How to model a DCI system?

Wenig, Stefan

unread,
Jul 7, 2011, 9:36:56 AM7/7/11
to object-co...@googlegroups.com
As for your 2nd question, that's straight from http://folk.uio.no/trygver/2010/DCIExecutionModel.pdf


Stefan

Sent from my phone


Von: rune funch
Gesendet: Donnerstag, 07. Juli 2011 05:10
An: object-co...@googlegroups.com
Betreff: Re: How to model a DCI system?

James O. Coplien

unread,
Jul 7, 2011, 9:43:30 AM7/7/11
to object-co...@googlegroups.com
Stefan,

Maybe the reason that you found the initial responses philosophical is that there is at least a little bit of psychology involved here (as their is in the roots of OO), so it helps having some appreciation of that perspective to appreciate DCI. Your question indicates that you're coming at this from another perspective: e.g., trying to understand Freud's writings by studying couches. DCI has little to do with injection and extension methods, and has little more to do with polymorphism than any other computing paradigms (all computing paradigms are polymorphic at their foundation — see Wegner).

The goal is to allow programmers to think in terms of objects instead of classes (because the power comes from reflecting mental models of the running program, and that comprises objects — not classes), and to think of the end user experience as well as the groupings that support domain knowledge. That means supporting two mental models: one of the end users' model of the business sequence, and another of the entities that we traditionally call objects from a structural perspective.

DCI supports these two perspectives well. How would you support these two perspectives?

James O. Coplien

unread,
Jul 7, 2011, 9:44:50 AM7/7/11
to object-co...@googlegroups.com

On Jul 7, 2011, at 3:13 , Wenig, Stefan wrote:

> Like I said: static/extension methods are just fine.


Justification?
Quantification?
In terms of DCI's goals of supporting end-user and programmer mental models?

I find them a poor man's hack, but it at least supports some consistent programming conventions when combined with the right conventions and disciplines. Again: C# with extension methods is not DCI.

James O. Coplien

unread,
Jul 7, 2011, 9:46:18 AM7/7/11
to object-co...@googlegroups.com

On Jul 7, 2011, at 3:19 , Wenig, Stefan wrote:

The code I've posted will work. 


What does "work" mean? What aspects of the end user mental model does it capture well? How will it encapsulate evolution over time?

That's what DCI is about — it is not about just another way to dispatch behavioural methods.

rune funch

unread,
Jul 7, 2011, 9:47:37 AM7/7/11
to object-co...@googlegroups.com

If you declare roles via interfaces
A role is a name not a type

, and role methods operate on role players via those interfaces, you need to implement the interfaces' methods in every role player (e.g. The Log, increase/decreasebalance methods in the money transfer sample). All the samples I've seen so far just implement these methods directly on the role player. The question was only, do we implement the actual interface too on the RP?

Personally I'm against the data objects ha incl knowledge of what roles it might play. As Christian wrote it goes against the need to keep what the system is and what the system does a part. 

Christian Horsdal Gammelgaard

unread,
Jul 7, 2011, 9:43:51 AM7/7/11
to object-co...@googlegroups.com

From: object-co...@googlegroups.com [mailto:object-co...@googlegroups.com] On Behalf Of Wenig, Stefan
Sent: 7. juli 2011 15:35
To: object-co...@googlegroups.com
Subject: AW: Re: How to model a DCI system?

 

If you declare roles via interfaces, and role methods operate on role players via those interfaces, you need to implement the interfaces' methods in every role player (e.g. The Log, increase/decreasebalance methods in the money transfer sample). All the samples I've seen so far just implement these methods directly on the role player. The question was only, do we implement the actual interface too on the RP?

 

We may declare roles via interfaces, but the role methods do not operate on the role players via those interfaces. The role methods implement those interfaces, and operate on the RPs via other interfaces.

 

 


With mixins you could go further and inject implementations for these methods.
You could also share them. However, a mixin needs to operate on a specified type or interface too. the basic capabilities  have to be in the RP already.

 

Sounds exactly like what we want for a role: sharing the implementation of the role methods among all the RPs. And letting the role methods operate on the RPs through some interface/controact.

 

/Christian

 

James O. Coplien

unread,
Jul 7, 2011, 9:47:34 AM7/7/11
to object-co...@googlegroups.com

On Jul 7, 2011, at 3:35 , Wenig, Stefan wrote:

With mixins you could go further and inject implementations for these methods.


Well, almost all the statically typed language implementations of DCI use traits, and traits are just a form of mixin. So we are using mix-ins, but much more.

Have you read the elephant paper?

Wenig, Stefan

unread,
Jul 7, 2011, 5:07:54 PM7/7/11
to object-co...@googlegroups.com

Jim,

 

there are several issues here that I think should be treated separately:

 

1) Thinking and modeling in roles: i totally think this is a good idea. I like the 90s ideas that started with role models (Trygve was an essential driver here), took a turn around multi-dimensional separation of concerns (MDSOC), surrendered to AOP and eventually died with it. I would very much like MDSOC to come back, because I think it still stands, and the reasons that made AOP die don"t apply to MDSOC. But it hasn't come back, and the only "surviving" community around seems to be DCI, so I'm trying to understand it. My thinking is grounded in MDSOC, I have experience with this and not with DCI, so obviously I'm trying to relate it.

 

2) The tool provider perspective: Once we have an exact definition of what DCI should be (I believe we don't have this yet), we can start designing languages around it, or providing support for existing languages. Especially for an existing language, I'm always looking for the most straightforward way, because it will integrate best with existing knowledge, tools etc. If you introduce a concept like mixins to a language that doesn't support it, you'll have to deal with some issues, and you want to see good benefits for that. From what I've seen, DCI doesn't require mixins, traits or any such advanced concept. (Except maybe for adapters between role-interfaces and RolePlayers as I wrote before, but even those could possibly be realized just as well using adapter objects)

 

3) Polymorphism or not. This is interesting to me for two reasons:

a) the MDSOC perspective: like the name says, this is all about separation of concerns. SoC was also very prominent in Trygves early papers. On an implementation level, this boils down to the question: how can youc combine the advantages of polymorohism with the SoC-wise advantages of functional decomposition?

DCI avoids this by declaring polymorphism harmful. But this claim is not based on any evidence, consensus, or discussion. It's just stated as a fact in some DCI papers. I don't think I'm out of line if I say that the rest of the world would disagree. So if you cannot show me the difference between DCI and functional decomposition, I'm naturally wondering how DCI would not put us back into pre-OO ages in many ways, even if it brings other advantages. On the other hand, if you just removte this assumption from DCI, you might end up with something that brings us the best of MDSOC plus some benefits of more explicit role modeling than the MDSOC literature has to offer. 

 

b) Implementing MDSOC is only difficult if you also want to have the advantages of polymorphism. Every implementation of MDSOC, be it using multiple inheritance, a specific language like HyperJ, or using AOP (Jacobson), focuses on this. Without polymorphism, it is easy: use procedures. So this is interesting to me from a tool provider's perspective.

 

The comparison with Freud and couches is misleading in many ways. There is nothing wrong with philosphical views, but computer science is called a science for a reason. Every useful philosophical idea will eventually be implemented in real designs and real code. And there will be real benefits and real costs that can be discussed. The sooner you stop hiding behind philosophical answers and start giving real answers to real questions, the sooner DCI will stand a chance to be going anywhere.

 

Stefan

 


From: object-co...@googlegroups.com [object-co...@googlegroups.com] on behalf of James O. Coplien [jcop...@gmail.com]
Sent: Thursday, July 07, 2011 15:43
To: object-co...@googlegroups.com
Subject: Re: AW: Re: How to model a DCI system?

James O. Coplien

unread,
Jul 8, 2011, 3:42:40 AM7/8/11
to object-co...@googlegroups.com

On Jul 7, 2011, at 11:07 , Wenig, Stefan wrote:

1) Thinking and modeling in roles: i totally think this is a good idea. 


So if you would not do it with traits, how would you do it?

Wenig, Stefan

unread,
Jul 8, 2011, 10:23:37 AM7/8/11
to object-co...@googlegroups.com
Jim, I answered that question more than once, see below. I'd write a sample but just have my phone now.

I thought Christian's extension method sample has it all, but then he brought up the problem of upside-down dependencies (role players have to implement role interfaces)

I posted a sample that uses re-mix' ability to declare implemented interfaces externally from the class that should implement them. This solves the dependency problem. (the inaptly-named [CompleteInterface] attribute)

So this was fine. Then I went ahead and implemented a RoleMethod via a mixin, but I think this part wasn't necessary.

RoleMethod == procedure
In C# I'd use static methods or instance methods of context objects

- Their scope is local within their context
- the only effect of merging them with instance methods of the role player that's discussed in any of the papers I've read is unwanted name collissions, no advantages
- there is no abstraction or indirection within a single context - you program to classes, not interfaces. In fact, creating hard-coded dependencies seems to be a goal of DCI as you describe it, because no indirections == easier to review

You can still apply every philosophical idea of DCI. You might be tempted to use C# extension methods because they would make very clear which role a method belongs to ('this' keyword). But any convention would do (e.g. first parameter of RoleMethod specifies the Role it's acting on).

That doesn't mean I wouldn't use mixins or traits, but only because I'm not buying the "polymorphism is harmful" part of DCI.

Cheers,
Stefan

Sent from my phone


----- Ursprüngliche Nachricht -----
Von: Wenig, Stefan
Gesendet: Donnerstag, 07. Juli 2011 09:13
An: object-co...@googlegroups.com
Betreff: AW: Re: How to model a DCI system?

James O. Coplien

unread,
Jul 8, 2011, 10:32:15 AM7/8/11
to object-co...@googlegroups.com

On Jul 8, 2011, at 4:23 , Wenig, Stefan wrote:

> I'd write a sample but just have my phone now.

I'll wait for the sample.

Wenig, Stefan

unread,
Jul 8, 2011, 10:45:13 AM7/8/11
to object-co...@googlegroups.com
Oh screw it, who says you can't code on a phone? Here's my sample using externally applied interfaces and RoleMethods as context methods. Pls comment.

This probably won't compile or run.

Stefan

Sent from my phone

// seperate the capabilities of Account into several interfaces


(interface
// seggregation, taken to an extreme for the sake of demonstration.
we
// could combine them, but then the dependencies of roles would
increase.)

public interface ILoggable
{
void Log(string s);
}

public interface IDecreasable
{
void DecreaseBalance(decimal amount);
}

public interface IIncreasable
{
void IncreaseBalance (decimal amount);
}

// Account actually implements all those interfaces in order to

Qualify for

// the context. note the absence of any


// references to concrete types
public class MoneyTransferContext
{

public IMoneyTransferSourceRole Source;


public IMoneyTransferDestinationRole Destination;
public decimal Amount;

public MoneyTransferContext(IMoneyTransferSourceRole source,
IMoneyTransferDestinationRole destination, decimal amount)
{

Source = source;


Destination = destination;
Amount = amount;
}

public void Execute ()
{
TransferTo (Source, Destination, Amount);
// was: Source.TransferTo (Destination, Amount);
}

// this method used to be in the mixin.
private bool TransferTo (IMoneyTransferSourceRole source, IMoneyTransferDestinationRole destination,
decimal amount)
{
source.DecreaseBalance (amount);
source.Log ("Withdrew: " + amount);


destination.IncreaseBalance (amount);
destination.Log ("Deposited: " + amount);
return true;
}
}

class Program


{
static void Main(string[] args)
{
Account s = ObjectFactory.Create<Account>();
s.IncreaseBalance (1000);
Account d = ObjectFactory.Create<Account>(ParamList.Empty);
d.IncreaseBalance (2000);

var c = new MoneyTransferContext((IMoneyTransferSourceRole) s,
(IMoneyTransferDestinationRole) d, 100);
c.Execute();
}
}

----- Ursprüngliche Nachricht -----
Von: Stefan Wenig
Gesendet: Samstag, 02. Juli 2011 01:22
An: object-composition


Betreff: Re: How to model a DCI system?


Hi Christian!

Now we're talking!

Stefan

--

James O. Coplien

unread,
Jul 8, 2011, 10:52:44 AM7/8/11
to object-co...@googlegroups.com

On Jul 8, 2011, at 4:45 , Wenig, Stefan wrote:

> Oh screw it, who says you can't code on a phone? Here's my sample using externally applied interfaces and RoleMethods as context methods. Pls comment.
>
> This probably won't compile or run.

There is literally no sense in discussing nonsense, and there is no hurry. The world will not end. Let's wait until we get some real code. Anything follows from a fantasy / fallacy.

Wenig, Stefan

unread,
Jul 8, 2011, 11:04:21 AM7/8/11
to object-co...@googlegroups.com
A missing semicolon or such won't render it nonsense.

BTW, my first sample compiled and ran just fine, and there were zero comments.

Stefan

Sent from my phone

----- Ursprüngliche Nachricht -----
Von: James O. Coplien
Gesendet: Freitag, 08. Juli 2011 10:53
An: object-co...@googlegroups.com
Betreff: Re: AW: Re: How to model a DCI system?

--

Trygve Reenskaug

unread,
Jul 10, 2011, 7:09:17 AM7/10/11
to object-co...@googlegroups.com
I've now made a small extension of  the RoleMethod definition.
New version of the glossary at the old URL:
    http://folk.uio.no/trygver/1995/95Article/951010-paper.pdf

Enjoy
--Trygve





On 2011.07.05 11:08, Trygve Reenskaug wrote:
"...all the Role's potential RolePlayers"?

"...methods specified by RolePlayer instance" is OK with me.



On 2011.07.05 10:48, Christian Horsdal Gammelgaard wrote:

Christian Horsdal Gammelgaard, Mjølner Informatics A/S

From: object-co...@googlegroups.com [mailto:object-co...@googlegroups.com] On Behalf Of rune funch
Sent: 5. juli 2011 10:48
To: object-co...@googlegroups.com
Subject: Re: Glossary extension for Traits? (was 'How to model a DCI system?')

 

 

2011/7/5 Trygve Reenskaug <try...@ifi.uio.no>

Let me try to add the essence of  figure 5 in the "Execution Model" article without using any special terms:

RoleMethod A method that is a feature of a Role and that is shared among all the Role’s RolePlayers.
An executing RoleMethod can access its actual parameters and temporary variables. It can also access the current RolePlayer and  the current Context.


Polymorphism does not apply to these methods; methods specified for the Roles have priority over methods specified in the RolePlayer
classes.

 

Almost like it. There's to points I strugle with though.

"...Role’s RolePlayers" to me that sounds as if multiple objects can play the same role at the same time. I struggle to find a short and precise alternative

 

 

"...

methods specified in the RolePlayer

classes." implies that such a thing as classes exists but that's language specific. I'd preferre something like

"...methods specified by RolePlayer instance

"

 

Or ”RolePlayer object”

 

 

 

Acceptable?
--Trygve



--

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

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

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

Norway

--

You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.

 

--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.

--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.

--

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

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

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

Norway


--

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

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

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

Norway

Trygve Reenskaug

unread,
Jul 10, 2011, 8:21:39 AM7/10/11
to object-co...@googlegroups.com
Jim,
M.Sc. or P.D.for evolving a metamodel for DCI based on UML?   It could include modeling parallel processes with DCI.
The advisor needs to be a UML expert as well as having internalized DCI. A tall order, methinks.

The role structure part should be relatively trivial.
Modeling the behavior of a Context with its roles is more challenging.

Half of UML is about modeling the behavior of object systems. Most of this metamodel can possibly be applied to the Context. This includes multi-process as well as sequential execution. UML has has rich semantics for modeling behavior such as state machines, Petri nets, data flow graphs, etc.
This is far outside my expertise, but UML looks promising to an uninformed eye. (UML has disappointed me in the past, but it need not do so in this case)

--Trygve

On 2011.06.30 17:50, James O. Coplien wrote:

On Jun 30, 2011, at 10:44 , Trygve Reenskaug wrote:

It should be possible to write a guide for modeling DCI systems with UML. 
Jim: Is this a theme for a Master or PhD? It could be a new and very useful intro for DCI novices.
The work would involve  extracting useful bits from UML and possibly modifying them where  necessary. The modifications could become input to a next version of UML.


I doubt that this is ph.d. material, but it could be a good MS project.
--

James O. Coplien

unread,
Jul 11, 2011, 4:52:58 PM7/11/11
to object-co...@googlegroups.com
My concerns:

1. With such a meta-model in hand, what could you do that you couldn't do today? UML to me is an informal communication tool, but the fact that you need to honor the effort with a full academic degree suggests to me that it isn't the first informalism I'd choose to communicate what DCI is.

2. I don't think that UML has sufficiently formal semantics to support Ph.D meta-modeling work.

3. I think parallel processes is a separate issue, a separate thesis, and I still don't understand why it has anything to do with DCI in particular.

4. UML is a collection of notations rather than a formalism. I'm not sure that the principle opportunities ahead of DCI lend themselves well to UML as a formalism. I'd identify the challenges first and the formalism separate. Each challenge might beg a different formalism. If the parallelism is important and in fact can be described using marked Petri nets, I don't understand the value is of bringing UML into the picture.

5. Though I think I know UML and DCI, I would never want my name associated with a Ph.D thesis that used UML as its expository formalism — either as a student or a professor. Part of it is that UML has become as passé as relational modeling as an academic topic, but part of it is that it can't stand up even to the formalism of relational modeling...

I am not sure that express-ability in UML is necessarily a good thing. When we uncovered the indirect template idiom — now a staple of programming in C++ and a foundation of the STL — I used it to design a simple state machine. I went to Grady Booch and asked him how we could represent it in the Booch notation. It was almost unreadable. UML makes it a little better, but is still pretty opaque and lacks most of the interesting details. Do you think you can really understand this diagram?


I don't understand it, and I wrote the code. C++ programmers will find the code much more accessible (if you're not a C++ programmer, you'll probably find this code disgusting and ugly, much as a Finn probably finds German poetry disgusting and ugly):

template <class M, class State, class Stimulus> class AbstractFSM {
public:
    virtual void addState(State) = 0;
    virtual void addTransition(Stimulus, State, State, void (M::*)(Stimulus));
};

class UserFSM: public AbstractFSM<UserFSM, char, char> {
public:
    void x1(char);
    void x2(char); void init() {
        addState(1); addState(2); addTransition(EOF,1,2,&UserFSM::x1); ... .
    }
};

template <class UserMachine, class State, class Stimulus> class ImplementationFSM: public UserMachine {
public:
    ImplementationFSM() { init(); }
    virtual void addState(State);
    virtual void addTransition(Stimulus, State from, State to, void (UserMachine::*)(Stimulus));
    virtual void fire(Stimulus);
private:
    unsigned nstates;
    State *states, currentState;
    map<State, void(UserMachine::*)(Stimulus)> *transitionMap;
};


I would much rather see a more formal basis for a DCI metamodel. Academic notations like the first-order predicate calculus are probably no more or less opaque than UML, but at least they have universally understood formal semantics. It's a good thing to get DCI more broadly understood, but I am not convinced that UML is the ideal tool to do this.

It would be a great thing to codify DCI so we could formally answer hard questions about it in the future, based an agreed, formal model of its fundamentals. That could be a good Ph.D thesis.

Greg Young

unread,
Jul 11, 2011, 5:09:14 PM7/11/11
to object-co...@googlegroups.com

The parallel side is likely just a mix of dci and the join calculus. You can do this easily today in scala using akkas futures.

On 11 Jul 2011 16:53, "James O. Coplien" <jcop...@gmail.com> wrote:
> My concerns:
>
> 1. With such a meta-model in hand, what could you do that you couldn't do today? UML to me is an informal communication tool, but the fact that you need to honor the effort with a full academic degree suggests to me that it isn't the first informalism I'd choose to communicate what DCI is.
>
> 2. I don't think that UML has sufficiently formal semantics to support Ph.D meta-modeling work.
>
> 3. I think parallel processes is a separate issue, a separate thesis, and I still don't understand why it has anything to do with DCI in particular.
>
> 4. UML is a collection of notations rather than a formalism. I'm not sure that the principle opportunities ahead of DCI lend themselves well to UML as a formalism. I'd identify the challenges first and the formalism separate. Each challenge might beg a different formalism. If the parallelism is important and in fact can be described using marked Petri nets, I don't understand the value is of bringing UML into the picture.
>
> 5. Though I think I know UML and DCI, I would never want my name associated with a Ph.D thesis that used UML as its expository formalism — either as a student or a professor. Part of it is that UML has become as passé as relational modeling as an academic topic, but part of it is that it can't stand up even to the formalism of relational modeling...
>
> I am not sure that express-ability in UML is necessarily a good thing. When we uncovered the indirect template idiom — now a staple of programming in C++ and a foundation of the STL — I used it to design a simple state machine. I went to Grady Booch and asked him how we could represent it in the Booch notation. It was almost unreadable. UML makes it a little better, but is still pretty opaque and lacks most of the interesting details. Do you think you can really understand this diagram?
>
>
>

Trygve Reenskaug

unread,
Jul 12, 2011, 6:00:36 AM7/12/11
to object-co...@googlegroups.com
Jim,
I stand corrected. Developing a modeling language for DCI cannot be an academic pursuit, at least not on the level of a doctoral thesis.

I have heard that 70-80% of the population does not understand abstractions (whatever that might mean). I have always been making tools for people, and I believe many or most users and even programmers are people in this sense. So it is a challenge to make abstractions appear as concrete as possible. BabyIDE is work in progress towards this goal for DCI.

For me, a UML Message Sequnce Chart communicates better than plain code be it written in C++ or Smalltalk. MSC can, for example,� be used to document a CRC-cards session , which is even more concrete. (CRC stands for CandidateRole-Responsibility-Collaboration these days). � Alan Kay had the children actually walking a program execution on the floor to help them find bugs in their code. (This was code for turtle geometry)

This thread is about looking for a modeling language for DCI. May be we cannot expect a practical answer from academia. Perhaps a technical college could come up with a contribution? But academia can give us the theoretical underpinnings for the practical tools. (Ole Johan Dahl was working with formal verification of software systems while I was working with programming practices. It was very interesting to see that we both came up with the same requirements to make it possible to reason about the code. He with his mathematics, I with my battle wounds. It was only a week ago that I appreciated the value of one of his rules that I have hitherto rejected: "An object can only be accessed from one other object if we shall be able to reason about the code."� This rule may apply to the Data part of DCI. In an article I am working on, I call it RestrictedOO. As opposed to FullOO which allows Interactions.)

Ah well. End of fun. Back to work.

--Trygve



On 2011.07.11 22:52, James O. Coplien wrote:
My concerns:

1. With such a meta-model in hand, what could you do that you couldn't do today? UML to me is an informal communication tool, but the fact that you need to honor the effort with a full academic degree suggests to me that it isn't the first informalism I'd choose to communicate what DCI is.

2. I don't think that UML has sufficiently formal semantics to support Ph.D meta-modeling work.

3. I think parallel processes is a separate issue, a separate thesis, and I still don't understand why it has anything to do with DCI in particular.

4. UML is a collection of notations rather than a formalism. I'm not sure that the principle opportunities ahead of DCI lend themselves well to UML as a formalism. I'd identify the challenges first and the formalism separate. Each challenge might beg a different formalism. If the parallelism is important and in fact can be described using marked Petri nets, I don't understand the value is of bringing UML into the picture.

5. Though I think I know UML and DCI, I would never want my name associated with a Ph.D thesis that used UML as its expository formalism � either as a student or a professor. Part of it is that UML has become as pass� as relational modeling as an academic topic, but part of it is that it can't stand up even to the formalism of relational modeling...

I am not sure that express-ability in UML is necessarily a good thing. When we uncovered the indirect template idiom � now a staple of programming in C++ and a foundation of the STL � I used it to design a simple state machine. I went to Grady Booch and asked him how we could represent it in the Booch notation. It was almost unreadable. UML makes it a little better, but is still pretty opaque and lacks most of the interesting details. Do you think you can really understand this diagram?


I don't understand it, and I wrote the code. C++ programmers will find the code much more accessible (if you're not a C++ programmer, you'll probably find this code disgusting and ugly, much as a Finn probably finds German poetry disgusting and ugly):

template <class M, class State, class Stimulus>�class AbstractFSM {
public:
�� �virtual void addState(State) = 0;
�� �virtual void addTransition(Stimulus, State, State,�void (M::*)(Stimulus));
};

class UserFSM: public AbstractFSM<UserFSM, char, char> {
public:
�� �void x1(char);
�� �void x2(char); void init() {
�� � � �addState(1); addState(2); addTransition(EOF,1,2,&UserFSM::x1); ... .
�� �}
};

template <class UserMachine, class State, class Stimulus> class ImplementationFSM: public UserMachine {
public:
�� �ImplementationFSM() { init(); }
�� �virtual void addState(State);
�� �virtual void addTransition(Stimulus, State from,�State to,�void (UserMachine::*)(Stimulus));
�� �virtual void fire(Stimulus);
private:
�� �unsigned nstates;
�� �State *states, currentState;
�� �map<State, void(UserMachine::*)(Stimulus)>�*transitionMap;
};


I would much rather see a more formal basis for a DCI metamodel. Academic notations like the first-order predicate calculus are probably no more or less opaque than UML, but at least they have universally understood formal semantics. It's a good thing to get DCI more broadly understood, but I am not convinced that UML is the ideal tool to do this.

It would be a great thing to codify DCI so we could formally answer hard questions about it in the future, based an agreed, formal model of its fundamentals. That could be a good Ph.D thesis.



On Jul 10, 2011, at 2:21 , Trygve Reenskaug wrote:

Jim,
M.Sc. or P.D.for evolving a metamodel for DCI based on UML?�� It could include modeling parallel processes with DCI.

The advisor needs to be a UML expert as well as having internalized DCI. A tall order, methinks.

The role structure part should be relatively trivial.�

Modeling the behavior of a Context with its roles is more challenging.

Half of UML is about modeling the behavior of object systems. Most of this metamodel can possibly be applied to the Context. This includes multi-process as well as sequential execution. UML has has rich semantics for modeling behavior such as state machines, Petri nets, data flow graphs, etc.
This is far outside my expertise, but UML looks promising to an uninformed eye. (UML has disappointed me in the past, but it need not do so in this case)
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.

--

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

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

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

Norway

Erlis Vidal

unread,
Jul 25, 2011, 1:53:42 PM7/25/11
to object-co...@googlegroups.com
On Tue, Jul 5, 2011 at 4:15 AM, Trygve Reenskaug <try...@ifi.uio.no> wrote:
Let me try to add the essence of  figure 5 in the "Execution Model" article without using any special terms:

RoleMethod A method that is a feature of a Role and that is shared among all the Role’s RolePlayers.
An executing RoleMethod can access its actual parameters and temporary variables. It can also access the current RolePlayer and  the current Context.

Polymorphism does not apply to these methods; methods specified for the Roles have priority over methods specified in the RolePlayer

This is a problem whey implementing RoleMethods as extension methods in C#. RolePlayer methods take precedence.
 
classes.


Acceptable?
--Trygve



--

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

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

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

Norway

--

rune funch

unread,
Jul 25, 2011, 3:07:40 PM7/25/11
to object-co...@googlegroups.com


Mvh
Rune

Den 25/07/2011 kl. 19.54 skrev Erlis Vidal <er...@erlisvidal.com>:



On Tue, Jul 5, 2011 at 4:15 AM, Trygve Reenskaug <try...@ifi.uio.no> wrote:
Let me try to add the essence of  figure 5 in the "Execution Model" article without using any special terms:

RoleMethod A method that is a feature of a Role and that is shared among all the Role’s RolePlayers.
An executing RoleMethod can access its actual parameters and temporary variables. It can also access the current RolePlayer and  the current Context.

Polymorphism does not apply to these methods; methods specified for the Roles have priority over methods specified in the RolePlayer

This is a problem whey implementing RoleMethods as extension methods in C#. RolePlayer methods take precedence.
Which is just another reason why extension methods are an ill fit for role methods

Wenig, Stefan

unread,
Jul 30, 2011, 9:26:22 PM7/30/11
to object-co...@googlegroups.com

OK, here's the next version of my sample without mixins (it still uses re-mix to address the problem of composing role interfaces from individual interfaces without creating dependencies from RolePlayers to Roles).

 

I tried to address the requirements I identified in my last mail:

1) code elegance: instance methods are usually more elegant than accessing parameter #1

Not much I can do about that. I name the first parameter representing the role 'self' (not a reserved keyword in C#). I also attach the [MethodRole] attribute (annotation) to this parameter, which is just for readability and has no actual functionality.

 

2) namespaces for each role

No problem in C# due to method overloading - the role parameter is part of the method's signature

 

3) independent files/modules for each role

I use partial classes for each role's methods. They can easily be distributed among several files. This clearly lacks in the elegance area. However, the only real disadvantages I see are that

a) putting role methods in the right partial class/file is not enforced

b) looking at the compiled context class (via tools/reflection) is a mess

 

 

If you compare this to my first sample using mixins, I'd say the mixin version is more elegant since it more clearly reflects the intention of the code. It also keeps the compiled classes separate, and even the generated classes are merged by RolePlayer class (not by context class) which is much more useful.

 

On the other hand, this version does have two important benefits:

- it does not require learning additional syntax and concepts, or additional libaries or tooling

- RoleMethods have direct access to their context

 

Only the context class changed since the last time, so I put it first.

 

Cheers,

Stefan

 

// the context (general part)
public partial class MoneyTransferContext


{
  public IMoneyTransferSourceRole Source;
  public IMoneyTransferDestinationRole Destination;

  public MoneyTransferContext (IMoneyTransferSourceRole source,

                                             IMoneyTransferDestinationRole destination)


  {
    Source = source;
    Destination = destination;
  }

  // slight modification: Transfer instead of Execute, amout is

  // specified to separate roles from (temporary) arguments
  public bool Transfer (decimal amount)
  {
    TransferTo (Source, amount);
  }
}

 

// all methods for IMoneyTransferSourceRole

public partial class MoneyTransferContext
{

  // this time, the destination is not a parameter in order to

  // demonstrate simple and direct access to other roles via

  // the context
  private bool TransferTo( [MethodRole] IMoneyTransferSourceRole self,

                                     decimal amount)
  {
    self.DecreaseBalance (amount);
    self.Log ("Withdrew: " + amount);
    Destination.IncreaseBalance (amount);
    Destination.Log ("Deposited: " + amount);
    return true;
  }
}


class Program
{
    static void Main(string[] args)
    {
        Account s = ObjectFactory.Create<Account>();
        s.IncreaseBalance (1000);
        Account d = ObjectFactory.Create<Account>(ParamList.Empty);
        d.IncreaseBalance (2000);

        var c = new MoneyTransferContext ((IMoneyTransferSourceRole) s,

                                                                  (IMoneyTransferDestinationRole) d);
        c.Transfer (100);

Wenig, Stefan

unread,
Jul 31, 2011, 5:25:58 AM7/31/11
to object-co...@googlegroups.com
> -----Original Message-----
> From: Wenig, Stefan
> Sent: Sonntag, 31. Juli 2011 03:26
> To: object-co...@googlegroups.com
> Subject: RE: Re: How to model a DCI system?
>
> On the other hand, this version does have two important benefits:
> - it does not require learning additional syntax and concepts, or
> additional libaries or tooling
> - RoleMethods have direct access to their context

That's not quite correct. if I want to avoid re-mix at all, I also have to stop using the [CompleteInterface] attribute, so I'd have to implement role interfaces directly with RolePlayer types, potentially leading to the dependency problem Christian mentioned.

Although this is probably a separate debate, I'll also include this version for completeness. It's just a matter of removing the [CompleteInterface] attribute and including those interfaces in the list of interfaces implemented by the RolePlayers. Furthermore, objects can now be constructed using the 'new' operator without any additional compile-time steps.

// seperate the capabilities of Account into several interfaces (interface
// seggregation, taken to an extreme for the sake of demonstration. we
// could combine them, but then the dependencies of roles would increase.)

public interface ILoggable
{
void Log(string s);
}

public interface IDecreasable
{
void DecreaseBalance(decimal amount);
}

public interface IIncreasable
{
void IncreaseBalance (decimal amount);
}

// Account actually implements all those interfaces in order to Qualify for
// the roles that depend on them. if it wouldn't, we could create mixins
// to translate between specific Roles and RolePlayers.

public class Account : ILoggable, IDecreasable, IIncreasable, IMoneyTransferSourceRole, IMoneyTransferDestinationRole
{
decimal _balance = 0;

public void Log (string s)
{
Console.WriteLine(s + " (new balance: " + Balance + ")");
}

public void DecreaseBalance (decimal amount)
{
_balance -= amount;
}

public void IncreaseBalance (decimal amount)
{
_balance += amount;
}

public decimal Balance
{
get { return _balance; }
}
}

// declaration of role interfaces


public interface IMoneyTransferSourceRole: ILoggable, IDecreasable { }

public interface IMoneyTransferDestinationRole: ILoggable, IIncreasable { }

// the context (general part)


public partial class MoneyTransferContext
{
public IMoneyTransferSourceRole Source;
public IMoneyTransferDestinationRole Destination;

public MoneyTransferContext (IMoneyTransferSourceRole source,
IMoneyTransferDestinationRole destination)
{
Source = source;
Destination = destination;
}
// slight modification: Transfer instead of Execute, amout is
// specified to separate roles from (temporary) arguments
public bool Transfer (decimal amount)
{
TransferTo (Source, amount);
}
}

// all methods for IMoneyTransferSourceRole
public partial class MoneyTransferContext
{
// this time, the destination is not a parameter in order to
// demonstrate simple and direct access to other roles via
// the context
private bool TransferTo([MethodRole] IMoneyTransferSourceRole self,
decimal amount)
{
self.DecreaseBalance (amount);
self.Log ("Withdrew: " + amount);
Destination.IncreaseBalance (amount);
Destination.Log ("Deposited: " + amount);
return true;
}
}

class Program
{
static void Main(string[] args)
{
Account s = new Account();
s.IncreaseBalance (1000);
Account d = new Account();

James O. Coplien

unread,
Jul 31, 2011, 5:55:34 AM7/31/11
to object-co...@googlegroups.com

On Jul 31, 2011, at 11:25 , Wenig, Stefan wrote:

> TransferTo (Source, amount);


This statement kind of offends my sense of aesthetics. It doesn't look like an operation on the Source role. And the Destination role should be implicated here, and is not. Or maybe I'm just confused.

Wenig, Stefan

unread,
Jul 31, 2011, 7:13:46 AM7/31/11
to object-co...@googlegroups.com
Yes, it clearly loses in the elegance category. But we can get used to that. After all, DCI is a concept you have to spend a lot of time learning and understanding, so I don't think that's a big obstacle. Our brains will quickly learn to interpret this as just funny syntax for Source.TransferTo (amount).

I'm not saying this can't be more beautiful. But how much trickery are we ready to put up with just to get more beautiful method invocation code? We need better reasons.


The destination role question is interesting. I personally don't have a very strong opinion about this, but isn't one of the advantages of DCI that you do not need to pass around role objects, but rather access the context directly from RoleMethds? I read some of Rickard's messages this way. Also, if this is not required, what's the big deal about accessing the context from RoleMethods via some stack in Trygve's execution paper? Passing everything around as parameters is easy and creates none of these problems (unique active context, single thread).


It's a bit hard to come up with answers if I have to show my own ideas and guess what DCI would require at the same time. A good, complete sample is overdue. And again, this sample just has to show how it's done, not prove the usefulness of DCI.

Cheers,
Stefan

> --
> You received this message because you are subscribed to the Google
> Groups "object-composition" group.
> To post to this group, send email to object-

> compo...@googlegroups.com.


> To unsubscribe from this group, send email to object-

> composition...@googlegroups.com.

rune funch

unread,
Jul 31, 2011, 7:21:22 AM7/31/11
to object-co...@googlegroups.com
> I'm not saying this can't be more beautiful. But how much trickery are we ready to put up with just to get more beautiful method invocation code? We need better reasons.
Sounds a lot like my high school teacher when he was so u fortunate to
stumble into a few students that knew OO which he at the time didn't.
"your code look weird, there seems to be a lot of magic and I don't
understand it" that was he reasons for barely passing a project that,
for several years thereafter would serve as a show case for what you
could learn at my old high.

/Rune

James O. Coplien

unread,
Jul 31, 2011, 7:33:32 AM7/31/11
to object-co...@googlegroups.com

On Jul 31, 2011, at 1:13 , Wenig, Stefan wrote:

> I'm not saying this can't be more beautiful. But how much trickery are we ready to put up with just to get more beautiful method invocation code? We need better reasons.

I would never hire anyone who said that to work on real code.


> It's a bit hard to come up with answers if I have to show my own ideas and guess what DCI would require at the same time. A good, complete sample is overdue. And again, this sample just has to show how it's done, not prove the usefulness of DCI.

We are waiting for your good, complete sample.

Have you read RIckard's sample? That qualifies as a good, complete sample to me. It's commercially deployed.

Have you read the Lean Architecture Book yet to understand a bit more of the context, history and motivation?

Paradigm shifts are hard. This is a paradigm shift, into object thinking. It sounds like you're not there yet. I empathize with your difficulty, but would challenge you to higher aspirations and continued work. For some, it's just too hard, and if that's the case, you're always welcome to leave. But neither should you expect to learn everything here without having gone through the basics: the fact that you say that there is no, good, complete sample makes me wonder if you've taken advantage of the basic startup resources available to you.

I know we need a FAQ page. Let me again see what I can do about that.

Trygve Reenskaug

unread,
Aug 1, 2011, 4:48:36 AM8/1/11
to object-co...@googlegroups.com
Stefan,
I won't answer your question directly, but rather espond on a higher level.

The purpose of DCI is to produce code that a person can read and understand and so reason about its correctness. Anything you can do with DCI, you can do in many other ways including POJO and even assembly. With DCI, it is all a question of readable code. All my experiments have aimed at finding how to express a solution that it puts the least barrier between the code and its reader. Does the code appear natural? does it hide administrative details so that the problem solution stands out clearly?

A RoleMethod is defined as "A stateless method that is a feature of a Role and that is shared among all the Role’s potential RolePlayers.
Polymorphism does not apply to these methods; RoleMethods have priority over methods specified in the RolePlayer instances An executing RoleMethod can access its actual parameters and temporary variables. It can also access the current RolePlayer and the current Context (and thence access all visible RolePlayers through their role names)
"

DCI does not forbid polymorphism. It does forbid it where it causes unreadable code. This is often the case for Interactions.  Polymorphism is permitted for readable code, All Data classes must fall into this category.

I am searching for a precise rule that separates the readable from the unreadable code. (RM-ODP defines some useful concepts: An "action" is something that happens. An "internal action" always takes place without the participation of the object's environment. An "interaction" takes place with the participation of the object's environment. May be Internal actions are always readable even with polymorphism. That's what I am currently looking into. POJO interactions, in general,  remind me of the "spaghetti code" of the early days of programming.

I am very happy about all the different attempts at realizing DCI in (un)suitable languages. The discussions on this list seem to be  missing in the code readability and transparency issues. I miss Context code that explicitly defines the structure of the roles and the communication channels between them. This structure is the high-level view on an Interaction; its table of contents if you like.

There are three essential questions about how a system of objects realize some required funtionality:
  1. What are the objects?
  2. How are they interconnected?
  3. What do they do?
A programmer may ask these questions, and the code should answer them clearly.

I see many discussions about language details. The details are important and interesting, but I miss more discussions about the programmer's mental model. My personal model is that a use case that leads to one or more scenarios; where each scenario includes one or more user commands to the system. A command goes directly to a Context object. This Context may impement the command any way you like; one solution is to apply the DCI paradigm with its roles and role methods. I look for explicit expression of this model in the code. Other people probably have other models. I would like to see discussions about the programmer mental models of the examples together with discussions about how the code reflects the models. I have read somewhere that our short term memory can handle 7 ± 2 items. If so, the programmer's mental model should be implemented in well separated parts with up to seven items in each.

Elegance is a vague term. I prefer readability. More precisely: How does your code answer the above essential questions?

Cheers
--Trygve
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/object-composition?hl=en.

Wenig, Stefan

unread,
Aug 1, 2011, 7:51:34 AM8/1/11
to object-co...@googlegroups.com
So you're smart and I'm clueless? Thanks for sharing this important information.

No need to discuss controversial matters then, how convenient.


> -----Original Message-----
> From: object-co...@googlegroups.com [mailto:object-
> compo...@googlegroups.com] On Behalf Of rune funch
> Sent: Sunday, July 31, 2011 1:21 PM
> To: object-co...@googlegroups.com
> Subject: Re: How to model a DCI system?
>

James O. Coplien

unread,
Aug 1, 2011, 7:59:16 AM8/1/11
to object-co...@googlegroups.com
If you're here to learn, you'll have to climb a knowledge gradient. I think you have three mails in this forum by know suggesting that that would be a good path for you.

If you are here to teach, you'll need to get some credibility with us first.

I do appreciate your efforts. At least you're writing code, which most people don't try. I know it is frustrating. But, like I say, it's a paradigm shift. That you can't make a paradigm shift doesn't mean you're clueless, or that those in the current paradigm are smart. It just means that we're different, and that we're human.

> To post to this group, send email to object-co...@googlegroups.com.
> To unsubscribe from this group, send email to object-composit...@googlegroups.com.

Wenig, Stefan

unread,
Aug 1, 2011, 8:05:09 AM8/1/11
to object-co...@googlegroups.com
Hi Jim

Maybe we can get this discussion back to a more productive level.

I just provided two very different samples, one with mixins and one based on a simpler implementation that nevertheless maps 1:1 to the conceptual model of DCI as I understand it so far. I did not express a preference of one of them. All I did was stating my opinion that the purely syntactical matter of writing a.Foo(b) vs. Foo (a,b) alone is not important enough to ignore all other factors.

Is that really a reason to resort to personal attacks?

I did clearly not read every available piece of information about DCI. I read that part of your book, several papers by Trygve, and some of the mailing list code. I looked for samples and found some, but I don't know which of them are really worth giving a close look. Are they authorative? Do they implement DCI as it is agreed upon in this group, or do they contain additional or controversial stuff? I cannot know that, so I came here to ask.

If there is a sample that would answer my questions, please just share a link.

Stefan

> -----Original Message-----
> From: object-co...@googlegroups.com [mailto:object-
> compo...@googlegroups.com] On Behalf Of James O. Coplien
> Sent: Sunday, July 31, 2011 1:34 PM
> To: object-co...@googlegroups.com
> Subject: Re: How to model a DCI system?
>
>

Wenig, Stefan

unread,
Aug 1, 2011, 8:12:02 AM8/1/11
to object-co...@googlegroups.com
Yes, I got my share of "you should find that out yourself" mails. I'm not good at reading thoughts though, so I chose to ask for information that was not in the material I read.

I asked for samples. The answer was: go write your own.

I provided samples with some discussion. The answer now is that I'm not up to understanding the paradigm shift that is so obvious to everyone else here, and I might want to consider going away.

I wonder what I should try next.

rune funch

unread,
Aug 1, 2011, 8:12:36 AM8/1/11
to object-co...@googlegroups.com
Making you feel clueless was never my intention and I can only apologize if I made you feel I was trying to. I was merely trying to point out that you're comment reminded me of some one that had to make a paradigm shift too.
Mu high school teacher was a bright man, he reacted as he did I'm sure because he was uncomfortable being challenged by his students (btw I never claimed that said piece of code was mine). He too was bright enough to take on the challenge and venture down unfamiliar paths and when he did discovered that the piece of code the students had generate was indeed on a much higher level than he had appriciated when merely passing their project. This realization resulted in him using the project as a show case for several years. And thus even though it would have been incorrect to state that the student who originally created the program had learned to do so at my high school it was true that new students could learn the basis of that application. The program challenged my teacher enough to risk a paradigm shift and taking up that challenge meant that it was the teacher that for a moment was taught by the students but students that followed all gained from the teachers guts to risk a paradigm shift.

Once again I can only apologize if you feel insulted by my previous comments. From your posts that bares reflections on several of the comments you've received I believe you to be bright and hope you brave enough to risk going down unfamiliar paths, paths you have to walk to make a paradigm shift.

Best regards
Rune

2011/8/1 Wenig, Stefan <stefan...@rubicon.eu>
To post to this group, send email to object-co...@googlegroups.com.
To unsubscribe from this group, send email to object-composit...@googlegroups.com.

rune funch

unread,
Aug 1, 2011, 8:18:05 AM8/1/11
to object-co...@googlegroups.com


2011/8/1 Wenig, Stefan <stefan...@rubicon.eu>

Hi Jim

Maybe we can get this discussion back to a more productive level.

I found Trygve's mail an excellent post. Restating the goals of DCI and giving certain questions to use when evaluating an implementation. It also posted a question to you in regards to your sample code. I believe answering that question could be  a way to heighten the level of productivity of this debate.

/Rune 

James O. Coplien

unread,
Aug 1, 2011, 8:33:18 AM8/1/11
to object-co...@googlegroups.com, object-co...@googlegroups.com
I still don't recall that you have answered my questions: Have you looked at Rickard's examples? Have you read the Lean Architecture book?

Let me know, and we'll go from there.


Sent from my iPhone

> To post to this group, send email to object-co...@googlegroups.com.
> To unsubscribe from this group, send email to object-composit...@googlegroups.com.

Wenig, Stefan

unread,
Aug 1, 2011, 8:39:14 AM8/1/11
to object-co...@googlegroups.com

I did read that as an insult, but I don’t insist. Anyway, I can take one or two. All I’m asking is that replies refer to my questions and do not resort back to “DCI is so great and you just didn’t get it”. This does not help even if it’s true.

 

One thing that I do insist is that OOP is not defined by where in a method call the self parameter is. I did not and still do not consider this an attack on DCI, so I don’t understand the harsh reactions. Is this not something that can be discussed on this list? To me, this seems to be an essential part of discussing the relative advantages and disadvantages of various DCI implementations.

 

Stefan

Wenig, Stefan

unread,
Aug 1, 2011, 9:10:19 AM8/1/11
to object-co...@googlegroups.com
I answered them half an hour ago:

> I did clearly not read every available piece of information about
> DCI. I read that part of your book, several papers by Trygve, and
> some of the mailing list code. I looked for samples and found some,
> but I don't know which of them are really worth giving a close look.
> Are they authorative? Do they implement DCI as it is agreed upon in
> this group, or do they contain additional or controversial stuff? I
> cannot know that, so I came here to ask.
>
> If there is a sample that would answer my questions, please just
> share a link.

I just tried to look at Rickard's samples, but it seems they have moved and I can't find them either at their old address http://dscm.ops4j.org/git/gitweb.cgi?p=qi4j-samples.git;a=tree;f=dci;h=d60693a8e7e162cf46e12ab37aeb09d246021f2a;hb=HEAD nor at github. Got a link to share?

Stefan

Risto Välimäki

unread,
Aug 1, 2011, 9:12:11 AM8/1/11
to object-co...@googlegroups.com
2011/7/31 Wenig, Stefan <stefan...@rubicon.eu>

class Program
{
   static void Main(string[] args)
   {
       Account s = new Account();
       s.IncreaseBalance (1000);
       Account d = new Account();
       d.IncreaseBalance (2000);

       var c = new MoneyTransferContext ((IMoneyTransferSourceRole) s,
                                         (IMoneyTransferDestinationRole) d);
       c.Transfer (100);
   }
}

Above resembles quite much my early interpretations of DCI. But actually this is not pure object oriented programming and therefore not pure DCI. If it was the best and only way you could do (almost) DCI in programming language X, then I would use it. I'd say above code looks like mediator pattern, and once upon a time (2010-06-29) Trygve wrote:

"You can indeed implement the algorithm as a whole in the Context. GOF calls this solution the Mediator pattern. 
[...]
The centralized solution in the Mediator pattern will be OK in simple cases such as the bank transfer example. The algorithm can become very complex and unreadable in bigger examples if all interaction shall be forced through the Context object. DCI is a distributed solution where the network of communicating objects is expressed explicitly in the Context and the Interaction algorithm is distributed among the role methods."

So the code readability is again what's soon sacrificed if we implement (large) algorithms directly in Contexts (just like "c.Transfer(100)") and not split them into Roles (like "source.transferTo(destination, amount)"). 

Often it's also semantically more reasonable to call roleplayer to do its actions than work as roleplayers were just puppets that obey anything puppet master (Context) orders. Puppet-master-context sounds like a god object to me.

James O. Coplien

unread,
Aug 1, 2011, 9:38:34 AM8/1/11
to object-co...@googlegroups.com, object-co...@googlegroups.com


Sent from my iPhone

On 01/08/2011, at 14.39, "Wenig, Stefan" <stefan...@rubicon.eu> wrote:

One thing that I do insist is that OOP is not defined by where in a method call the self parameter is. 


You might think twice about taking issue with OO definitions in current company. I would better accept your objection if you had demonstrated understanding if the DCI model here, but you have not. Your above claim about code doesn't prove that you don't understand it, but it certainly suggests it.

Further, this us not a discussion about traditional OO or it's definition, but about DCI. 

Go back and read the chapters relating to mental models. My current theory is that you are missing that. I think that our frustration may come from your continued arguing in the old paradigm. Friends, have patience with Stefan. Stefan, have patience. You're going to have to let go of some things to make room for what we're telling you. We can't do that for you. 
It is loading more messages.
0 new messages