Whither OO

195 views
Skip to first unread message

James Coplien

unread,
Jan 2, 2023, 6:50:57 AM1/2/23
to noreply-spamdigest via object-composition
I have been chatting with a brilliant guy named Felix Hovsepian whom I respect a lot, and who seems to be of like mind as I am on many things computing-related, about whither OO. He’s strongly enthusiastic about the possibility that we’ve been getting OO wrong all of these years so he has a keen interest in DCI. He approaches software engineering from an AI background (a very sober, grounded, pragmatic form of AI).

He recently posted on LinkedIn (https://www.linkedin.com/posts/felixhovsepian_hardest-programming-distributedsystems-activity-7011613687769649153-_DAu/) pointing out that Kay likens OO to distributed systems — a metaphor that Trygve also occasionally invokes.

PastedGraphic-1.png

He goes on to point out that the problems of distributed systems are some of the hardest problems we have in programming, and I think he’s right. I worked for 20 years at AT&T, which is kind of in the middle of distributed-systems-land, and one implemented distributed solutions only with great fear and trepidation.

First, I think there may (or may not) be a disconnect here because there is a difference between distributed and nondeterministic systems. DCI is distributed (multiple interacting objects) but deterministic (a use case, with the formal semantics and computational complexity of algorithms). I think the complexity of distributed systems owes to having multiple time bases, and DCI is not that. Whether the notion of multiple tiime bases is fundamental to Kay’s vision is unclear. It is not fundamental to DCI.

As preface to what follows, I’ll give a couple of definitions, because different parts of CS use these terms differently. By concurrent I mean multiple simultaneous activities; i.e., multiple time bases. By parallel I mean multiple, largely independent sequences of computation whose flow of control or results may be influenced by interactions with other such sequences. By this definition, most concurrent implementations (like a Transputer or the Internet) have parallelism, but parallel implementations need not have concurrency (e.g., Simula — or vulgar OOP).

The disconnect aside, Felix's post awakened a nagging feeling I’ve harbored over the years about what exactly Kay’s vision was, and about the degree to which DCI rises to the occasion. I’ve been doing some playing around with these ideas over the past year and finally have created a talking point — in code — of an example that I think is closer’s to Kay’s vision. The real-world example on which it is based is very distributed, and the program feels distributed, but really is simulating concurrency (multiple time bases) with a single time base (it, after all, runs on a single CPU). This is in a large sense what Dahl and Nygård were striving for in Simula: to give the illusion of concurrency in a parallel programming language.

What’s interesting about this example is that Roles don’t stand out as major building blocks, except to the degree that they support the scaffolding for graphics and for mundane housekeeping (e.g., ensuring that two objects do not overlap on the screen, or ensuring that no object gets stuck going in circles but at least makes some progress along the axis of partial recursive reduction). Maybe that’s because the example is too simple; I don’t know. It in any case as a much different “use case” feel than you find the UML people discussing.

And it may be that folding concurrency onto a parallel-only world loses at least some potential efficiencies, as well as potentially losing important semantics that might owe to concurrency. One big different is that any sane mapping of a concurrent world onto a parallel world necessarily uses discrete time, whereas this is not true of concurrent worlds. There can be simultaneity in a parallel world but there is simply no simultaneity in a concurrent world: Heisenburg runs rampant here.

If Kay really meant that the Internet is the only OO system that we have (and why should we think otherwise?), then it’s certainly not about use cases. But it is about local independence and local, simple decision-making and autonomy — which is largely what he seems to mean by messaging. And my example squarely brings that out.

With that as a background I posted the following reply to Felix’s post, including a link to my latest trygve example of what might be a “more object-oriented” talking point.

I struggle with "OO as distributed systems." Indeed, distributed systems are hard. In DCI we address that with a static, local representation of a dynamic, distributed algorithm. The dynamics unfold at run time in a controlled way. This is Trygve Reenskaug's understanding of OOP: a use-case-based approach. Most Nordics or Nordic-influenced OO approaches (like the Three Amigos) have had use cases in the background.

I think that Kay maybe started there; his early papers make this clear. However I think he ended up elsewhere — as above, at the metaphor of distributed systems. He has also quipped that the Internet is our only contemporary example of an object-oriented system, and that early on, we got our objects too small. I think his real vision is about emergent behavior in systems centralized control, without any a priori algorithm design. As the Internet shows, that can work. But it isn't the DCI vision, and it isn't how anyone I know programs today.

This is why I think that my most recent trygve program is closer to what Kay's vision is. The intelligence is local, minimal, and distributed, yet generates powerful and deterministic emergent behavior.


By “[Kay’s] early papers make this clear,” I’m referring to this, from Kay’s landmark (but only recently published, I think) 1972 paper:

PastedGraphic-2.png

I think this is worth exploring, first and foremost from the perspective of any historic grounding or published psychological research that can be brought to the fore.

Has anyone else had the same reservations about DCI?

Raoul Duke

unread,
Jan 2, 2023, 7:22:24 PM1/2/23
to object-co...@googlegroups.com
very interesting to read.

sounds right to me, as a joe day job programmer in the street, that time is the hard thing moreso than breaking up and distributing. although of course the network is not reliable per N Rules Of Distributed Computing, and locking is hard to get right, so even if we had global linear time we'd have other things failing on us randomly to keep life interesting. even if in theory a partial ordering would be logically ok for the system, the problem is that when a human has to debug wtf went wrong, the state space we have to keep in mind explodes as we move away from 1 single linear time truth. ... locally, things like deterministic dataflow have always appealed to me tho i've not used it 'in anger' ever. distributed actors + logical timestamping -> reactors.



Unmesh Joshi

unread,
Jan 4, 2023, 1:13:43 AM1/4/23
to object-co...@googlegroups.com
Hi Jim,

This is interesting. Particularly the mention of distributed systems in the context of OO. I have been trying to document patterns of distributed systems for the last few years. My goals were limited, to understand the architecture of all the modern cloud services or products like Kafka/Cassandra, etc. And to be able to build them one piece at a time.
I see that one of the key design goals of distributed systems is to work towards managing the client's expectations about the consistency of the data they interact with. 
A few years ago, I tried to document similarities between concepts of MVC and how most microservice designs are done today—specifically focusing on ideas of Aggregates that add a notion of transactional consistency to Objects. 
I built a small prototype of a movie booking system. I called these 'Aggregate Oriented Microservices'... (I really do not care about the word 'microservices' here). 
The example there probably maps to what you refer to as 'atomic event architecture' and not DCI per se. 

Thanks,
Unmesh




--
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 view this discussion on the web visit https://groups.google.com/d/msgid/object-composition/1D2FBD4C-9B34-4F01-A5CE-8B9D3961E87F%40gertrudandcope.com.

Dom

unread,
Jan 9, 2023, 5:30:46 PM1/9/23
to object-composition
Hi Cope

There are many deeply fascinating questions here.

Has anyone else had the same reservations about DCI?

Is your question whether DCI rises to the challenge of enabling and representing independently acting objects without itself being fundamentally concurrent or distributed?

Dom

Dom

unread,
Jan 11, 2023, 11:45:44 AM1/11/23
to object-composition
Hi Cope

I'd like to start with a couple of rhetorical questions to frame my attempt at an answer.

First (cynical): Why try to decode and follow a vague vision from 40 or more years ago [1] (video)? Isn't this just a case of (cynical/funny) "The Shoe is the Sign" [2] (video)?  Alan Kay seems clear on what was not meant by OO (famously C++).  If the OO that he intended was so much better, why did he not go on to implement the real thing in the subsequent 40 years?  VPRI, which ran from 2002 - 2018,  included amongst its aims "Inventing Fundamental New Computing Technologies" [3] surely this would have realized a new OO?

As to why hasn't something already been done - I think that inventing new paradigms, OO or otherwise, is extremely difficult. The fact that it is hard is not a reason not to try.  I have been writing programs for over 40 years and I know that I am not satisfied with where we are today. I have been writing C++ for a quarter of a century, so ought to have a good sense of what OO is not intended to be.  Hopefully that makes for a solid start.

As to the vision: sometimes the original expressions of the underlying ideas, free from the baggage and assumptions, have a fresh clarity.  They also contain suggestions as to the paths not taken.  There may be many reasons why one path was taken over others. With today's technology, and what we know now (if we can filter out our assumptions) it may be that one of the paths not taken would now hold answers.

Oh, and it is fun :)

