DCI and The Expression Problem

101 views
Skip to first unread message

Jonah S

unread,
Apr 10, 2015, 10:23:19 AM4/10/15
to object-co...@googlegroups.com
I am curious if DCI views itself as a solution to the expression problem:

http://c2.com/cgi/wiki?ExpressionProblem

or is this simply an orthoganal problem from those DCI solves?  Perhaps one which is better solved at the language level, as mentioned in the link, via MultiMethods or similar.

Where do you guys locate the expression problem in your own conceptual understanding of design problems, OOP, and FP?

It seems to me that what is really going in is that we have a matrix, with "functions" on one side (imagine labels going down the y-axis) and "types" (or classes) on the other side (the column labels on the x-axis), and behaviors arising from the intersection of these two (cells of the matrix). 

Fundamentally, when you add a new "function", a new "row" of behavior data must be calculated -- that is, the new behavior cannot be reduced to any of the existing behavior, it is truly "new".  Same goes for a new "column" of data when we add a new type.

The expression problem then arises because the OOP primitive for conceptual grouping is the "column", so it performs well when we add a new column: It simply adds one more primitive.  But it performs poorly when we add a new "row": The change ripples across every single one of the existing primitives.  FP, whose conceptual primitive is the "row", has precisely the inverse qualities.

But in both cases isn't the real problem that the conceptual primitive is not small enough?  The "world" of behavior is made up of the matrix cells, not of rows or columns...

I'd love to hear any thoughts on this subject from the posters here.

Thanks,
Jonah

Egon Elbre

unread,
Apr 10, 2015, 11:37:17 AM4/10/15
to object-co...@googlegroups.com
The more I studied DCI, the more I started to realize that decomposing systems into very small pieces that can be easily added/removed harms readability. It requires adding a a lot of machinery to make the code readable.

But, regarding choosing the conceptual grouping - I'll base my choice based on a prediction in which dimension things will more likely grow. Or slice based on the dimension where things are more likely to change together. If it helps I'll use a custom dispatch/forwarding.

For example, if I'm implementing that Shape for a drawing program - I would probably use the "OO" style - because I'm probably more likely to add new shapes that I can draw, rather than new operations on them. If I now need check collision of objects, I would make a separate thing that knows how to check collisions - instead of adding that operation to the "Shape"-s themselves. i.e. https://play.golang.org/p/jnZq3LrT2o (code is a bit messy there)...

So, it's not one or the other approach... or some intricate type-system that allows me to grow in all directions. They work together very well. Basically, I'll try to use one that makes the code clearest and easiest to modify.

+ Egon

Egon Elbre

unread,
Apr 10, 2015, 11:44:52 AM4/10/15
to object-co...@googlegroups.com
On Friday, 10 April 2015 18:37:17 UTC+3, Egon Elbre wrote:
On Friday, 10 April 2015 17:23:19 UTC+3, Jonah S wrote:
I am curious if DCI views itself as a solution to the expression problem:

http://c2.com/cgi/wiki?ExpressionProblem

or is this simply an orthoganal problem from those DCI solves?  Perhaps one which is better solved at the language level, as mentioned in the link, via MultiMethods or similar.

Where do you guys locate the expression problem in your own conceptual understanding of design problems, OOP, and FP?

It seems to me that what is really going in is that we have a matrix, with "functions" on one side (imagine labels going down the y-axis) and "types" (or classes) on the other side (the column labels on the x-axis), and behaviors arising from the intersection of these two (cells of the matrix). 

Fundamentally, when you add a new "function", a new "row" of behavior data must be calculated -- that is, the new behavior cannot be reduced to any of the existing behavior, it is truly "new".  Same goes for a new "column" of data when we add a new type.

The expression problem then arises because the OOP primitive for conceptual grouping is the "column", so it performs well when we add a new column: It simply adds one more primitive.  But it performs poorly when we add a new "row": The change ripples across every single one of the existing primitives.  FP, whose conceptual primitive is the "row", has precisely the inverse qualities.

But in both cases isn't the real problem that the conceptual primitive is not small enough?  The "world" of behavior is made up of the matrix cells, not of rows or columns...

The more I studied DCI, the more I started to realize that decomposing systems into very small pieces that can be easily added/removed harms readability. It requires adding a a lot of machinery to make the code readable.

But, regarding choosing the conceptual grouping - I'll base my choice based on a prediction in which dimension things will more likely grow. Or slice based on the dimension where things are more likely to change together. If it helps I'll use a custom dispatch/forwarding.