Second (a fair question): What do I know about DCI?

Ultimately the good folks here will be the judge :)

Since 2018 I (with others) have been using something that I think you would recognise as DCI.  We have been incorporating it incrementally and shipping with it.  I'm not sure what a good DCI metric would be, but we have 111 contexts containing 444 roles being used in two major sub-systems of the product.  The system is concurrent and distributed (in the hundreds of network connected computers sense).

I like DCI, a lot.

With that out of the way, Cope asked: Has anyone else had the same reservations about DCI?

I don't know that mine are the same reservations, but here goes...

There is a great deal that DCI gets right, but I think there is something missing that does fall into the realm of what it should seek to address.

DCI doesn't have anything to say about concurrency, but I don't want to start with this as I think there is something more fundamental.

For me, the issue is what Kay called Modularising Control [4] (video), and, at VPRI, described as the "field" side of the { "particle" (objects) : "fields"(messages) } duality:

"Part of the key to success is that not just the “particle” side of things has to have a good model, but also the “field” side (which is often almost neglected in so-called “object-oriented” programming which is usually anything but). The “field” side has to do with messaging and events, the interstitial side of interactions (which is almost invisible because the concreteness of the objects takes too much of the center stage). In fact, the objects and the messaging system form duals of each other and have to be kept in balance for the most powerful and compact modeling." [3]