For example, if I'm implementing that Shape for a drawing program - I would probably use the "OO" style - because I'm probably more likely to add new shapes that I can draw, rather than new operations on them. If I now need check collision of objects, I would make a separate thing that knows how to check collisions - instead of adding that operation to the "Shape"-s themselves. i.e. https://play.golang.org/p/jnZq3LrT2o (code is a bit messy there)...


As a similar question...

Which way do you prefer to divide a house into rooms?
From North to South or East to West? :)

Raoul Duke

unread,
Apr 10, 2015, 11:55:53 AM4/10/15
to object-co...@googlegroups.com
> The more I studied DCI, the more I started to realize that decomposing
> systems into very small pieces that can be easily added/removed harms
> readability. It requires adding a a lot of machinery to make the code
> readable.

at least, with our current tools.

i can imagine a Star Trek / Bret Victor / Doug Engelbart future where
it isn't the case. (now if only i were rich and smart enough to embark
on Making It So.)

Jonah S

unread,
Apr 10, 2015, 12:08:51 PM4/10/15
to object-co...@googlegroups.com

Hey Egon,

Thanks for your thoughts.  But doesn't your rhetorical question about the house, which implies choosing a "direction" is silly, contradict the advice from your first reply, which argues that it's harmful to readability (or would it be "livability" in the house metaphor :) )  to design a house broken up in both directions?  As I read your argument, continuing the house metaphor, you were saying that your approach would be to determine the direction you were more likely to walk across the house most of the time, and divide the rooms in accord with that.

Regarding your concern about breaking things into overly small pieces, my understanding is that DCI frown upon that in so far as spreads what should be a single logical unit of system behavior (collaboration among objects) across a network of objects, obscuring that system behavior in the process.  Hence the "error" is not breaking things down into small pieces per se, but shattering coherent units of logic into bits.  However, there is nothing wrong with small pieces when those pieces are the appropriate logical primitives.  That's my understanding, anyway.

Egon Elbre

unread,
Apr 10, 2015, 12:35:03 PM4/10/15
to object-co...@googlegroups.com
On Friday, 10 April 2015 19:08:51 UTC+3, Jonah S wrote:

Hey Egon,

Thanks for your thoughts.  But doesn't your rhetorical question about the house, which implies choosing a "direction" is silly, contradict the advice from your first reply, which argues that it's harmful to readability (or would it be "livability" in the house metaphor :) )  to design a house broken up in both directions?  As I read your argument, continuing the house metaphor, you were saying that your approach would be to determine the direction you were more likely to walk across the house most of the time, and divide the rooms in accord with that.

All metaphors break down when examined too closely, but...

If the house is sliced like a matrix... i.e. many small rooms - it wouldn't be very pleasant to live in; because you would have to constantly move through doors. Neither would be slicing in a single direction; harder to utilize the space. Livability isn't only about walking from one place to another.

You divide your house into rooms - maybe there is a hallway (the entrypoint to your code), living room (with the main server logic), attached to a kitchen (administrative features), a bedroom (website usage statistics), a closet (full of util functions) and a bathroom (some deployment scripts)... and so on...

In a way, you divide/organize your code based on how you "live" in it.


Regarding your concern about breaking things into overly small pieces, my understanding is that DCI frown upon that in so far as spreads what should be a single logical unit of system behavior (collaboration among objects) across a network of objects, obscuring that system behavior in the process.  Hence the "error" is not breaking things down into small pieces per se, but shattering coherent units of logic into bits.

Yes.

However, there is nothing wrong with small pieces when those pieces are the appropriate logical primitives.

Yes. Of course there's also the concern of having too many little pieces - the more different pieces you have, the harder it is to understand them collectively. (As usual terms and conditions apply :))

James Coplien

unread,
Apr 10, 2015, 2:26:55 PM4/10/15
to object-co...@googlegroups.com
I view it in part as a solution to that or a very closely related problem; see the "Elephant Paper."

(My responses here are likely to be terse and sporadic. Like Trygve I am fighting a serious illness and am in medical facilities far from home with limited E-access. Someone here should have a recent draft of the paper.)
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
To post to this group, send email to object-co...@googlegroups.com.
Visit this group at http://groups.google.com/group/object-composition.
For more options, visit https://groups.google.com/d/optout.

James O Coplien

unread,
Apr 11, 2015, 5:19:57 AM4/11/15
to object-co...@googlegroups.com
There are very strong patterns to Alexander's architectural theories here. That is not an accident. In the end the rooms do not exist - only the space they enclose. An architect designs space - not rooms. The rooms are just manifestations of some mental model - they exist no more on the circulation realms of life than classes exist in an OO program. 

Yet in another, more vulgar sphere, they do exist and form a geometry. It can even be "beautiful." The most beautiful city I have visited on this regard is Efres in Asia Minor. Beautiful - but lacking the use cases of daily life, it is dead. 