To my mind this concept of Modularising Control is in some sense more fundamental than the distributed/concurrent question.  Modularising Control would provide the tools to be able to better express concurrency, and control flow generally.

I don't think that Kay had the answer to how Modularising Control would be done, albeit he does reference work in this area.  His sketches in the seminar video seem to me more conceptual.

So what do I mean by Modularising Control?

First, what is Control?

When we look at code there will be parts that do the actual work of combining values to compute answers, and other parts whose job is firstly to get the program counter (which moves implicitly from statement to statement) to the parts of the code that will compute the answers, and secondly to gather the data to do the computing (function arguments for example).  It is the guiding the program counter and gathering the data that is the Control.  We are so used to the necessity of writing and reading it that it hides in plain sight.  It is a huge source of non-essential complexity (see Out of the Tar Pit [5] (pdf) for an eloquent treatment of this).

Being able to see the Control there in the code can be re-assuring, especially for novice programmers.  After all, when it is all visible you can see exactly what will happen.  Right? Really? Is it always easy to follow?  Is the order in which it is doing things really essential?

Control code by its mere presence can obscure intent.  Swathes of Control code can leave the code brittle and hard to change.  Control is the opposite of a shearing layer, it is all glue.  The computation part can end up like an insect trapped in amber.  You can see it, indistinctly, but you can't extricate it without risking destroying it.

Code with less Control we usually describe as being more declarative.  The dark side to this can be that, if we don't understand the implicit rules behind the declarative form, the code can appear "magical". Even small scale "magic" like argument dependent method dispatch (virtual functions in C++), used inappropriately, can become "hyper-galactic gotos" that could take your precious control anywhere. There is a balance to find.

So what of Modularising?

We are used to modularising code artefacts in many ways: Into files, data types, classes, functions etc.

DCI helps to modularise behaviour into contexts, extracting behaviour specific state and functions from domain objects, extending objects' functionality through roles to meet particular tasks.  DCI contexts could be seen in this way as "Feature Modules".

However, from a Control perspective, DCI contexts are still very much like functions.  They are provided arguments (objects that will play roles) and are executed by the external system calling a method on the context.  They may recursively create further contexts and execute those.

A DCI context gets to execute only as allowed by the surrounding Control, when it is called.  It has modularised much of the representational aspects of state and behaviour, but is still dependent on Control.

A context cannot be lifted out of one part of a program and put into another part without the Control in that other part of the program being modified to provide its life support.  It has no independence in this regard.  If a Context has some part of itself that needs to operate autonomously over time, or uses some other Context that does, it cannot do so without the surrounding Control being adapted to provide control to it whenever and wherever it needs it.

Modularising Control is about finding a way of freeing objects (contexts) from their dependency on surrounding Control.  From a DCI perspective we want Contexts to encapsulate Control as well as State and Behaviour.  Remember, Control is not Behaviour.  Behaviour is what happens as a result of Control passing through the code that expresses behaviour.

Modularising control does not necessarily imply concurrency.  A system that has modular control must provide mechanisms for modules to be composed and engage with each other, as collaborating objects must.  Control must be extracted and "modularised" in some way, as we already do for other things.  The question is "How?".

The "something" that carries Control through and between modules (objects or "particles") might be what Kay describes as a "field".

He imagines the possibility of objects that only receive messages; messages that provide the values that the objects wants.  This suggests an expectation of emergent behaviour that I think people find hard to envisage beyond systems that have evolved.  Whilst this clearly does happen in biological systems, I am still at a place where I imagine software being more deliberately designed.

We already have other approaches to modularising control. Systems such as Erlang and Actors can be seen as putting control modularisation first.  Each component (process/actor) having its own independent flow of control.  This frees them from the tyranny of Control but comes at a cost when building certain kinds of systems.  At the extreme end, the non-determinacy of the actor model, whilst very general, makes some otherwise simple things extremely hard to reason about.  These independent control models are essential for physically distributed systems, if only because the hardware run them on introduces all of the same uncertainties - they cannot be wished away.

My observation is that all forms of modularisation (state, behaviour and control) are scale dependent.  Different approaches can and should be taken at different scales of representation.  We have to be prepared to be more Actor like on physically distributed systems, whilst at close quarters, where there are fewer failure modes, we can adopt other models that are easier to reason about.

In summary

My reservation is that DCI doesn't have a story around modular and composable control beyond regular procedure calls at the scale of contexts.

I believe that DCI needs this because, for composition at some scales, Control concerns will overlap DCI contexts. DCI contexts shouldn't be limited to being atomic with respect to Control.  A Control composition mechanism is a pre-requisite for having a good story about concurrency broadly.

A couple of illustrative examples:

Consider an application that performs some long running tasks and wants to provide a web interface for users to monitor progress.  Both the long running task and the web server will require Control in order to do their work.  Much of the work of one will be completely independent of the other.  The application will be computing results whilst the embedded web server will be listening for incoming socket connections, reading and decoding HTTP requests and so on.  When the web server wants the application to render its status as HTML (or JSON or whatever) to send to a browser, the two worlds will collide.  The two parts could be quite separate, live on separate threads and communicate through shared message queues using custom written Control that would coordinate access to this.  But suppose we wanted them to live on one thread?  Could we envisage modularising their Control requirements such that we could do this?  Could DCI + something tell a story as to how this might be done?

Consider Cope's recent trygve example that simulates the "Self Organization Game" [6] in which players, initially arranged in a circle, secretly choose two others players and then try to position themselves equidistant from the two.  The example simulates the actions of each independent player and their dependencies on the positions of just two of the others.  Eventually the system as a whole converges on a solution to demonstrate self-organization.  The implementation is in a single DCI context running on a single thread.  The code consists of the computations performed by each player, rendering code to display the state of the game and Control code that must join all of the pieces together, passing Control to each player as necessary and to the renderer as things change.  There is non-trivial complexity in the Control code as it propagates player position changes, guards against infinite recursion, renders updates periodically and so on.  Clearly Control is necessary in some form to run all of this on a single thread, but could some mechanism for Modularising Control allow some of these parts to be separated and then composed?  If we were to create long lived contexts for each player and their selected targets, in which their movements could be planned and calculated, we would separate this from other aspects of the implementation.  If we did this, how might we compose the Control required by these individual contexts with that of the others, the propagation of changes in player positions, the rendering and so on?

I would not be surprised to find adhoc Control implementations in both of these examples, indeed I might not even "see" all this code "hidden in plain sight" for what it really it is because it is ubiquitous, it is always there.  We expect it and read it as somehow an integral part of the program.  But it need it be?

Spoilers

To adapt DCI to work in our concurrent system I have extended it with one new idea. This seems to have worked well so far.  It was only in the writing of this reply that I revisited the video of Alan Kay's old OO seminar and started to make a connection to his concept of modular control. More soon...

Dom

[1] Seminar with Alan Kay on Object Oriented Programming. https://www.youtube.com/watch?v=QjJaFG63Hlo
[2] The Shoe is the Sign - Monty Python. https://www.youtube.com/watch?v=Ka9mfZbTFbk
[3] Inventing fundamental Computing Technologies - VPRI. http://www.vpri.org/work/ifnct.htm
[4] Modularising Control (in [1] Seminar with Alan Kay on Object Oriented Programming) https://www.youtube.com/watch?v=QjJaFG63Hlo&t=5775s
[5] Out of the Tar Pit - Ben Mosely and Pater Marks. https://curtclifton.net/papers/MoseleyMarks06a.pdf
[6] Self Organization example in tygve - Jim Coplien.  https://github.com/jcoplien/trygve/blob/master/examples/selfOrganization.k


Quang

unread,
Jan 11, 2023, 9:36:00 PM1/11/23
to object-composition

Interesting....A while ago, I did experimenting DCI for robotic programming like: ROS: https://www.ros.org/.  Each component of the robot has its own "actor" (chip/CPU/Timer).

Quang

unread,
Jan 12, 2023, 12:56:54 AM1/12/23
to object-composition
This is the video I found, Alan talked about messaging: https://youtu.be/QjJaFG63Hlo?t=3799

James Coplien

unread,
Jan 12, 2023, 4:10:39 AM1/12/23
to object-co...@googlegroups.com
My DCI “control” models originate in the end-user mental model. I don’t think that my control models (Contexts) have these problems. The self-organizing game may be an exception because, there, I am trying to shoehorn my understanding of Kay’s model into the potentially foreign model of DCI.

The recursion check (and much other stuff) in that program are optimizations and the program might “work” (at least on paper) without them.

I think the problem of concurrency is independent of objects, unless one goes all the way to a pure Actor vision. Concurrency should again reflect the real-world model so as not to introduce accidental complexity. Folding a truly concurrent system onto a merely parallel framework (like Simula-67) also adds accidental complexity in the end I believe that DCI makes this neither better nor worse than anything else. The question that remains, is: was it part of Kay’s vision?

As for events and messages: While studying Kay I still can’t see much of a difference between Kay’s messages and synchronous method invocations ー except for the place of the method selector, and therefore of late binding, and therefore of giving the operand object the choice of what to do with each message request.

Sending event messages to multiple objects in parallel is roughly equivalent to the master FOR loop in the self-organizing game. We can probably find that loop somewhere in your code. I can see how it can be a powerful technique together with some engineering rules and experience, but I would tentatively put it on a par with GOTOs and exceptions as it’s prospects for being a *general-purpose* programming technique. For what you are doing, though, it may be brilliant.

What problem do you think it solves (in the sense that DCI addresses the problem of poorly partitioned code that is hard to understand and evolve)?

DCI is supposed to make code easier to understand. Distributing the handling of a single event (which is just a message in a Von Neumann world) across several objects works against that: there is no locality of reasoning about the event. (At least with the FOR loop, there is.) A better solution, IMHO, might be to think along the lines of multiple dispatch. I think DCI rises to the occasion (as per the Elephant paper).