Compartmetalization is formally a form of symmetry and Alexander has noted that symmetry is a mark of death, rather than life, in the world. Focusing on the parts just perpetuates the death of class-oriented programming.  Focus on the Life: the parts will be either obvious or irrelevant. 

Remember: in Lean Architecture I can do both a complete domain archutecture, and / or a complete Context, without once naming a conventional class. The other parts aren't "designed" but are merely a way to record what emerges from deep within ourselves. 

Alexander has found all of these to be true of the built world and I recognise all of them in DCI. 


Sendt fra min iPhone

James O Coplien

unread,
Apr 11, 2015, 5:21:33 AM4/11/15
to object-co...@googlegroups.com
P.S.: See Alexander's "A City is Not a Tree."

Sendt fra min iPhone

Den 10/04/2015 kl. 18.35 skrev Egon Elbre <egon...@gmail.com>:

Jonah S

unread,
Apr 11, 2015, 2:12:52 PM4/11/15
to object-co...@googlegroups.com
Cope,

Thanks for the recommendation.  Terrific stuff -- the insights are deep and applicable far beyond architecture or programming, I thought.  

In OOP, I see the parallels between tree-like, artificial cities and class hierarchies.  The designed cities paper over the complexities of life in the same way static class heirarchies paper over the complex, changing interactions of objects in different contexts.  And this is exactly what DCI tries to solve.

Regarding my original question, you said: "I view it in part as a solution to that or a very closely related problem; see the "Elephant Paper.""

I did some searching but couldn't figure out what paper that was.  Is it listed at http://fulloo.info/Documents/?  If so, which is it?

As for the expression problem, how would you solve the shapes example with DCI?

Hope you're feeling better!  But glad to know that even when sick your priorities are on track (ie, discussing philosophy and OOP)!

Jonah

James O Coplien

unread,
Apr 11, 2015, 2:48:08 PM4/11/15
to object-co...@googlegroups.com
Here is a very old version of the Elephant paper I found on the web. I know there is a newer one. I will try to get it to you when I make it out of the hospital and can get around again. 

Sendt fra min iPhone
-- 
2010.05.07-SixWiseMenAndTheElephant-COMMENTED.doc

Matthew Browne

unread,
Apr 11, 2015, 7:17:48 PM4/11/15
to object-co...@googlegroups.com
On Friday, April 10, 2015 at 12:08:51 PM UTC-4, Jonah S wrote:
Regarding your concern about breaking things into overly small pieces, my understanding is that DCI frown upon that in so far as spreads what should be a single logical unit of system behavior (collaboration among objects) across a network of objects, obscuring that system behavior in the process.  Hence the "error" is not breaking things down into small pieces per se, but shattering coherent units of logic into bits.  However, there is nothing wrong with small pieces when those pieces are the appropriate logical primitives.  That's my understanding, anyway.

Indeed, that's one of the reasons roles are so helpful...they divide system operations into easily comprehensible segments according to the mental model, but you can still see the whole operation in one place.*  You could also organize behavior according to roles in FP without DCI, but you'd of course lose the notion of a role player. Perhaps that's why FP by itself doesn't solve the expression problem.

* Except in the case of nested contexts, which is why nested contexts should reflect different levels of abstraction rather than just being used to divide things up arbitrarily

James O Coplien

unread,
Apr 12, 2015, 3:09:43 AM4/12/15
to object-co...@googlegroups.com
Roles don't divide anything up, any more than words divide up a sentence.  They merely express one perception of a named process that we often describe with words, which we have donned Roles. 

I don't recall anyone, ever, on this list, or on any paper, extolling any intrinsic benefit either of role decompsition or of the aggregation of role methods into Roles. All the discussion from the jnjectionless crowd indeed points in the other direction and its mechanics too often become confused with the semantic model. 

I'd love to see concrete counter examples of my claim above, if you know of any. 


Sendt fra min iPhone
--

Jonah S

unread,
Apr 12, 2015, 4:40:13 AM4/12/15
to object-co...@googlegroups.com
Cope,

Are you saying that the purpose of roles is solely to capture the mental model in code, and that any functional decomposition of the system operation due to the roles is purely incidental?