Dom

unread,
Jan 12, 2023, 8:04:03 AM1/12/23
to object-composition
I'm keen to talk more about the ideas that I have been working with, and allude to above, but I'd like to make sure that find a good way to express how these stand in relationship to DCI.

Ideas in context

I've seen a number of very spirited discussions on the list about what does and does not constitute DCI.  These have an essential purpose in clarifying and defining the DCI ideas and enabling the use of the term "DCI" as a compression of the ideas it represents (my understanding has benefitted from studying these discussions).  Since I've been making something that is not "DCI" by this measure I'll call it something different: "EDCI".  If anyone objects to the term, or feels it suggests some relationship to DCI that would introduce confusion, then I'm happy to call it something else.

First, let me try to place the two things in context.  I'm, aware that I haven't yet explained the nature of this thing, so this will be somewhat abstract, but I'm keen to avoid falling afoul of terminology.

Purely for the purposes of drawing a distinction, let me offer this somewhat abstract perspective to help to tease apart the relationship, as I see it, between DCI and EDCI.

Philosophy + Mechanisms

One way to look at DCI is as a philosophy plus implementation technology that supports its expression in code.

The philosophy has goals and says things about what one should and shouldn't do if one values those goals.

The technology (practical implementation in languages) adds a number of Mechanisms to a base language (or provides them in a new one like trygve) to support programming in a way that can meet the goals of the philosophy.

Most practical (in the sense that they exist and you can write programs with them) DCI implementations currently take a base language and add DCI supporting Mechanisms in some way.  This may entail a mix of convention, direct implementation (mixins etc) or language extensions (going beyond the base language).  In particular the Mechanisms support the expression of the DCI concepts of Contexts and Roles in the host language.

EDCI's relationship to DCI

1. Mechanisms

EDCI takes the DCI Mechanisms and adds a new one, which it calls "Events".  Events build upon, but are are orthogonal to, the existing DCI mechanisms. Pure DCI is still possible on an EDCI implementation if you don't use Events.

If you use EDCI Events in a program you may be doing something that doesn't fit with the DCI philosophy. In the same vein one might use other non-DCI features of your base language to do things that fall outside of the DCI philosophy (hopefully only for pragmatic reasons).

The EDCI Event Mechanism is different to other non-DCI base language features that might happen to exist in a (multi-paradigm) base language in that it relies and builds upon DCI Roles and Contexts.  You can't have EDCI Events without the DCI Mechanisms.

2. Philosophy

EDCI attempts to take the DCI philosophy (with its many benefits) and apply it to a domain that DCI doesn't explicitly speak to (a concurrent one in our case).  To do so it has to resolve any areas of conflict and the ideas must be adapted or give a little.

So, whilst the EDCI Mechanisms are an additive superset of the DCI Mechanisms, the EDCI philosophy is not a superset of the DCI philosophy.  EDCI philosophy likely relaxes or breaks some tennets of DCI philosophy, so it admits the possibility of doing things that fall outside of what DCI would allow.

Looking forward

I'm not saying that DCI should be EDCI. They are different, and this is ok.  My hope is that there is something interesting in the differences that may help to cement or bring new understandings.

In building EDCI we stand on the shoulders of giants: Cope, Trygve, Kay and many others.  We may well fall off, but that is our lookout.  And I'd hate not to try!

Back to the question

Since EDCI is strongly inspired by, yet different to, DCI and there is some path of transference of vision and ideas from Kay -> DCI -> EDCI. I'm intrigued by what a discussion of the differences between all of these ideas might reveal.

Cope, does your question suggest that you have some reservations about DCI today, or are you wondering if anyone else has any that might shed light, provide a different perspective or provoke discussion?

Dom

unread,
Jan 12, 2023, 12:00:21 PM1/12/23
to object-composition

On Thursday, January 12, 2023 at 9:10:39 AM UTC Cope wrote:
> The recursion check (and much other stuff) in that program are optimizations and the program might “work” (at least on paper) without them.

Yes.  These parts are examples of non-essential complexity (not in the user's mental model) from Control.  There is nothing wrong per se, all programs have some of it, but it adds to complexity.  Different languages mechanisms can reduce some of it in some circumstances.  My sights are in complexity around concurrency.

On Thursday, January 12, 2023 at 9:10:39 AM UTC Cope wrote:
> My DCI “control” models originate in the end-user mental model. I don’t think that my control models (Contexts) have these problems. The self-organizing game may be an exception because, there, I am trying to shoehorn my understanding of Kay’s model into the potentially foreign model of DCI.
> I think the problem of concurrency is independent of objects, unless one goes all the way to a pure Actor vision. Concurrency should again reflect the real-world model so as not to introduce accidental complexity. Folding a truly concurrent system onto a merely parallel framework (like Simula-67) also adds accidental complexity in the end I believe that DCI makes this neither better nor worse than anything else. The question that remains, is: was it part of Kay’s vision?

Some thoughts on Control below. I'll return to your other points and our "Events" later and try to show how I think they can help...

In a sequential program the Control is manifest in the program text that does the for loops, function calls and all that stuff - steering the program counter flow (like the recursion check you identified above).  This is neither what the program is (Data) not what the program does (Interaction/Behaviour), it isn't in the user's mental model.  We have the "user program" that corresponds to the user's mental model plus this non-essential Control baggage.

In a concurrent program we have the same "user program" (corresponding to the users mental model), but the Control baggage can be much more significant.  So much so that this can be considered to be another program in its own right that is keeping track of the different, concurrent things that the "user program" is doing.  This activity is invisible to the end-user, and isn't part of their mental model.  I'll call this the "control program". The programmer must have mental models that encompass both of these programs.  This contributes to concurrent programs being much harder to understand.

In control-modularity-first concurrency oriented languages such as Erlang there is a clean separation as components of the "user program" run as individual, shared nothing, processes under control of the Erlang VM - its "control program".  Both programs are there, but distinct because of the emphasis the language places on control-modularity.  An Erlang programmer has to write programs the Erlang way, but doesn't have to concern themselves with writing the "control program", it is all implicit in the language.

In concurrent programs in other languages there is unlikely to be a clean separation between these two notional symbiotic "programs".  They are complected and interleaved together.  You can see exactly this in the Self Organization sample which has both a "user program" for the game, and a "control program" providing control in the style of Kay's model. You have to mentally separate them, but they are both in there.

If we look at the "control program" aspect through the lens of DCI we see that what the "user program" does (is doing) is what the "control program" is (Data) and what this "control program" does (Interaction/Behaviour) is facilitate the execution of the "user program".  Does that make sense?

What I'd like to do is use DCI for both of these complected programs at the same time.  In order to do this I want to be able to use Contexts to hold what the "user program" is doing (so far so normal) in such a way that the "control program" part can see these Contexts as its Data.  I don't mean in the VM or language run-time sense, but co-existing in the same program, blended.  Bear with me.

In DCI, contexts can play roles, so we are part of the way there already.

If we had long running "user program" contexts that play roles (as Data) in "control program" contexts we can merge the two aspects of these "programs" using the same DCI-like paradigm.  The key to be able to do this easily is to minimize what our controlling context needs to know about the "user program" contexts it is holding and their requirements for receiving control flow (so they can do things).  We want to be able to compose contexts such that they can execute with a degree of independence of the structure holding them, and, crucially, without it the holder having to know about every external event that it might need to pass in to them (control flow).  This independence requires control modularity and composability.

I suspect that this is going to need an example to make things concrete.

I must stress that these ideas aren't needed for sequential programs (except perhaps those that seek to emulate some other control style...).  DCI has sequential programs covered, and already makes them easier to understand.  However, concurrent programs are so much harder (in my experience) that even if introducing some additional Mechanisms into DCI adds complexity, we can still be looking at a win overall.

Raoul Duke

unread,
Jan 12, 2023, 12:25:14 PM1/12/23
to object-co...@googlegroups.com
> DCI is supposed to make code easier to understand. Distributing the handling of a single event (which is just a message in a Von Neumann world) across several objects works against that: there is no locality of reasoning about the event. (At least with the FOR loop, there is.) A better solution, IMHO, might be to think along the lines of multiple dispatch. I think DCI rises to the occasion (as per the Elephant paper).


my personal belief is that we suffer from the tyranny of the dominant
paradigm, whatever that is, or whatever those N paradigms in the core
language are. in particular, i think ascii 2d walls of text in files,
no matter how you try to split them up, are a fail in the long run.
the inherent problem is that in reality many things are
multidimensional, and we thus far mostly utterly fail to have great
tooling to manage things in a multidimensional way. by that i mostly
mean being able to look at things from different views / perspectives.

as one small example, a classic problem with debugging OOP especially
when inheritance is in play is that as you say the handling of a
single event gets split up too much and one finds oneself bopping
around many different files and chunks of code, and one has to rebuild
a mental model of what the final behaviour is vs. should be. whereas
if we had the ability to convert the whole thing into a more
"linearized" form even in ascii as bad as ascii is, we as humans would
more be able to see what the sum total of the code is at any given
point.

sandy klausner's coretalk was a hilariously vapor ware slide deck in
the end, but the meme it was pushing was one i really liked in this
regard.

Quang

unread,
Jan 12, 2023, 12:37:12 PM1/12/23
to object-composition
fun fact, when I "got" DCI...debugging OOP becomes much easier...something similar to this: https://youtu.be/-j2XrT0QN5A :)

Raoul Duke

unread,
Jan 12, 2023, 12:49:56 PM1/12/23
to object-co...@googlegroups.com
> > fun fact, when I "got" DCI...debugging OOP becomes much easier...something similar to this: https://youtu.be/-j2XrT0QN5A :)

makes sense to me, and one of the reasons i am interested in dci for sure!

yet overall i currently believe there are too many
non-feature/non-use-case things involved for there to be a single
paradigm that works however, much for the same reasons that people
invented and experimented with aspect-oriented or feature-oriented
programming, again none of which fully resolved all the issues with
software development.

Quang

unread,
Jan 12, 2023, 12:58:07 PM1/12/23
to object-composition

I remember Trygve mentioned that he was not sure about the role of the observer pattern in DCI. He still needs to use it for the Model to View communication.
I worked in 3d/game interaction application, so I constantly have to deal with non-user interaction control.
Each object in the scene has its own simulation in an nondeterministic way, after an interesting event, somehow some objects need to work "together" to do something interesting in an deterministic way.

In DCI spectrum, we have atomic event to context (even nested context). In theory, we can use on giant context for entire program with a lot of nested context...but it seems impossible to program that complex context.
In the practical world, we have modules, libraries, language barriers like Dom said.

For me, I try to think about Kay OOP as: 1. messaging 2. simulation --> messaging simulation.
So messaging simulation is the key to me. We can simulate message with all the tools we have: method invocation, sending event object locally/remotely.
The task of the designer is to chose which tool for the job, sometimes it has to be very strong coupling (method call) and sometimes we need to accept some degree of loose coupling (event).
Each of them will have some trade-offs. We was not happy with spaghetti code with strong coupling everywhere, but I was amused that we move to fully loose coupling with events everywhere and hope it will be OK :)