Assuming I'm hearing you right, couldn't you still say that the purpose of role (I'm speaking now of the conceptual role as it exists in life, with no reference to code) is to divide up our mental concepts in ways that are natural to us?  That is, the mental models we are trying to encode implicitly have value because they slice up our world in ways we understand.  From that perspective, it wouldn't be entirely wrong to say the decomposition in code imposed by those roles has intrinsic value?  Or did I miss your point?
To unsubscribe from this group and stop receiving emails from it, send an email to object-composition+unsub...@googlegroups.com.

James Coplien

unread,
Apr 12, 2015, 5:24:48 AM4/12/15
to object-co...@googlegroups.com
There is not, as far as I know, any statement of philosophical purpose to any part of DCI. We have argued that Roles derived from a mental model but the leverage from any such derivation has sorely been lacking in both our argumentation and implementations.

There is something both more dangerous and deep going on here than I originally feared. Consider again the Dijkstra implementation. It comprises a sea of so-called methods (really functions) that we arbitrarily group into Roles. Yet there are no rules for the grouping and no measures of coupling, cohesion, affinity, or any other kind of association that we think of as owing to Role-ness. Perhaps they precipitate from a volitive model but I am not yet convinced that the Role architecture actually aids the reader either in understanding a use case or in understanding the locus of a necessary change. 

In fact the major structure of interest —which is the scenario — is hidden as it is woven into the use cases that hopelessly cut across the Role architecture. 

What value — in any software engineering sense — is gained by the presence of role constructs in a context?

I am still sorting this out in my head and some of these questions are provocatively rhetorical. But for now Roles still retain a position of honor in capturing the important names we use for the objects in a use case and as such are a good part of design. They may not however, be a driver of the architectural partitioning or of any structural part of the system. And that was my main point. It makes me wonder if there is any value in including them in the code.

A Context containing nothing but a sea of disembodied "role" methods would certainly make the folks from the injectionless school happier. 

There is an alternative view which one might call "object oriented" where Role actually do have a function. It relates to the cocretisation of identity. However I cannot yet reconcile it either with the way that injectionless implementations have been confounded with DCI semantics here or with some of the recent clarifications presented here on this list. 

To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.

Matthew Browne

unread,
Apr 12, 2015, 8:58:42 AM4/12/15
to object-co...@googlegroups.com
On 4/12/15 3:09 AM, James O Coplien wrote:
Roles don't divide anything up, any more than words divide up a sentence.  They merely express one perception of a named process that we often describe with words, which we have donned Roles.
I don't think "divide" was the right word; I should have said "decompose". I meant to "divide" it according to its natural divisions -- or to be more precise, its mental components / parts -- which is an important distinction. Although it's obviously better for readability to avoid gargantuan methods that go on for pages, the important thing is not the size of a method per se (or how many methods belong to a single role), but rather how closely we match our mental model of objects interacting to achieve the goal of the use case. That's why I used the phrase "according to the mental model" in my previous post.

While searching this group for statements about functional decomposition, I came across this post of yours from last year that seems quite relevant here:
https://groups.google.com/d/msg/object-composition/2s2ur4-BdX4/je7t-YF-UsQJ

That post more eloquently and clearly expresses the same general idea as my above statements.

I don't recall anyone, ever, on this list, or on any paper, extolling any intrinsic benefit either of role decompsition or of the aggregation of role methods into Roles. All the discussion from the jnjectionless crowd indeed points in the other direction and its mechanics too often become confused with the semantic model. 

I'd love to see concrete counter examples of my claim above, if you know of any.
From Lean Architecture, p. 259:
Each of these methodful object roles captures its part of the algorithm of transferring money from one account to another. Each method is a reasonably sized mental chunk of the overall algorithm. This chunking helps us understand the overall transfer in terms of its pieces, instead of overwhelming the reader with a single procedure that captures all the steps of the transfer. Yes, we use procedural decomposition here - or is it just a method invocation? The point is that the right logic is in the right place with respect to the roles that come from the end user mental model. The transfer logic doesn’t belong to any single account class.
You're right, this doesn't extoll any intrinsic benefit of decomposition according to roles / role methods - the value comes from considering the roles (and their interactions) in their context. Here's a good quote from you about that:
More precisely, DCI is based more on a metaphor of "cue scripts" than that of a full script or play manuscript. Each role has its own set of instructions on how to act. The Context collectively has the information for the whole play because roles are encapsulated in the Context. But one still has to switch one's locus of attention from role to role to understand the whole, just as one switches attention from procedure to procedure to understand a procedurally-decomposed program. In DCI, the roles, rather than procedures alone, are the units of decomposition — and, in the other dimension, they provide a grouping of the clips of dialogue relevant to a role.
(From https://groups.google.com/d/msg/object-composition/MjIHLMxuIJg/mjJY1SuaflUJ)


Den 12/04/2015 kl. 01.17 skrev Matthew Browne <mbro...@gmail.com>:

On Friday, April 10, 2015 at 12:08:51 PM UTC-4, Jonah S wrote:
Regarding your concern about breaking things into overly small pieces, my understanding is that DCI frown upon that in so far as spreads what should be a single logical unit of system behavior (collaboration among objects) across a network of objects, obscuring that system behavior in the process.  Hence the "error" is not breaking things down into small pieces per se, but shattering coherent units of logic into bits.  However, there is nothing wrong with small pieces when those pieces are the appropriate logical primitives.  That's my understanding, anyway.

Indeed, that's one of the reasons roles are so helpful...they divide system operations into easily comprehensible segments according to the mental model, but you can still see the whole operation in one place.*  You could also organize behavior according to roles in FP without DCI, but you'd of course lose the notion of a role player. Perhaps that's why FP by itself doesn't solve the expression problem.

* Except in the case of nested contexts, which is why nested contexts should reflect different levels of abstraction rather than just being used to divide things up arbitrarily
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
To post to this group, send email to object-co...@googlegroups.com.
Visit this group at http://groups.google.com/group/object-composition.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/N0RFIadUgt0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.

Matthew Browne

unread,
Apr 12, 2015, 10:48:03 AM4/12/15
to object-co...@googlegroups.com
On 4/12/15 5:24 AM, James Coplien wrote:
A Context containing nothing but a sea of disembodied "role" methods would certainly make the folks from the injectionless school happier. 

There is an alternative view which one might call "object oriented" where Role actually do have a function. It relates to the cocretisation of identity. However I cannot yet reconcile it either with the way that injectionless implementations have been confounded with DCI semantics here or with some of the recent clarifications presented here on this list.
I think we are getting at something deep here - one of the key distinguishing points of DCI as compared with other approaches that are similar on the surface.

But first of all I just want to say that I think you may be taking Trygve's draft document of a DCI meta-model (or "illusion" or whatever we're calling it) too literally, or at least not sufficiently acknowledging that it's just a starting point and can be made much less implementation-specific (i.e. based on overarching ideas rather than his Squeak implementation)...

With regard to the "sea of disembodied 'role' methods", if we're going that route then we may as well just use multi-paradigm design, where instead of roles, we create mini-services according to the role boundaries that take role players as arguments (or as Ant called it, "micro SOA"). In terms of the underlying implementation, that's essentially what injectionless DCI is, but I don't think that's actually a deficiency most of the time. How often should we really need to use a debugger to determine what roles an object is playing at runtime? And reflection should be used only for a few specific cases (e.g. metaprogramming) rather than the norm. So from the programmer's perspective at least 90% of the time, what difference does it make whether the implementation uses method injection or not, as long as it provides the illusion of role methods being bound and unbound when appropriate? For the other 5-10% of cases when it matters (and it may not even be that much), I agree it's important to improve injectionless implementations to better provide the illusion of role methods belonging to role players. (Since it's all illusion anyway, I think that should be possible, but perhaps we will discover it works better in the end to just make method injection smarter.)

I think the more important question is, why is it better to provide the illusion that we're actually attaching role methods to objects, than to just use multi-paradigm design? You and Trygve have explained many times over the years why you think DCI is superior, and I and others on this group have echoed those thoughts when newcomers and skeptics have questioned why DCI is truly new or truly an improvement over other approaches. At the technical level, role binding is the only feature of DCI that's truly unique; the rest of the ideas in DCI can be implemented with existing programming techniques. As we all know, this has been a tripping point, but I think we continue to insist on getting it right at the programming language level with good reason: it's the linchpin that gives DCI its unique advantage over multi-paradigm programming. That's why I have been so emphatic about the important illusion of a single unified object at runtime that contains both data and behavior.

I think Martin Fowler is right when he calls an "anemic domain model" (by which he means data objects without any domain behavior) an anti-pattern:
The fundamental horror of this anti-pattern is that it's so contrary to the basic idea of object-oriented design; which is to combine data and process together. The anemic domain model is really just a procedural style design, exactly the kind of thing that object bigots like me (and Eric) have been fighting since our early days in Smalltalk. What's worse, many people think that anemic objects are real objects, and thus completely miss the point of what object-oriented design is all about.
http://www.martinfowler.com/bliki/AnemicDomainModel.html

The unfortunate thing about that quote is that he doesn't mention anything about mental models, which are much more essential to object-orientation than the principle of combining "data and process together". But at a technical level, I think he is right that combining data and process together is essential to object orientation. That's also why I think role-object contracts are so important: they help us envision what the object will look like at runtime, and how data and function will interact. It may seem to some that DCI shares many of the same downsides as procedural programming (a particular past thread comes to mind ;) ), but I think the role-object contract addresses that nicely...in fact even more nicely than regular OOP, since you can focus just on the data method/property signatures that are relevant to a given operation, rather than being distracted by all the data-method details.

Taking a more relaxed perspective on all of this, we have to admit that you can get a lot of the same advantages as DCI with a well-designed multi-paradigm / micro SOA approach (or as Quang put it, even "fake DCI" helps a lot). But when we are missing the union of data and behavior in one conceptual unit, we get only Data-Function instead of Data-Context-Interaction. I'm sure this could be better explained with the help of some good analogies...

Den søndag den 12. april 2015 skrev Jonah S <jona...@gmail.com>:
Cope,

Are you saying that the purpose of roles is solely to capture the mental model in code, and that any functional decomposition of the system operation due to the roles is purely incidental?

Assuming I'm hearing you right, couldn't you still say that the purpose of role (I'm speaking now of the conceptual role as it exists in life, with no reference to code) is to divide up our mental concepts in ways that are natural to us?  That is, the mental models we are trying to encode implicitly have value because they slice up our world in ways we understand.  From that perspective, it wouldn't be entirely wrong to say the decomposition in code imposed by those roles has intrinsic value?  Or did I miss your point?

On Sunday, April 12, 2015 at 3:09:43 AM UTC-4, Cope wrote:
Roles don't divide anything up, any more than words divide up a sentence.  They merely express one perception of a named process that we often describe with words, which we have donned Roles. 

I don't recall anyone, ever, on this list, or on any paper, extolling any intrinsic benefit either of role decompsition or of the aggregation of role methods into Roles. All the discussion from the jnjectionless crowd indeed points in the other direction and its mechanics too often become confused with the semantic model. 

I'd love to see concrete counter examples of my claim above, if you know of any. 


Sendt fra min iPhone

Den 12/04/2015 kl. 01.17 skrev Matthew Browne <mbro...@gmail.com>:

On Friday, April 10, 2015 at 12:08:51 PM UTC-4, Jonah S wrote:
Regarding your concern about breaking things into overly small pieces, my understanding is that DCI frown upon that in so far as spreads what should be a single logical unit of system behavior (collaboration among objects) across a network of objects, obscuring that system behavior in the process.  Hence the "error" is not breaking things down into small pieces per se, but shattering coherent units of logic into bits.  However, there is nothing wrong with small pieces when those pieces are the appropriate logical primitives.  That's my understanding, anyway.

Indeed, that's one of the reasons roles are so helpful...they divide system operations into easily comprehensible segments according to the mental model, but you can still see the whole operation in one place.*  You could also organize behavior according to roles in FP without DCI, but you'd of course lose the notion of a role player. Perhaps that's why FP by itself doesn't solve the expression problem.

* Except in the case of nested contexts, which is why nested contexts should reflect different levels of abstraction rather than just being used to divide things up arbitrarily
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
To post to this group, send email to object-co...@googlegroups.com.
Visit this group at http://groups.google.com/group/object-composition.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
To post to this group, send email to object-co...@googlegroups.com.
Visit this group at http://groups.google.com/group/object-composition.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/N0RFIadUgt0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.

Matthew Browne

unread,
Apr 12, 2015, 11:37:25 AM4/12/15
to object-co...@googlegroups.com
You raised an important point here that I didn't address in my last post...what if role boundaries are not the most fitting way to decompose a system operation? If we take an operation and decompose it from a purely functional perspective, the sub-functions that result might cross role boundaries or in any case not be organized by role and role method. We have seen many examples where the structure of the roles aligns nicely with logical sub-functions, but that may have led us to a false sense that this will always be the case. And your point about interwoven use case scenarios is important to consider too.

But if we call that into question then I think we also need to question the concept of "internal use cases" as interactions between internal actors / objects. Maybe for some use cases it's more like a game of chess, where it's less about the "role behavior" of the pawns and other pieces and more about the sequences of moves that lead toward the goal, and the pawns are just a means to an end. For most use cases, there are elements of both, so role methods will usually work well (at least it seems so based on my experience so far).



On 4/12/15 5:24 AM, James Coplien wrote:
There is not, as far as I know, any statement of philosophical purpose to any part of DCI. We have argued that Roles derived from a mental model but the leverage from any such derivation has sorely been lacking in both our argumentation and implementations.

There is something both more dangerous and deep going on here than I originally feared. Consider again the Dijkstra implementation. It comprises a sea of so-called methods (really functions) that we arbitrarily group into Roles. Yet there are no rules for the grouping and no measures of coupling, cohesion, affinity, or any other kind of association that we think of as owing to Role-ness. Perhaps they precipitate from a volitive model but I am not yet convinced that the Role architecture actually aids the reader either in understanding a use case or in understanding the locus of a necessary change. 

In fact the major structure of interest —which is the scenario — is hidden as it is woven into the use cases that hopelessly cut across the Role architecture. 

What value — in any software engineering sense — is gained by the presence of role constructs in a context?

I am still sorting this out in my head and some of these questions are provocatively rhetorical. But for now Roles still retain a position of honor in capturing the important names we use for the objects in a use case and as such are a good part of design. They may not however, be a driver of the architectural partitioning or of any structural part of the system. And that was my main point. It makes me wonder if there is any value in including them in the code.

A Context containing nothing but a sea of disembodied "role" methods would certainly make the folks from the injectionless school happier. 

There is an alternative view which one might call "object oriented" where Role actually do have a function. It relates to the cocretisation of identity. However I cannot yet reconcile it either with the way that injectionless implementations have been confounded with DCI semantics here or with some of the recent clarifications presented here on this list. 


Den søndag den 12. april 2015 skrev Jonah S <jona...@gmail.com>:
Cope,

Are you saying that the purpose of roles is solely to capture the mental model in code, and that any functional decomposition of the system operation due to the roles is purely incidental?

Assuming I'm hearing you right, couldn't you still say that the purpose of role (I'm speaking now of the conceptual role as it exists in life, with no reference to code) is to divide up our mental concepts in ways that are natural to us?  That is, the mental models we are trying to encode implicitly have value because they slice up our world in ways we understand.  From that perspective, it wouldn't be entirely wrong to say the decomposition in code imposed by those roles has intrinsic value?  Or did I miss your point?

On Sunday, April 12, 2015 at 3:09:43 AM UTC-4, Cope wrote:
Roles don't divide anything up, any more than words divide up a sentence.  They merely express one perception of a named process that we often describe with words, which we have donned Roles. 

I don't recall anyone, ever, on this list, or on any paper, extolling any intrinsic benefit either of role decompsition or of the aggregation of role methods into Roles. All the discussion from the jnjectionless crowd indeed points in the other direction and its mechanics too often become confused with the semantic model. 

I'd love to see concrete counter examples of my claim above, if you know of any. 


Sendt fra min iPhone

Den 12/04/2015 kl. 01.17 skrev Matthew Browne <mbro...@gmail.com>:

On Friday, April 10, 2015 at 12:08:51 PM UTC-4, Jonah S wrote:
Regarding your concern about breaking things into overly small pieces, my understanding is that DCI frown upon that in so far as spreads what should be a single logical unit of system behavior (collaboration among objects) across a network of objects, obscuring that system behavior in the process.  Hence the "error" is not breaking things down into small pieces per se, but shattering coherent units of logic into bits.  However, there is nothing wrong with small pieces when those pieces are the appropriate logical primitives.  That's my understanding, anyway.

Indeed, that's one of the reasons roles are so helpful...they divide system operations into easily comprehensible segments according to the mental model, but you can still see the whole operation in one place.*  You could also organize behavior according to roles in FP without DCI, but you'd of course lose the notion of a role player. Perhaps that's why FP by itself doesn't solve the expression problem.

* Except in the case of nested contexts, which is why nested contexts should reflect different levels of abstraction rather than just being used to divide things up arbitrarily
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
To post to this group, send email to object-co...@googlegroups.com.
Visit this group at http://groups.google.com/group/object-composition.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
To post to this group, send email to object-co...@googlegroups.com.
Visit this group at http://groups.google.com/group/object-composition.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to a topic in the Google Groups "object-composition" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/object-composition/N0RFIadUgt0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to object-composit...@googlegroups.com.

Trygve Reenskaug

unread,
Apr 16, 2015, 5:42:03 AM4/16/15
to object-co...@googlegroups.com
My latest version of the elephant paper is the one you published (with and without my comments). I rather suspect this is the latest version. I like this paper and it would be great if it could be published somewhere. Its current form is OK IMO.

James O Coplien

unread,
Apr 16, 2015, 6:56:27 AM4/16/15
to object-co...@googlegroups.com

On 12 Apr 2015, at 17:37, Matthew Browne <mbro...@gmail.com> wrote:

You raised an important point here that I didn't address in my last post...what if role boundaries are not the most fitting way to decompose a system operation?

1. Yes, that follows from the discussion.

2. It is an interesting question.

3. Do we have a nice example?

Matthew Browne

unread,
Apr 16, 2015, 9:05:44 AM4/16/15
to object-co...@googlegroups.com
I haven't thought of a really good example yet, but we may be able to take inspiration from one of the examples in this book:
https://books.google.com/books?id=O45eBAAAQBAJ&printsec=frontcover#v=onepage&q=decomposition&f=false

I'll take a closer look later and see if I can find one that illustrates the issue we're discussing...

Raoul Duke

unread,
Apr 16, 2015, 12:13:21 PM4/16/15
to object-co...@googlegroups.com
I thought the whole point of Context & Roles was that they were the
Right Way to decompose the system?

James O Coplien

unread,
Apr 17, 2015, 1:09:55 PM4/17/15
to object-co...@googlegroups.com

> On 16 Apr 2015, at 18:13, Raoul Duke <rao...@gmail.com> wrote:
>
> I thought the whole point of Context & Roles was that they were the
> Right Way to decompose the system?

How could that be?

Let’s say that you view the world (or a program) in terms of its objects. What is the “whole” that you start with, which you then slice up in a way that results in Contexts?

Within a Context, what is the behavioural “whole” that you divide up that results in Roles? A use case decomposes into scenarios, and scenarios decompose into methods. A set of Roles is a set of compositions over this lowest-level decomposition. That’s really weird if you think about it. I think there may some insight to be gained from some kind of two-phase process like that. I haven’t yet found how it falls together.

Again, I am beginning to believe that the real power of Roles may be naming, apart from grouping. I understand that there may be a paradox there but now believe that it may not necessarily be so.

Matthew Browne

unread,
May 3, 2015, 3:00:24 PM5/3/15
to object-co...@googlegroups.com
I tried to come up with some examples of where a role-based decomposition would differ from a purely functional decomposition and it was harder than I expected...I thought perhaps I could find a simple business use case example, but my tentative finding is that in business software, most of the functions and sub-functions involve analyzing or transforming some particular data, so it makes sense from a functional perspective (and not only a data perspective) to decompose the system operation into methods on role-playing data objects. Of course, it could also just be my own bias.

However, with more complex algorithms / number crunching (which perhaps is more common outside of database-centric business software), I think a divergence between the two may be more common. For example, consider this algorithm to compose musical melodies:
http://lenmus.sourceforge.net/en/paginas/composer-algorithm-pitch

The only real data objects are the chords (and that notes they consist of), which are used as the input, and the notes that are generated by the algorithm. But there are a lot of sub-functions of the algorithm, and having them all be methods of role-playing chord or note objects might be more confusing than helpful.

Here's another example, of an algorithm to generate a fractal:
http://nakkaya.com/2009/10/04/fractals-in-clojure-buddhabrot-fractal/

(I don't have much experience with functional programming so I found it difficult to follow the code...someone with more functional programming experience may be in a better position to offer additional insights and examples.)

And I'm sure these sorts of algorithms (that are less focused on data objects) come up in business software too; we just may need to look at more complex use cases to find them.

~~
Finally, here's a good theoretical perspective I found about this issue:
Algorithmic versus Object-Oriented Decomposition

Which is the right way to decompose a complex system—by algorithms or by objects? Actually, this is a trick question because the right answer is that both views are important: The algorithmic view highlights the ordering of events, and the object-oriented view emphasizes the agents that either cause action or are the subjects on which these operations act.

However, the fact remains that we cannot construct a complex system in both ways simultaneously, for they are completely orthogonal views. We must start decomposing a system either by algorithms or by objects and then use the resulting structure as the framework for expressing the other perspective.

Our experience leads us to apply the object-oriented view first because this approach is better at helping us organize the inherent complexity of software systems, just as it helped us to describe the organized complexity of complex systems as diverse as computers, plants, galaxies, and large social institutions. Object-oriented decomposition has a number of highly significant advantages over algorithmic decomposition. Object-oriented decomposition yields smaller systems through the reuse of common mechanisms, thus providing an important economy of expression. Object-oriented systems are also more resilient to change and thus better able to evolve over time because their design is based on stable intermediate forms. Indeed, object-oriented decomposition greatly reduces the risk of building complex software systems because they are designed to evolve incrementally from smaller systems in which we already have confidence. Furthermore, object-oriented decomposition directly addresses the inherent complexity of software by helping us make intelligent decisions regarding the separation of concerns in a large state space.
http://www.drdobbs.com/windows/software-complexity-bringing-order-to-ch/199901062

I don't think the claims above hold in all situations — as I think the examples above show — but my experience with most of the systems I have worked with does confirm it. The key of the above quote is this line:
The algorithmic view highlights the ordering of events, and the object-oriented view emphasizes the agents that either cause action or are the subjects on which these operations act.
DCI emphasizes objects and the flow of messages between them, but is less focused on the sequence of events. In one sense, DCI is very concerned with timing — it helps us better conceptualize/imagine future interactions — but I agree with Cope that we may have possibly hit upon a weakness of role-based decomposition here, even if it only turns out to be an issue in a relative minority of cases...
Reply all
Reply to author
Forward
0 new messages