For practical reason, I now do this:
1. Control flow is clear and concise within the context.
2. Someone somewhere needs to trigger the context (could be from UI interaction, or a timer).
3. Object composition means we compose role object interaction within the context.
4. Sometimes, we still need to simulate async messaging. e.g a context triggered in "Model Module" should update the Model correctly, then trigger event for the "View Module". The View Module can in turn trigger its own context.
It is something like bounded context in DDD but just for communication between contexts, and where to sub-divide context into nested context or "wire" them via event.
One benefit I can think of: the context in Model Module just must succeed or fail as a whole (transaction???). The context in the View Module can be rerun anytime to update the UI.

On Thursday, January 12, 2023 at 9:25:14 AM UTC-8 raould wrote:

James O Coplien

unread,
Jan 12, 2023, 2:06:06 PM1/12/23
to object-co...@googlegroups.com


On 12 Jan 2023, at 18.58, Quang <wan...@gmail.com> wrote:

So messaging simulation is the key to me

Please define what you mean by “messaging."

Quang

unread,
Jan 12, 2023, 2:40:32 PM1/12/23
to object-composition
Nope, I can't...If Alan could not articulate that well enough for us to understand, and we as entire industry still cannot do messaging "correctly"  according to Alan :)

Joke aside. I got the simulation from Simula, and messaging from Alan, hence the messaging simulation (both from learning things here anyway).

Messaging to me is from life simulation. I am not sure if rock can send and receive message but it looks like whale and human can do that.
So let use human as examples.

There is a task needed to be done by a group of human, within the group, each member does his/her job, then communicate to others until the task is done.
The group work in deterministic order to achieve the outcome. We have the deterministic order so that we can incrementally build and verify the correctness of the collaboration.

The group will send the "done" message to the rest of the world. Whoever is interested in the message will trigger new task for another group of human.
Again this is still the same as using observer pattern with DCI.

Of course, it would be nice if we can unify the above 2 messaging models into 1. But do we need to? since in real life we have both of them exists.

Dom

unread,
Jan 13, 2023, 3:42:40 AM1/13/23
to object-composition
On Thursday, January 12, 2023 at 7:40:32 PM UTC Quang wrote:
The group will send the "done" message to the rest of the world. Whoever is interested in the message will trigger new task for another group of human.
 
Yes (for some definition of "world").  Hold that thought... 

James Coplien

unread,
Jan 13, 2023, 4:29:23 AM1/13/23
to object-co...@googlegroups.com
The question is less about whether something is or isn’t DCI than it is about value and consequences of difference.

DCI solves a problem: locality of reference when reasoning about use cases. The problem is broad and general and the solution is direct. There is, if you will, an underlying theory: that is why, as you say, it is more than a technique but rather a philosophy. Sociopsychological research bears out that the solution solves the problem. That is its primary value.

EDCI appears not to weaken such benefits. Maybe. It seems to presume that multiple threads of control emanating from an event are Independent: I cannot reason serially about event processing, (Question: Do Contexts encapsulate event processing? If not, it seems like there’s little benefit.) But I think it solves a different problem. The question is less about whether something is or isn’t DCI than it is about value and consequences of difference.

DCI solves a problem: locality of reference when reasoning about use cases. The problem is broad and general and the solution is direct. There is, if you will, an underlying theory: that is why, as you say, it is more than a technique but rather a philosophy. Sociopsychological research bears out that the solution solves the problem. That is its primary value. problem than DCI does. Am I right? What additional problem does it solve?

I do believe that EDCI has value, but I doubt that comes from addressing DCI deficiencies. I think it’s approach to parallelism (multicasting) is at odds with the DCI model of a single closed copy of whatever code is invoked as the consequence of a major system “happening.” Both are about system-level architecture. A good next step would be to do some simple empirical research to bolster EDCI grounding.

I am still not convinced, at the technique level, that multicast is not homomorphic with a loop that iterates over instances to send them an event.

On 12 Jan 2023, at 14.04, Dom <dom.spi...@gmail.com> wrote:


--
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.

James Coplien

unread,
Jan 13, 2023, 6:47:08 AM1/13/23
to object-co...@googlegroups.com


Sent from my iPad

> On 12 Jan 2023, at 18.00, Dom <dom.spi...@gmail.com> wrote:
>
> My sights are in complexity around concurrency.

I think that part of the challenge in the discussion here is that most concurrency in CS adds accidental complexity. Your concurrency appears not to be part of the fundamental problem domain model, but of a speed-up optimization. I think the self-organization example is more representative of essential concurrency (and an attempt to serialize it).

The solution to such problems is not complex; simply divide and conquer. Correct me if I’m wrong. For any given single event, does any object directly receiving the event process additional messages within that event cycle? If so, then unless such an invocation owes solely to recursion, it becomes impossible to reason about system state. DCI is designed to be able to reason about system state.

Yet it seems that in your system, it’s intuitive that the algorithm will eventually terminate; that is a hint that you can reason about system state…

The recursion-check code is literally vestigial: you can eliminate it and the program still works (I tried it).

DCI does not address concurrency concurrency is a huge area. EDCI appears to address part of it. Perhaps it can be a programming language issue. H@Ve a look at concurrent C++, or FORTRAN for the Intel iAPX/432. Those languages might solve your special-case subset of being able to express concurrent solutions, or, more to the point, to apply engineering techniques that speed up a serial application with parallelism (e.g. multiplying a matrix by a vector.)

James O Coplien

unread,
Jan 13, 2023, 9:13:28 AM1/13/23
to noreply-spamdigest via object-composition


On 13 Jan 2023, at 09.42, Dom <dom.spi...@gmail.com> wrote:

The group will send the "done" message to the rest of the world. Whoever is interested in the message will trigger new task for another group of human.

Groups of objects don’t send messages. Objects do.

Whenever I see this I get worried that people are thinking that some objects somehow live inside other objects. That’s nonsense. Objects aren’t C structs. Objects can know about each other if one objects owns some binding to another object, but there is no notion of containment.

There may be a notion of scoping, but that pertains to classes — not objects.

That a group of objects does something implies a collaboration.

Do you mean:

  • there is a voting event and if a majority of the “group” concur, then the counter sends a *done* message?
  • there is an Observer pattern setup, and each object checks in with the Observer when it is *done,* and the Observer sends the global “done” message?
  • ...

Dom

unread,
Jan 13, 2023, 11:06:07 AM1/13/23
to object-composition
A Context representing the activity (in which the group members are playing roles as participants in the activity ) could send a "done" message to indicate that the activity was complete.

James O Coplien

unread,
Jan 13, 2023, 3:35:37 PM1/13/23
to object-co...@googlegroups.com


On 13 Jan 2023, at 17.06, Dom <dom.spi...@gmail.com> wrote:

A Context representing the activity (in which the group members are playing roles as participants in the activity ) could send a "done" message to indicate that the activity was complete.

Maybe. But I think this is a bit undisciplined.

Best practice is that all operational code be in Roles. If the notification is in a Context method, it is not a Role method.

Best practice seems to be that the Context is itself the Role-player for one of its Roles. The code that sends the “done” message would be found in a method of that Role.

This is in contrast to a mental model that holds that the objects are “inside” the Context, and the Context provides the interface from its “contained” objects to the outside world.

When coding it up, it may be over-constrained thinking to assume that the Context object is playing that Role. It’s just another object playing the Role that includes notifying some other object of completion.

Dom

unread,
Jan 13, 2023, 4:10:03 PM1/13/23
to object-composition
On Friday, January 13, 2023 at 8:35:37 PM UTC Cope wrote:
> Maybe. But I think this is a bit undisciplined.
> Best practice seems to be that the Context is itself the Role-player for one of its Roles. The code that sends the “done” message would be found in a method of that Role.

Yes, absolutely.  My point was that a context is a singular object, rather than a group of objects, that could emit an event in this case.

I'll need to continue my account of what we are doing and we'll see that this fits into it...

On Friday, January 13, 2023 at 8:35:37 PM UTC Cope wrote:

Dom

unread,
Jan 16, 2023, 10:10:16 AM1/16/23
to object-composition
> I'll need to continue my account of what we are doing and we'll see that this fits into it...

To make this more concrete I'll come up with a sample to show what this looks like, and then get into what is going on.
Reply all
Reply to author
Forward
0 new messages