Is DCI an MVC-U for a programmer?

198 views
Skip to first unread message

Oleh Novosad

unread,
Apr 7, 2018, 4:53:55 PM4/7/18
to object-composition
I do not know if this perspective was already discussed or not, please let me know. Is DCI an MVC-U for a programmer? 

In MVC-U views are created by a programmer and manipulated by a User. In DCI roles are created by a programmer and manipulated in source code by a programmer. In MVC views can be more than a static display of data. In MVC views are not only to "see" mental model of a user but also manipulate it, same as roles in DCI. If Role is a view of Data(mental model), whose view is it? I think it is programmer's view. Yes, programmer tries to align her views with requirements and use-cases, but in the end, a programmer is the one who creates those views (Roles) and manipulates them in the source code.

A programmer can have different views of Data dependently of a context. A Use-Case of a Context is a place for a programmer to manipulate those views (roles).

In MVC-U user selects which views to work with at a given moment through controllers. In DCI source code of a Context (more specifically a Use-Case of a Context) define how programmer reads and changes objects through views (roles) in their head (we do not care how processor/compiler does it, we care about how programmer does it in their head).

DCI paradigm is for a programmer to provide readability, separation of concerns, etc. Can we say that DCI is DCI-P?

If DCI is an MVC for a programmer, does it mean that we can extend MVC by adding a concept of Context to it? Different views of the same user's mental model in MVC make sense inside of different contexts same as in DCI.

Matthew Browne

unread,
Apr 7, 2018, 8:42:45 PM4/7/18
to object-co...@googlegroups.com

Hi Oleh,
I would say DCI is more like DCI-U. The emphasis is still very much on the actual end user of the system. DCI also has a goal of making software more understandable to everyone, and that includes programmers of course, hence the emphasis on readable code. But good readable code shouldn't only be readable to the programmer who wrote it, but to anyone who understands the domain language, which should use business terms rather than technical programming terms. I'm not sure how useful it is to try to come up with an acronym that covers all of this, but for the sake of illustration, maybe it would be more like DCI-USP where USP is Users, Stakeholders, and Programmers. Of course the simpler way of saying this is that DCI is fundamentally more focused on people than technology - the focus on people is what drives everything else.

--
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 https://groups.google.com/group/object-composition.
For more options, visit https://groups.google.com/d/optout.

Matthew Browne

unread,
Apr 7, 2018, 8:43:05 PM4/7/18
to object-co...@googlegroups.com

On 4/7/18 4:53 PM, Oleh Novosad wrote:

If DCI is an MVC for a programmer, does it mean that we can extend MVC by adding a concept of Context to it? Different views of the same user's mental model in MVC make sense inside of different contexts same as in DCI.

The relationship between DCI and MVC is briefly discussed in the latest DCI article (not yet published but available on fulloo.info):

MVC and DCI are complementary paradigms. MVC transforms the Model data into a physical form that can readily be assimilated by the user’s brain. DCI is about creating a program that faithfully represents the human mental model. The two meet when MVC is used to bridge the gap between the human mind and the model implied by the DCI-based computer system.

For the most part, DCI is concerned with the Model in MVC since the Model is where most use case logic belongs. See also the FAQ entry: http://www.fulloo.info/doku.php?id=how_does_dci_relate_to_mvc

At one point I was exploring how DCI might be used in conjunction with Views and Controllers as well. This actually led me to question whether Controllers are even needed if you have a smart implementation of the observer idiom (commonly known as the "observer pattern" but that's a misnomer in the sense that it's not a true design pattern - separate topic...). I was playing around with the idea that the Controller could be a DCI context and the Models and the Views would be the roles in that Context, but when I started looking into actually implementing this using a modern web UI stack with a state management library (e.g. MobX or Redux), I found that something like a Controller was rarely needed since the built-in observer mechanisms are very good at keeping the Model and View in sync without the need for manual coding. This is just my own observation and not something I've previously brought up with the group, so others might have a different opinion.

I suppose that when using a library like MobX or Redux, the state manager becomes something like a Controller for your whole app without the need for separate controllers for different screens. And of course, applying the observer idiom to the UI is also very common in desktop programming, I'm just not very familiar with that space.

(BTW, MobX and Redux actually take very different approaches...MobX is much more similar to MVC frameworks that came before it, but in the end they serve a similar function.)

Anyway, the larger point is that DCI is the paradigm and can potentially be applied anywhere you have objects, it just tends to be more beneficial in some places (like use cases) than others. Just as you can do traditional OO with MVC, you can do DCI with MVC. But you might find that regular old OO is sufficient for the Views and the Controllers (if you even need Controllers).

Raoul Duke

unread,
Apr 7, 2018, 9:09:36 PM4/7/18
to object-co...@googlegroups.com
huh, i thought pure fp was the way to go :-)

Matthew Browne

unread,
Apr 7, 2018, 9:15:40 PM4/7/18
to object-co...@googlegroups.com

In case of any confusion, I should mention a common misunderstanding...

The popular concept of an MVC View as described in many books and tutorials is narrower than Trygve's definition. To quote from Trygve's website:

An important aspect of the original MVC was that its Controller was responsible for creating and coordinating its subordinate views. Also, in my later MVC implementations, a view accepts and handles user input relevant to itself. The Controller accepts and handles input relevant to the Controller/View assembly as a whole
In web development, we are now calling Views "UI Components". I think the name "Component" is actually a good fit because components aren't just concerned with displaying things on the screen, but they can also handle user input events. And as Trygve himself has said, "View" and "Controller" are really roles, and you could even have the same object playing both roles (I think he used the example of a scrollbar). So when I said I rarely find the need for Controllers these days, that was assuming this definition of a View as something that can both display data and handle user input events (either internally or delegating to the Model when the event is received). Of course only some Views should have both responsibilities; many are purely presentational.

Matthew Browne

unread,
Apr 7, 2018, 9:21:12 PM4/7/18
to object-co...@googlegroups.com
On 4/7/18 9:09 PM, Raoul Duke wrote:
> huh, i thought pure fp was the way to go :-)
Not seeing the connection to this thread...? Also, I might be missing
something, but I think "purely functional DCI" would be an entirely new
thing that I haven't seen an example of yet. Most FP languages don't
even have objects that are anything like DCI objects, so it might
require an entirely new language, or at least a hybrid language such as
Scala or OCaml and cousins.

Oleh Novosad

unread,
Apr 7, 2018, 11:55:04 PM4/7/18
to object-composition
Hi Matthew, 

I am not sure about DCI-USP. This is an excerpt from Trygve's article https://www.artima.com//articles/dci_vision.html:

"...  a telephone system may have underlying objects that represent the basic building blocks of local telephony called half-calls. (Think about it: if you just had "calls," then where would the "call" object live if you were making a call between two call centers in two different cities? The concept of a "half-call" solves this problem.)"

In MVC User will see those "half-calls" through views as a "calls." While in DCI programmer will see "half-call" roles. Stakeholders and Users will not have an idea you have "half-calls."

Thank you for links and answers, I will read articles.

Oleh Novosad

unread,
Apr 8, 2018, 12:11:55 AM4/8/18
to object-composition


 (if you even need Controllers).


I think C (Controller) in MVC can be replaced with Context. It makes sense. Context has use-case(s), and we present views to User following use-case(s). Views are related to Contexts same as Roles are related to Contexts in DCI.  Now DCI-P and MVC-U make a whole.

Rune Funch Søltoft

unread,
Apr 8, 2018, 1:55:15 AM4/8/18
to object-co...@googlegroups.com


> Den 8. apr. 2018 kl. 05.55 skrev Oleh Novosad <oleh.n...@gmail.com>:
>
> In MVC User will see those "half-calls" through views as a "calls." While in DCI programmer will see "half-call" roles. Stakeholders and Users will not have an idea you have "half-calls."
No one has claimed that all the code should be understandable to all stakeholders (whether they be programmers, users or something else). They should however be able to see their mental model represented in those areas that concern them. Take a look at the Marvin money transfer example of fulloo.info. There you’ll see that the account implementation speaks to one kind of stakeholder (knowledgable about how banking works) while the design surface represents the mental model of a common bank customer. Similar could be done with half calls and calls

Andreas Söderlund

unread,
Apr 8, 2018, 3:17:49 AM4/8/18
to object-co...@googlegroups.com
Hi Oleh, a Controller is a role played by an object, so it's not about replacing one thing with another. A Controller is basically a view manager, and if it's tightly coupled to its data, it may play the role of a Model, and also be part of a Context.

See my article Rediscovering MVC for more details: https://github.com/ciscoheat/mithril-hx/wiki/Rediscovering-MVC

/Andreas

Den sön 8 apr. 2018 13:11Oleh Novosad <oleh.n...@gmail.com> skrev:


 (if you even need Controllers).


I think C (Controller) in MVC can be replaced with Context. It makes sense. Context has use-case(s), and we present views to User following use-case(s). Views are related to Contexts same as Roles are related to Contexts in DCI.  Now DCI-P and MVC-U make a whole.

--

James Coplien

unread,
Apr 8, 2018, 4:03:17 AM4/8/18
to object-co...@googlegroups.com
I think what Matt replied is mainly true, but I do think that Oleh is also on to something. I like his premise, and it has often been articulated during the shaping of DCI.

Sent from my iPad

James Coplien

unread,
Apr 8, 2018, 4:07:58 AM4/8/18
to object-co...@googlegroups.com
MVC is itself a use case in three roles, with several related scenarios characterized by dependency management, which can be (and has been) implemented using DCI.
--

Matthew Browne

unread,
Apr 8, 2018, 4:58:50 AM4/8/18
to object-co...@googlegroups.com
On 4/8/18 4:07 AM, James Coplien wrote:
> MVC is itself a use case in three roles, with several related
> scenarios characterized by dependency management, which can be (and
> has been) implemented using DCI.
Good insight. I'm not sure I understand it 100% since it's not like the
user sits down and says "I want to do MVC", but maybe it's a
whole-system use case, or alternatively an internal perspective on use
cases involving a GUI...

Matthew Browne

unread,
Apr 8, 2018, 5:03:40 AM4/8/18
to object-co...@googlegroups.com
On 4/7/18 11:55 PM, Oleh Novosad wrote:
> In MVC User will see those "half-calls" through views as a "calls."
> While in DCI programmer will see "half-call" roles. Stakeholders and
> Users will not have an idea you have "half-calls."
I believe it was Cope who worked on that system and in any case I don't
know the details, but it's possible that the stakeholders (business
people at the company) and not only the programmers used and understood
the concept of "half-calls". But even if it was only a programmer
concept, that would be valid too (as Rune said) without changing the
fact that DCI allows you to represent different people's mental models
in the same system.

Matthew Browne

unread,
Apr 8, 2018, 5:13:34 AM4/8/18
to object-co...@googlegroups.com
On 4/8/18 12:11 AM, Oleh Novosad wrote:
> I think C (Controller) in MVC can be replaced with Context. It makes
> sense. Context has use-case(s), and we present views to User following
> use-case(s). Views are related to Contexts same as Roles are related
> to Contexts in DCI.  Now DCI-P and MVC-U make a whole.
If I'm understanding you correctly, this reflects a common
misunderstanding of Controllers - one that I used to have as well. In
original MVC, a Controller was never supposed to be a place where you'd
put lots of business or use case logic (talking about user goal-level
use cases here) -- that was meant to happen in the Model. I think this
misinterpretation of Controllers became common in the earlier years of
web development when we had "Controllers" handling HTTP requests, but
probably started before that. So if you mean that the DCI Context is now
where you'd put use case code that you previously would have put in a
so-called "Controller", then yes.

I also agree with what Cope said that you may be on to something here,
because the relationship and purpose of MVC in terms of what it does for
the user is similar to what DCI does for the programmer (and when
programmers can understand code more easily and it reflects the
business, it indirectly benefits everyone else).

Matthew Browne

unread,
Apr 8, 2018, 5:16:06 AM4/8/18
to object-co...@googlegroups.com
On 4/8/18 5:13 AM, Matthew Browne wrote:
On 4/8/18 12:11 AM, Oleh Novosad wrote:
I think C (Controller) in MVC can be replaced with Context. It makes sense. Context has use-case(s), and we present views to User following use-case(s). Views are related to Contexts same as Roles are related to Contexts in DCI.  Now DCI-P and MVC-U make a whole.
If I'm understanding you correctly, this reflects a common misunderstanding of Controllers - one that I used to have as well. In original MVC, a Controller was never supposed to be a place where you'd put lots of business or use case logic (talking about user goal-level use cases here) -- that was meant to happen in the Model. I think this misinterpretation of Controllers became common in the earlier years of web development when we had "Controllers" handling HTTP requests, but probably started before that. So if you mean that the DCI Context is now where you'd put use case code that you previously would have put in a so-called "Controller", then yes.
P.S. Reading Andreas's article on rediscovering MVC (linked in his post) should help.

Oleh Novosad

unread,
Apr 8, 2018, 12:32:16 PM4/8/18
to object-composition
Hi Andreas, 
I read your very good article about MVC. Thank you.
First of all, in my opinion, everything that has a name is a role in some context. Pure Data is not required to be named (we name it to easier operate it in the context of a program we create). Names make sense only in a context. Cannot think of any contra argument to this statement. 

In your article, Controller 

- Creates and manages Views
- Handles selection across Views
- Passes commands to the Model
- Handles commands that apply to the entire window

If we replace Controller with Context 
- Creates and manages Views  - we do it all time with Roles in Use-Cases of a Context 
- Handles selection across Views - no problem, interaction is a part of a Use-Case of a Context 
- Passes commands to the Model -  part of interaction inside of a Use-Case of a Context
- Handles commands that apply to the entire window - why not, EntireWindow is just a Role inside of a Context, easy

- plus Context can handle any other interactions

I think Context is more specific and better than Controller because Context has Use-Cases. How you present Views to User(s) should follow Use-Cases. A controller doesn't have that. I do not like how current web frameworks like Ruby on Rails are implemented. Controllers only have a part of Use-Case in them. Usually, it is hard to grasp the full business logic of Use-Case looking only at one controller. I think this is wrong and can be fixed with something like Fiber(coroutine) in Ruby (part of the standard library) so we can write full Use-Case in one method so it can be much easier readable and understandable. This is how I would improve Ruby on Rails.

Andreas Söderlund

unread,
Apr 8, 2018, 1:31:59 PM4/8/18
to object-co...@googlegroups.com
I'm not completely convinced, because not all MVC objects are relevant as a Context. For simple, atomic operations for example, there aren't any roles that interact. The controller could contain (or even be) a single model, and then we have just some simple message passing.

"Promoting" such an object to a Context would require it to have a business value, and simple operations don't tend to have that (compare use case to user stories). They are probably a part of a higher level use case, but those aren't that easy to model as a flow of messages in a DCI interaction, since the execution order can be quite arbitrary.

As you say it's hard to see the business logic in controllers, and I would love to see DCI solve this, but I haven't seen it yet, and haven't been able to come up with something I'm happy about in my own experimentation. Please make an attempt! I have worked on this and I have some ideas I could share later, but not tonight! :)


--

Matthew Browne

unread,
Apr 8, 2018, 7:01:48 PM4/8/18
to object-co...@googlegroups.com

I agree with Oleh: it could certainly work to implement a Controller as a Context. Views and Models are interacting objects so it makes sense to put them in a Context to make that interaction clearer. In a previous thread (probably a year or two ago now), Rune brainstormed the idea of a Context for MVC where M V and C are roles. After thinking about this more recently, I realized that the main purpose of the Controller is to facilitate interaction between the Views and the Model(s), so I don't see the reason for introducing a 4th part of the pattern - the Controller *is* the Context for the interaction of Models and Views.

But as I said in a previous post, when I actually started implementing this idea, I began questioning the need for Controllers in the first place because most of the time, their function can be automated (other than creating Views in the first place, but that's a fairly limited function that falls short of what I would call a Controller, if that's all it's doing). I think quote from the MobX documentation makes a good point:

Anything that can be derived from the application state, should be derived. Automatically.

If all of your Views automatically react to changes in the Model and vice versa, then in my experience there's very little need for the plumbing code that would otherwise go in Controllers.

~~~

There's another big factor in this discussion...Oleh mentioned Ruby on Rails. Rails is a framework that runs only the server, and as a server-side framework, its implementation of MVC is considerably different than client-side MVC. Most of my comments have been about client-side MVC, where the Model View and Controller can all interact with each other directly. This of course is much closer to the original MVC which was first applied to desktop software. While it was great for server-side frameworks to follow the spirit of MVC, their "Controllers" are of course a different animal than client-side Controllers, and there was an important thing they got wrong, which was that aside from code involving the UI specifically, use case logic belongs in the Model of MVC, not the Controller. But of course this is harder to achieve for practical reasons when your controllers are handling stateless HTTP requests on the server and are not directly connected to your UI or your client-side Model. And also, without DCI, putting all use case logic in Models can become a mess.

As I see it, the place where DCI fits best into this picture (most of the time) is as Contexts apart from MVC. The Views accept user input events and then trigger the appropriate use case Context...or, if there's some complexity that warrants it, a Controller could handle the event rather than the View, and then the Controller in turn calls the Context. (Note that when I say "handle the event" I don't necessarily mean processing it; this could simply be passing some data along to be processed by the use case Context.)

Of course, the asynchronous nature of GUIs complicates all of this. I don't think we've landed on a complete solution yet, especially in the case of use cases that involve multiple interactions with the user to reach completion (e.g. a wizard-style interface or a shopping cart system). Synchronous blocking is one option, but that only works in a multi-threaded environment (which means it's not a workable solution for web browsers), and has some technical downsides anyway. In the case of Ruby and other environments with fibers or coroutines, I agree that those might be helpful here. IMO there are also simpler solutions that could work.

Oleh, I have some additional thoughts regarding the preceding paragraph which I've expressed in previous threads, but rather than resurface that now, I would encourage you to experiment as Andreas suggested and then share your findings. I would be interested to hear where this exploration leads you.

Trygve Reenskaug

unread,
Apr 9, 2018, 9:32:47 AM4/9/18
to object-co...@googlegroups.com
I see MVC and DCI as 2 orthogonal principles for separation of concerns. An example is my planning example where I first organize the program along MVC lines, and then each seperately along DCI lines:
    Model
        Context
        Data
    UI
        Context
        Data
More at
    http://folk.uio.no/trygver/Diverse/PlannningExtract.pdf
--

The essence of object orientation is that objects collaborate  to achieve a goal.
Trygve Reenskaug      
mailto: try...@ifi.uio.no
Morgedalsvn. 5A       
http://folk.uio.no/trygver/
N-0378 Oslo             
http://fullOO.info
Norway                     Tel: (+47) 22 49 57 27

James O Coplien

unread,
Apr 9, 2018, 12:34:35 PM4/9/18
to object-co...@googlegroups.com


Sendt fra min iPhone

> Den 9. apr. 2018 kl. 01.01 skrev Matthew Browne <mbro...@gmail.com>:
>
> the Controller *is* the Context for the interaction of Models and Views.

I think that is true only for some use cases. For example, when the Model is updating the View, there is not much need to involve the Controller in most cases.

There are many use cases involving the three roles of Model, View, and Controller. It may be that all of these could be handled in a single Context, called MVC, which encapsulated all three roles. I think it is more likely that there could be different Contexts for different sets of related use cases. In other words, I think the latter architecture would improve separation of concerns, improve decoupling, and optimize locality of reference.

As always, it would be good to have experiments to validate and verify these conjectures.

I also think that this design – and this discussion – are somewhat different from the ideas in the original post in this thread.

Matthew Browne

unread,
Apr 9, 2018, 1:54:17 PM4/9/18
to object-co...@googlegroups.com
On Mon, Apr 9, 2018 at 12:34 PM, James O Coplien <jcop...@gmail.com> wrote:

> Den 9. apr. 2018 kl. 01.01 skrev Matthew Browne <mbro...@gmail.com>:
>
> the Controller *is* the Context for the interaction of Models and Views.

I think that is true only for some use cases. For example, when the Model is updating the View, there is not much need to involve the Controller in most cases.

I agree. I didn't mean that the Controller should be the only way that Models and Views should be allowed to interact (and in fact I previously mentioned that Views are allowed to handle input relevant to themselves directly). Yes, Models can talk to Views and Views can talk to Models without necessarily needing a Controller. So let me say it another way: anytime you have an MVC Controller class, that class could instead be implemented as a Context in which the Model(s) and View(s) are roles. But only if you need a Controller for coordinating your Models and Views in the first place...

I also think that this design – and this discussion – are somewhat different from the ideas in the original post in this thread.

Yes, this is a tangent from Oleh's original post, but I do think it's directly relevant to his most recent post, unless I misunderstood it.

Matthew Browne

unread,
Apr 9, 2018, 2:09:03 PM4/9/18
to object-co...@googlegroups.com
On Mon, Apr 9, 2018 at 9:32 AM, Trygve Reenskaug <try...@ifi.uio.no> wrote:
I see MVC and DCI as 2 orthogonal principles for separation of concerns. An example is my planning example where I first organize the program along MVC lines, and then each seperately along DCI lines:
    Model
        Context
        Data
    UI
        Context
        Data
More at
    http://folk.uio.no/trygver/Diverse/PlannningExtract.pdf

Thanks for the explanation Trygve. Yes, I've seen that that's how it works in the big planning example (Prokon). But what do you think of the idea of a Controller being implemented as a DCI Context instead of a class? Is there some compelling reason to avoid the use of DCI in the parts of your code that implement MVC? Or is it more that you just didn't see a reason to use it?

Trygve Reenskaug

unread,
Apr 12, 2018, 9:16:38 AM4/12/18
to object-co...@googlegroups.com
On 07.04.2018 22:03, Oleh Novosad wrote:
> I do not know if this perspective was already discussed or not, please let me know. Is DCI an MVC-U for a programmer?
A good question, Oleh. MVC and DCI are both created for the benefit of humans and both relate to the structure of programs. Your question started a long discussion, which was good. It also challenged me to formulate why I believe the answer must be no.

The foundation of my thinking is my definition of a runtime object as an entity that encapsulates state and behavior. The encapsulation is opaque. Seen from outside the encapsulation, an object has a unique and immutable identity and can only be accessed through its provided message interface. The object's inside is invisible from its outside. Seen from inside the encapsulation, an object stores its state (e.g. in instance variables) and defines its behavior (e.g. in its methods). The object's outside is invisible from its inside. (The class isn't interesting at runtime.)

 Cope's trygve language and Smalltalk support this definition. (Most OO languages don't support it. Their encapsulations are transparent and confuse the definitions of DCI and MVC.)

MVC and DCI serve different purposes. MVC (= MVC-U) serves to bridge the gap between the human user's (U) mental model of some information and the computer's digital representation (M) of it. DCI serves to describe the behavior of a system of communicating objects, i.e. what happens in the space between them. The crucial difference is that MVC deal with the insides of stand-alone objects while DCI deals with with what happens in the space between the objects and is only see them from outside their encapsulations.

The responsibilities of M, V, and C are assumed by objects. They are primarily responsible for maintaining state: The C maintains a digital representation of some user information. The V maintains a picture of this information, e.g., as pixels on a screen. The C creates, manages, and coordinates the Vs, so its state must include information about them. All this means that we work with the M. V, and C objects in their insides. (There is no inherent collaboration between M, V, and C, so DCI has nothing to contribute at the outer level. The M is responsible for warning its dependents (state) whenever the user information changes. M must understand the addDependent: v -message. It must send update-messages to its current dependents whenever appropriate. M does not care about how the dependents will handle the received update-messages. M is a stand-alone object. We are only interested in its insides; it is specified as part of a class somewhere.)

The D in DCI  is a set of objects seen from their outsides; their insides are explicitly hidden. The C seen from its inside declares its roles and links to its Interaction(s) Seen from its outside, it looks like any other D object and can play roles in other Cs (recrusion).

To conclude: DCI can not be MVC-U for a programmer; they are fundamentally incompatible.


On 09.04.2018 20:08, Matthew Browne wrote:
But what do you think of the idea of a Controller being implemented as a DCI Context instead of a class?
Confusing class and Context is not a good idea because the concepts are incommensurable. The first deals with the inside of a stand-alone object, the second with a structure of communicating objects (seen from their outsides). The state of a Controller is essential. There's no room for it in a DCI Context.

Is there some compelling reason to avoid the use of DCI in the parts of your code that implement MVC?
Not at all. It can be hidden  within the encapsulation boundary of a M, V, or C object. In my Planning example, the implementation of a View is with a class that uses a Context to paint it on the screen.

In haste. My apologies if I misunderstood you.
--Trygve


Matthew Browne

unread,
Apr 12, 2018, 8:16:41 PM4/12/18
to object-co...@googlegroups.com
On 4/12/18 9:16 AM, Trygve Reenskaug wrote:
On 09.04.2018 20:08, Matthew Browne wrote:
But what do you think of the idea of a Controller being implemented as a DCI Context instead of a class?
Confusing class and Context is not a good idea because the concepts are incommensurable. The first deals with the inside of a stand-alone object, the second with a structure of communicating objects (seen from their outsides). The state of a Controller is essential. There's no room for it in a DCI Context.
Ah, good point. Here's a variation of my idea where the Controller is a Context but the Context itself plays a role that could be used to store and access the controller state (that would happen in the Controller role):

    context MyController {
        // some state used by the Controller role
        private String foo

        public MyController(Model model, View1 view1, View2 view2) {
            Controller = this
            Model = model
            View1 = view1
            View2 = view2
        }
       
        ...
   
        role Controller { ... }
        role Model { ... }
        role View1 { ... }
        role View2 { ... }
    }


I plan to play around with this more at some point and make it more concrete, so it probably doesn't make sense to discuss it much more in detail right now. But that's the general idea. I'm not sure yet if it has significant advantages over just implementing the controller in the traditional way, as a class.

Andreas Söderlund

unread,
Apr 12, 2018, 8:55:16 PM4/12/18
to object-co...@googlegroups.com
Matt, when you play around with this I'm curious about the communication between the roles. If there are no communication, or maybe even a hierarchical communication where the controller is basically telling the views what to do, is this Context anything else than a glorified class?

We had a discussion in the group about the Tower of Hanoi game, and found out that not every object should play a role because of a lack of genericity. I suspect this could be a similar case.

Matthew Browne

unread,
Apr 12, 2018, 9:31:42 PM4/12/18
to object-co...@googlegroups.com
On 4/12/18 8:55 PM, Andreas Söderlund wrote:
For some reason this link didn't work for me (mobile vs. desktop issue?) so for the group here's another link in case it helps:
https://groups.google.com/forum/#!searchin/object-composition/hanoi%7Csort:date/object-composition/SjMZ_vyLrh4/N8S7qPJXCAAJ
Matt, when you play around with this I'm curious about the communication between the roles. If there are no communication, or maybe even a hierarchical communication where the controller is basically telling the views what to do, is this Context anything else than a glorified class?

We had a discussion in the group about the Tower of Hanoi game, and found out that not every object should play a role because of a lack of genericity. I suspect this could be a similar case.
I'm not sure about the communication yet... but yeah, regarding the lack of genericity, that does cast some doubt on this concept. But I don't think genericity or lack of it is necessarily the only factor in deciding whether or not interaction should be represented as roles in a Context. It seems like a good rule of thumb, especially for business use cases. But even in cases where a role is only ever played by objects of the same class, using a role could still help clarify its interaction with other objects when reading the code. For example, this could be helpful when there's at least one other role in the same Context that is generic, which is arguably true of the Model role here. And maybe in some systems it would be true of the View roles as well... for example, an additional frontend to the same backend API, e.g. a kiosk with a nearly identical GUI but a different UI library to actually render things to the screen. (The more common example would be both a web version and native mobile version of the same app, although for practical reasons I'm not sure if you'd be able to reuse the same Controller Context for both versions in that case.)

BTW, I'm kind of curious about the Account Context example we all seem to generally agree on:
http://fulloo.info/Examples/Marvin/MoneyTransfer/Listings/Account/

This is a Context with only one role, which is a little weird. Also, LedgerEntry doesn't seem particularly generic...it could be played by objects of some other class as long as it implements the basic LedgerEntry interface, but I'm not sure what that would be. Anyway, if we are OK with using a Context for this, then perhaps we should broaden our horizons and also consider using Contexts in other places we might not have previously considered. There is of course some risk of, "If you have a hammer then everything looks like a nail". But on the other hand, there might be benefits to be found even if they are rather marginal ones.

James Coplien

unread,
Apr 13, 2018, 8:01:21 AM4/13/18
to object-co...@googlegroups.com
I think Trygve’s objections are at the level of detail that substantiate that the two are no equivalent. I think this says nothing about whether they may be analogous, which, to me, is more in the spirit of the original question.

I would encourage us to continue to explore common elements in our mental models of these two formalisms. I have a gut feeling that there is something there, in terms of design conceptualization, that might elude a Western reductionist analysis of any possible common basic foundation for the two. And if we find it, we will have found a true gem of software conceptualization and design.

Sent from my iPad

Andreas Söderlund

unread,
Apr 13, 2018, 10:53:11 AM4/13/18
to object-co...@googlegroups.com
The closest I have gotten to a generic view Role is in the library machine example, where the Role "screen" has the following RoleObjectContract:

function display(s : ScreenState) : Void;

Where ScreenState is an Enum of states. Since Enums in Haxe are algebraic data types, you can pass data from the Context to the view using the enum constructor, which is why the contract is so simple. Example:

screen.display(DisplayBorrowedItems(scannedItems));

If you couldn't, as in many other languages, the contract would have one method for displaying each state, and the genericity is gone.

function displayWelcome();
function displayBorrowedItems(scannedItems : Iterable<ScannedItem>);
...etc for 8 different states

Does this mean this solution is really an illusion?

I think the Role itself is useful, for example the other Roles are communicating with the screen, asking it to display different states, and in the RoleMethods it's also wiring up events, so the RoleMethods aren't just relaying a call to the RoleObjectContract. If the pin code needs to be entered, the screen will ask the keypad to wait for user input.

Oleh Novosad

unread,
Apr 14, 2018, 2:01:41 AM4/14/18
to object-composition
Thanks, Trygve, and everyone. 

As I understand, a Controller decides how to update View(s), which View(s) and in what order to present to a User taking into account User's input. I would say Controller provides/enforces a scenario by which a User interacts (or should interact) with Views. A DCI Context also has a scenario. In that sense Controller is a Context. A Controller offers Views(Roles), enforces scenario, but interaction (between User and Views part) happens outside of it. The difference to DCI Context is that in MVC interaction occurs between User and View(s) while in DCI interaction occurs between View(s)(Roles). Roles have meaning in specific Contexts. Similarly, I think, Views have sense in particular Controllers.

Another question was: Is DCI an MVC-U (tool) for a programmer? Can we say that DCI is DCI-P?

For a programmer, a Context is where programmer operates with Roles in her head. And Roles are views to Data. When programmer reads Context's code statement by statement - Context controls how Roles(Views) are presented to a programmer's mind. I would say, to programmer's mind, a Context in that sense is a Controller with Views (Roles) when she reads the code. 

Is DCI an MVC-U tool for a programmer to work with code?  To me, it looks like yes.

Matthew Browne

unread,
Apr 14, 2018, 8:16:17 AM4/14/18
to object-co...@googlegroups.com
On 4/12/18 9:16 AM, Trygve Reenskaug wrote:
The responsibilities of M, V, and C are assumed by objects. They are primarily responsible for maintaining state: The C maintains a digital representation of some user information.
Did you mean to say "The M maintains a digital representation of some user information"? Yes, the Controller can temporarily store user information too, but reading this and noticing that you didn't go into the M's role, I was just wondering if this was a typo.

Matthew Browne

unread,
Apr 14, 2018, 8:20:40 AM4/14/18
to object-co...@googlegroups.com
On 4/12/18 9:16 AM, Trygve Reenskaug wrote:
Seen from outside the encapsulation, an object has a unique and immutable identity and can only be accessed through its provided message interface. The object's inside is invisible from its outside. Seen from inside the encapsulation, an object stores its state (e.g. in instance variables) and defines its behavior (e.g. in its methods). The object's outside is invisible from its inside. (The class isn't interesting at runtime.)

 Cope's trygve language and Smalltalk support this definition. (Most OO languages don't support it. Their encapsulations are transparent and confuse the definitions of DCI and MVC.)
How is the trygve language different from Java or C# in this regard? Yes, the trygve language does have a very limited inheritance model with no super() calls, but I'm guessing you were talking about this in general and not just about encapsulation of superclasses and subclasses. (I see more of a difference with Smalltalk, since it accepts messages rather than methods being called directly.)

Trygve Reenskaug

unread,
Apr 14, 2018, 1:52:53 PM4/14/18
to object-co...@googlegroups.com
The instance variables can be reached (read and written) from anywhere if they have a public attribute. Java etc. have no encapsulation.

Trygve Reenskaug

unread,
Apr 14, 2018, 2:08:05 PM4/14/18
to object-co...@googlegroups.com

On 14.04.2018 14:16, Matthew Browne wrote:
On 4/12/18 9:16 AM, Trygve Reenskaug wrote:
The responsibilities of M, V, and C are assumed by objects. They are primarily responsible for maintaining state: The C maintains a digital representation of some user information.
Did you mean to say "The M maintains a digital representation of some user information"? Yes, the Controller can temporarily store user information too, but reading this and noticing that you didn't go into the M's role, I was just wondering if this was a typo.
I had to read it three times to see the typo. The M maintains a digital representation of some user information, not the C.
Thank you.

Matthew Browne

unread,
Apr 14, 2018, 3:11:38 PM4/14/18
to object-co...@googlegroups.com
On 4/14/18 1:52 PM, Trygve Reenskaug wrote:
The instance variables can be reached (read and written) from anywhere if they have a public attribute. Java etc. have no encapsulation.
You can do the same thing in trygve:

class Demo {
    public int x = 0
}

{
    Demo d = new Demo()
    d.x = d.x + 1
    System.out.println(d.x)
}


Perhaps ironically, in some other languages such as PHP which are generally considered less robust OOP languages, public properties are less of an encapsulation issue (unless you use them carelessly), because you can change them from public to private or protected at any time while still maintaining the same public API for your class. For example, in PHP you can change this:

class Demo {
    public $x = 0
}


to this:

class Demo {
    private $x = 0;
   
    public function __get($key) {
        if ($key == 'x') {
            return $this->$key;
        }
    }
   
    public function __set($key, $val) {
        if ($key == 'x') {
            $this->setX($val);
        }
    }
   
    public function setX($val) {
        if ($val > 0) {
            throw new \InvalidArgumentException("x must be a positive number");
        }
        $this->x = $val
    }
}


...and you can still get and set $x in the same way (and of course, you can also implement read-only properties, etc).

But I'm getting off-topic... The principle of encapsulation still seems relevant though. I suppose that encapsulation is one of the most important features enabling the compressions and abstractions that help make DCI code more understandable - something like "Views" for the programmer as Oleh put it.

Trygve Reenskaug

unread,
Apr 14, 2018, 4:21:04 PM4/14/18
to object-co...@googlegroups.com


On 14.04.2018 21:11, Matthew Browne wrote:
On 4/14/18 1:52 PM, Trygve Reenskaug wrote:
The instance variables can be reached (read and written) from anywhere if they have a public attribute. Java etc. have no encapsulation.
You can do the same thing in trygve:
A grave disappointment.
Simplicity, simplicity, simplicity!

Matthew Browne

unread,
Apr 14, 2018, 9:49:49 PM4/14/18
to object-co...@googlegroups.com

Starting a new thread to avoid hijacking the other one...

On 4/14/18 4:21 PM, Trygve Reenskaug wrote:
On 4/14/18 1:52 PM, Trygve Reenskaug wrote:
The instance variables can be reached (read and written) from anywhere if they have a public attribute. Java etc. have no encapsulation.
You can do the same thing in trygve:
A grave disappointment.
Simplicity, simplicity, simplicity!
I agree that encapsulation is important, but if the goal is simplicity, then sometimes public properties are the simplest solution and are effectively no different from equivalent getters and setters. i.e. this:


class Demo {
    public int x
}


is simpler than this:

class Demo {
    private int x_
    public int getX() {
        return x_
    }
    public void setX(int x) {
        x_ = x
    }
}


But there are potentially two big problems here:

1. Maybe 'x' shouldn't be exposed in the first place. For example, it became a common practice among some Java developers to add getters and setters for almost every property without really thinking about it. But let's assume for now that there's a good reason to allow consumers of the Demo class to both get and set 'x'.

2. It might seem like a good idea to expose 'x' as a public property at the time you're originally writing the class, but some future requirement might arise for which you'd like to add some additional logic, e.g. validation before setting the value. But because you already made it public, this would require refactoring not only your class but also all the code that uses Demo.x.

I think Cope has said before (and I agree) that we're kidding ourselves if we think getters and setters are universally superior to public properties -- the simplest getters and setters like those above break encapsulation in just the same way.

There's a simple way to address problem #2: introduce a syntax to intercept property access so that you can change your property from public to private at any time. For example, something like this:

class Demo {
    private int x_
    get int x() {
        return x_
    }
    set int x(int newX) {
        x_ = newX
    }
}

...which would allow you to access the property in the same way as a public property:


Demo d = new Demo()
d.x = d.x + 1

This could also create read-only and write-only properties if you omitted either the set or get method.

I'm not sure if it would be worth it to pursue adding this to trygve because its primary focus is of course DCI contexts and roles (and it's only a research language).

I'm bringing it up mainly to point out that public properties aren't necessarily bad. There are plenty of cases where you legitimately want to allow consumers of your class to both get and set the value of a property. In the absence of something like the above 'get' and 'set' syntax, I can understand why many teams would just have a blanket rule of always avoiding public properties. But if you solve problem #2, then I don't see any issues with appropriate use of public properties.

I'm guessing that Cope does not view public properties as such a catastrophe either, or he wouldn't have included them in the language.
Message has been deleted

Trygve Reenskaug

unread,
Apr 15, 2018, 4:44:04 AM4/15/18
to object-co...@googlegroups.com
private means private to the class, not the instance. So your x can be changed from any instance of class Demo. There is no encapsulation.

James O Coplien

unread,
Apr 15, 2018, 5:35:51 AM4/15/18
to object-co...@googlegroups.com


Den 15. apr. 2018 kl. 10.43 skrev Trygve Reenskaug <try...@ifi.uio.no>:

private means private to the class, not the instance. So your x can be changed from any instance of class Demo. There is no encapsulation.

I think this is a bug in trygve. Do you agree?

I have implemented and tested a fix for it.

James O Coplien

unread,
Apr 15, 2018, 5:43:53 AM4/15/18
to object-co...@googlegroups.com


Den 15. apr. 2018 kl. 03.49 skrev Matthew Browne <mbro...@gmail.com>:

2. It might seem like a good idea to expose 'x' as a public property at the time you're originally writing the class, but some future requirement might arise for which you'd like to add some additional logic, e.g. validation before setting the value. But because you already made it public, this would require refactoring not only your class but also all the code that uses Demo.x.

Not in trygve. aDemo.x is a perfectly fine method invocation syntax.

Thanks and a tip of the hat to Bertrand Meyer.

James O Coplien

unread,
Apr 15, 2018, 5:47:26 AM4/15/18
to object-co...@googlegroups.com
Den 15. apr. 2018 kl. 03.49 skrev Matthew Browne <mbro...@gmail.com>:

I'm guessing that Cope does not view public properties as such a catastrophe either, or he wouldn't have included them in the language.

I am with Trygve on this one. Working around pseudo-encapsulation with getters and setters is just fooling one’s self. A program should say what we mean and mean what we say. Public members perfectly express the intent to have public members.

It’s important to understand that encapsulation != information hiding, that scoping != information hiding, and that data structuring != information hiding. Many languages confuse these.

James O Coplien

unread,
Apr 15, 2018, 6:02:17 AM4/15/18
to object-co...@googlegroups.com


Den 14. apr. 2018 kl. 22.21 skrev Trygve Reenskaug <try...@ifi.uio.no>:

A grave disappointment.
Simplicity, simplicity, simplicity!

Can you show your proposed solution and argue why it is more simple?

This seems much simpler from the perspective of information theory and the corresponding semiotics.

Matthew Browne

unread,
Apr 15, 2018, 8:26:20 AM4/15/18
to object-co...@googlegroups.com
Oh right. But what about:

aDemo.x = newValue

That's what my proposed custom setter would allow.

(And in case it wasn't clear, the space is significant - 'set x(int newX) {...}' wasn't a typo and would have a different meaning than 'setX(int newX) {...}'. BTW the syntax is inspired by Javascript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set)

Matthew Browne

unread,
Apr 15, 2018, 8:31:00 AM4/15/18
to object-co...@googlegroups.com
On 4/15/18 5:47 AM, James O Coplien wrote:
> I am with Trygve on this one. Working around pseudo-encapsulation with
> getters and setters is just fooling one’s self. A program should say
> what we mean and mean what we say. Public members perfectly express
> the intent to have public member
I think Trygve is advocating that there should be no public properties
whatsoever (but obviously there would still be public methods). So I
guess you're not "with Trygve" on that part? Anyway, I think what I
previously posted agrees with everything you said above.

Matthew Browne

unread,
Apr 15, 2018, 8:46:41 AM4/15/18
to object-co...@googlegroups.com
What are we talking about exactly? Are you referring to the following:

class Demo {
    private int x_
   
    public Demo(int x) {
        this.x_ = x.clone
    }   

    public boolean compare(Demo otherInstance) {
        return this.x_ == otherInstance.x_
    }
}

{
    Demo d1 = new Demo(1)
    Demo d2 = new Demo(2)
    System.out.println(d1.compare(d2))
}



My two cents: I agree, this should be illegal in trygve. If you need this sort of comparison function, the programmer should provide a public interface that makes it possible rather than the language allowing encapsulation of the instance to be broken.

James O Coplien

unread,
Apr 15, 2018, 9:14:22 AM4/15/18
to object-co...@googlegroups.com

Den 15. apr. 2018 kl. 14.46 skrev Matthew Browne <mbro...@gmail.com>:

On 4/15/18 5:35 AM, James O Coplien wrote:
Den 15. apr. 2018 kl. 10.43 skrev Trygve Reenskaug <try...@ifi.uio.no>:

private means private to the class, not the instance. So your x can be changed from any instance of class Demo. There is no encapsulation.

I think this is a bug in trygve. Do you agree?

I have implemented and tested a fix for it.
What are we talking about exactly? Are you referring to the following:


Here is the test:

class Demo {
    private int x_
    int getX() {
        return x_
    }
    int setX(int newX) {
        x_ = newX.clone
        Demo d = new Demo();
        d.x_
return x_
    }
}

new Demo().x_


/* GOLD:
line 9: Cannot access expression `d.x_' with `private' access qualifier across instances.
line 14: Cannot access expression `[new Demo].x_' with `private' access qualifier.
0 warnings, 2 errors.
___________________________________________________________
*/

Trygve Reenskaug

unread,
Apr 15, 2018, 11:50:38 AM4/15/18
to object-co...@googlegroups.com
On 15.04.2018 11:35, James O Coplien wrote:
Den 15. apr. 2018 kl. 10.43 skrev Trygve Reenskaug <try...@ifi.uio.no>:

private means private to the class, not the instance. So your x can be changed from any instance of class Demo. There is no encapsulation.

I think this is a bug in trygve. Do you agree?

As I understand it, not being a 3GL language programmer,  protection codes in 3GLs apply to the source, not the runtime. For example i Java:
"What is private in Java?
A private member is only accessible within the same class as it is declared. A member with no access modifier is only accessible within classes in the same package. A protected member is accessible within all classes in the same package and within subclasses in other packages."
My mental model consists of objects and objects only. Classes are very much in the background. I think of methods as parts of the object. The class is merely a shared repository that saves space. A private member should only be visible within the object in my mental model. This means that a private inst.var. is only visible to the object's own methods. Similarly, a private method is only visible to the object's own methods (i.e. sender=receiver=this). As  far as I can see, a public tag is the only meaningful alternative to private.

inst1.x breaks the encapsulation because it implies that inst1 is not the current object (because if it were the same, x alone would suffice).

The above Java quote is clearly class-oriented; there are no classes, subclasses, or packages in DCI.

Hmm?

James O Coplien

unread,
Apr 15, 2018, 4:00:18 PM4/15/18
to object-co...@googlegroups.com


Den 15. apr. 2018 kl. 17.50 skrev Trygve Reenskaug <try...@ifi.uio.no>:

As I understand it, not being a 3GL language programmer,  protection codes in 3GLs apply to the source, not the runtime.

Not always. You might dig into the work I did on C++/P with protection domains. They are kind of like a capability machine, only inside-out.

You should also look at the work at Intel on the iAPX 432 capability-based machine, and its Ada compiler and the other associated work. It supported protection on a per-instance and per-method basis (so did C++/P).

But this is all old technology, all ca. 1985 or 1986. We learned that unless you were doing secure systems like banks, that you needed protection only between mutually cooperating well-meaning programmers. Most of that plays out at the class level, and what doesn¨t can be handled on a per-instance basis of the largest objects in the system. Most of those turned out to be at the level of the process. Today, it would be at the level of a Context.

James O Coplien

unread,
Apr 15, 2018, 5:35:03 PM4/15/18
to object-co...@googlegroups.com


Den 15. apr. 2018 kl. 14.26 skrev Matthew Browne <mbro...@gmail.com>:

Oh right. But what about:

aDemo.x = newValue

No problem if it’s public. It should be illegal if it’s private.

Matthew Browne

unread,
Apr 15, 2018, 5:44:35 PM4/15/18
to object-co...@googlegroups.com
My point was that you can't always foresee that you might want to add custom validation logic to a setter in the future. So if the language allows you to do that while keeping the above syntax, it's more robust to change. I don't consider the lack of such a feature a deal-breaker and I'd still rather have public properties than not, but this feature allows you to have your cake and eat it too -- and strengthens the argument in favor of having public properties in the language. Basically you always have the option of full encapsulation without having to pay for it up front (unless you simply got the design wrong of course, in which case encapsulation is broken regardless).

James O Coplien

unread,
Apr 15, 2018, 6:23:38 PM4/15/18
to object-co...@googlegroups.com
I think trygve perfectly accommodates your preferences.

Trygve Reenskaug

unread,
Apr 16, 2018, 2:19:41 AM4/16/18
to object-co...@googlegroups.com
"What is private in Java?
A private member is only accessible within the same class as it is declared. A member with no access modifier is only accessible within classes in the same package. A protected member is accessible within all classes in the same package and within subclasses in other packages."
I still see a difference between the meaning of 'private' at compile time and private at runtime. In Java, for example, a private member is visible within the source file, while a property private to the object is only visible within the object. aDemo.x would only be legal if aDemo is the current object. Specifically, a private property should never show up in a DCI Data object interface.

James O Coplien

unread,
Apr 16, 2018, 4:22:35 AM4/16/18
to object-co...@googlegroups.com
Trygve,


Den 16. apr. 2018 kl. 08.19 skrev Trygve Reenskaug <try...@ifi.uio.no>:

Specifically, a private property should never show up in a DCI Data object interface

This statement is unclear.

I thought DCI was a programming technique. Programming is about source code. The above statement makes sense with respect to source code: I do not know what an interface is at run time (is the access to an object’s data part of its interface? Any machine that is a non-capability-based machine can access any object state at run time with a pointer.)

That means that “private” must be a source code phenomenon and as such it can be enforced at compile time. So while this is true:

I still see a difference between the meaning of 'private' at compile time and private at runtime.

to implement it, you need help from the virtual machine. And unless it is just a suggestion for well-meaning cooperative programmers, you need to implement it in hardware.

Further, even in source code, private data “show up in the interface.” There is a difference between visibility and accessibility. A private member is often said to be “part of the private interface.” The convention is often linked to the scope of the entity hosting the element.

Last, there is the issue of aliasing. That an identifier is declared private does not mean that the associated object  cannot be accessed from outside the object: it means only that the object may not be modified through that identifier. If another identifier is bound to the same object, the object can be changed thereby — unless you have hardware protection. This property of ‘private’ seems to discount your statement:

aDemo.x would only be legal if aDemo is the current object

because it requires either capability or protection domain knowledge to enforce.

Rune Funch Søltoft

unread,
Apr 16, 2018, 5:37:05 AM4/16/18
to object-co...@googlegroups.com
And the problem about the robustness of change with custom validation goes away if you didn’t have that strange idea of mutating the instances :). Actually If you have public immutable fields on your data and don’t expose your context internals (which is what my personal interpretation of DCI would entail) most of this if not all of this discussion simply goes away. 

I’d argue that mutable data is itself breaking encapsulation and therefor everything we can think of aside immutability is not fixing the root cause but merely the symptom :). For some reason outside FP this problem has only been fixed for primitive types. When integers or strings expose their internal mutable representation all sort of weird things happen:

While i < 10 do
    i =  i + 1
    1 = i / 3 

- How many times do the loop execute?

- Why is all answers (aside from unknown) wrong?

I wrote three lines of code but because the premise was that the internal mutable representation of integers were exposed the following might apply

1) It’s an infinite loop when i < 2 to begin with
2) if 2 < i < 6 then it executes 8 - i times
3) of course that is all invalid if 1 is not actually the value of one
4) and all of the above is utter nonsense if I before I wrote the text mutated the value of the integers I used to describe the situation. 

Any mutability of data has this effect, we are however trained at ignoring it and accepting that value literals of our domain can take on arbitrary values (arbitrary in the sense that they are different than the literal)

At my present product we have various kinds of timeliness. A timeliness is represented by an object. In some work flows that timeliness is a sliding windows of 20 days and in some cases it’s 20 days from the start of the month. Let call them sliding and fixed. We could represent them with an enumeration and the object would have field for number of days and the type. 

const sliding20 = {days : 20, type : SLIDING}
const fixed20 = {days : 20, type : FIXED}

I now have to literals I can use wherever appropriate. However because these VALUES are not immutable I might have some one accidentally writing this

setDays(days) { this.timeliness.days = days }
setTimelinessType(type){ this.timeliness.type = type }

Which will work absolutely fine unless of course you at some point assign one of the literals to this.timeliness. In which case you create a scenario much like the one above with integers. 


-Rune

Den 15. apr. 2018 kl. 23.44 skrev Matthew Browne <mbro...@gmail.com>:

--

James O Coplien

unread,
Apr 16, 2018, 6:03:37 AM4/16/18
to object-co...@googlegroups.com
I do agree. But this entails a completely different way of thinking.

This example is interesting but some may discount it, because the language may not allow it, etc:


Den 16. apr. 2018 kl. 11.37 skrev Rune Funch Søltoft <funchs...@gmail.com>:

I’d argue that mutable data is itself breaking encapsulation and therefor everything we can think of aside immutability is not fixing the root cause but merely the symptom :). For some reason outside FP this problem has only been fixed for primitive types. When integers or strings expose their internal mutable representation all sort of weird things happen:

While i < 10 do
    i =  i + 1
    1 = i / 3 

Here is a real trygve program:

class VectorTest {
public void test() {
int [] intVector = new int[5];
for (int i = 0; i < 5; i++) {
 intVector[i] = i
 }
for (int i = 0; i < 5; i++) {
System.out.println(intVector[i])
}
}
}
 
(new VectorTest()).test()
 
You would probably guess wrong if I were to ask you to write down its output — and, the reason is, you are thinking in terms of low-level bit-fiddling computation, rather than a “high level” model such as one finds in algebra — and which Rune and I espouse in our advocacy for functional, applicative, and dataflow styles. (The answer is at the end of Section 4.6.2 of the trygve manual).

I feel this program takes the discussion in a slightly different direction by discussing identifier / object bindings, which is an issue closely linked to that of mutability. This program clearly uses the “high level language” notion of identifier bindings, simulating what a mathematician might employ. Most programmers are instead taught the Smalltalk model of memory cells whose contents are managed by methods, so they learn object-oriented programming through the eyes of a very low-level  it-twiddling language.

These semantics of identifier / object binding transcend the discussions of private and public, and my previous mail was an attempt to point out the futility of such discussions. In a real capability-based machines, identifiers are themselves objects (implemented as annotated “pointers” in the hardware). Anything else is just an approximation. So saying that the expression foo.X is allowed for a private X only if foo is bound to the current object is not axiomatically guaranteed: it is only a convention, and one that can be violated at that.

Of course, good dataflow also needs hardware support to enable efficient execution. While we are still simulating dataflow with Von Neuman machines (I don’t know where to buy a good dataflow machine these days) dependency registrations must be simulated with trigger wrappers around all values. That really slows things down and, further, it creates computational surprises that can be mitigated only with massive parallelism. So nothing is perfect: only an approximation. Smalltalk tried hard to do object-level protection by defining an agreed contract called a virtual machine, but it is still only a convention that I can choose to violate if I want to (the entire Baby IDE works because in some sense Trygve had the power to violate these conventions, and chose to).

Trygve Reenskaug

unread,
Apr 16, 2018, 6:22:09 AM4/16/18
to object-co...@googlegroups.com




On 16.04.2018 10:22, James O Coplien wrote:
Trygve,

Den 16. apr. 2018 kl. 08.19 skrev Trygve Reenskaug <try...@ifi.uio.no>:

Specifically, a private property should never show up in a DCI Data object interface

This statement is unclear.

I thought DCI was a programming technique. Programming is about source code.
I'm afraid you won't like the talk I just sent you, because it is about programing without any source code.

To me, DCI is a conceptual execution model that can be reified into several different techniques. I am particularly concerned about your definition of 'source code' 

I've been programming since 1958. My programming has sometimes, but not always included source code. For the first years, it was only binary instructions loaded directly into a von Neumann computer. I was certainly programming, but can't see any source code. From 1960, it was assembly. My mental model was still the von Neumann machine and my assembler was essentially converting one symbol at the time to binary. Should I regard my assembly code as source code? From 1965 it was FORTRAN and my compiler was clearly translating source code.

In the 40 years from 1978 to today, I have been programming Smalltalk. Smalltalk is a running execution in a universe objects, all persistent. When I program, I cause the execution of methods that extend and/or modify the universe of objects. There is no notion of a program in closed form, only interlinked objects. I haven't seen a conventional source code for 40 years, yet I have created many capabilities in my computer, some of them quite complex and some of them became SW products.  I suppose the main difference is that conventional programming starts with an empty computer; everything is specified in the source code. With Smalltalk, I always have a running program in a persistent universe of objects and extend/modify the objects on the fly to make them do the things I want them to do. My program then, is a combination of my new code and a some unspecified parts of the existing universe of objects. It creates itself during an execution and it has no closed form like a source code.

If you look carefully, you'll see the same model behind DCI on the single, global machine and that a Personal Programmer extends/modifies it while it is running.




Matthew Browne

unread,
Apr 16, 2018, 7:49:51 AM4/16/18
to object-co...@googlegroups.com

For the purposes of this discussion, can we set aside the fact that you can do this:

class Demo {
    private int x_

    private ExternalClass external_

    public foo() {
        external_.bar(x_)
    }
}

Trygve, correct me if I'm wrong, but I don't think you're concerned about the fact that you can deliberately pass a private value outside of the class (as above), but rather that you can directly access demoInstance.x_ from outside the instance. And it sounds like we all agree that Cope's fix to limit privacy to the instance level rather than the class level is a good thing.

Matthew Browne

unread,
Apr 16, 2018, 7:58:46 AM4/16/18
to object-co...@googlegroups.com
On 4/16/18 2:19 AM, Trygve Reenskaug wrote:
In Java, for example, a private member is visible within the source file, while a property private to the object is only visible within the object. aDemo.x would only be legal if aDemo is the current object.
This is not true in Java. As stated in the quote:

A private member is only accessible within the same class as it is declared.
Privacy in Java is at the class level, not the instance level. For example, in Java you can write an equals() method to compare the private state of two instances of the same class. Apparently the creators of Java thought that was an important enough use case to allow encapsulation to leak outside of the instance as long as you're within the same class (or perhaps this is only the result of class-based thinking and nothing else).

James O Coplien

unread,
Apr 16, 2018, 9:23:44 AM4/16/18
to object-co...@googlegroups.com


Sendt fra min iPhone

> Den 16. apr. 2018 kl. 12.22 skrev Trygve Reenskaug <try...@ifi.uio.no>:
>
> I'm afraid you won't like the talk I just sent you, because it is about programing without any source code.

What ever a human edits to control computer behavior is source code. As Abraham Lincoln said, calling a donkey an ass doesn’t make it one.

My argument stands.

James O Coplien

unread,
Apr 16, 2018, 9:24:56 AM4/16/18
to object-co...@googlegroups.com
That is source code. I’ll bet you even wrote it down on a piece of paper first.

Sendt fra min iPhone

> Den 16. apr. 2018 kl. 12.22 skrev Trygve Reenskaug <try...@ifi.uio.no>:
>

James O Coplien

unread,
Apr 16, 2018, 10:14:58 AM4/16/18
to object-co...@googlegroups.com
It’s committed on GitHub as version 3.17.

Oleh Novosad

unread,
Apr 16, 2018, 11:25:16 AM4/16/18
to object-composition
I am trying to understand your answer Trygve.

The responsibilities of M, V, and C are assumed by objects. They are primarily responsible for maintaining state: The M maintains a digital representation of some user information. The V maintains a picture of this information, e.g., as pixels on a screen.

V takes information from M, filters it("It is thus acting as a presentation filter"), adds more information about how to present information received from M. "A view is attached to its model (or model part) and gets the data necessary for the presentation from the model by asking questions. It may also update the model by sending appropriate messages. " - isn't it very similar to Roles?
 
The C creates, manages, and coordinates the Vs, so its state must include information about them.

C state must include state information about Vs only because interaction (between Vs and User) happens outside of C. 
 
All this means that we work with the M. V, and C objects in their insides.

Same as in DCI. In DCI roles interact inside of Context. From inside of Role, Role has access to Data. 
 
(There is no inherent collaboration between M, V, and C,

I think, there is collaboration. If I change one element (view) on the same page other elements might change too. If I do a text search on a web page text is highlighted in many different HTML elements. 
 
so DCI has nothing to contribute at the outer level. The M is responsible for warning its dependents (state) whenever the user information changes. M must understand the addDependent: v -message. It must sendupdate-messages to its current dependents whenever appropriate. M does not care about how the dependents will handle the received update-messages. M is a stand-alone object. We are only interested in its insides; it is specified as part of a class somewhere.) 

On this figure http://www.artima.com/images/dci/Figure5.jpg you showed that DCI Roles can work with models. And  "A view is attached to its model (or model part) and gets the data necessary for the presentation from the model by asking questions. It may also update the model by sending appropriate messages. " - isn't it very similar to Role?


The D in DCI  is a set of objects seen from their outsides; their insides are explicitly hidden.

How Is D different from M? Again on this figure http://www.artima.com/images/dci/Figure5.jpg you showed that Roles work with Models?
 
The C seen from its inside declares its roles and links to its Interaction(s) Seen from its outside, it looks like any other D object and can play roles in other Cs (recrusion). 

If Context can look like a D object it means it has state same as Controller. Also to "play roles in other Cs (recursion)" shouldn't Context first be detached from an interaction code it already has? (this is probably separate topic)

To me, MVC and DCI look analogous unless I miss something.


Trygve Reenskaug

unread,
Apr 16, 2018, 2:01:41 PM4/16/18
to object-co...@googlegroups.com
I am very sorry, but pressing works forces me to retire from the list for a while. I will rejoin as soon as the workload permits.
--Trygve
--
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 https://groups.google.com/group/object-composition.
For more options, visit https://groups.google.com/d/optout.

--

The essence of object orientation is that objects collaborate  to achieve a goal.
Trygve Reenskaug      
mailto: try...@ifi.uio.no
Morgedalsvn. 5A       
http://folk.uio.no/trygver/
N-0378 Oslo             
http://fullOO.info
Norway                     Tel: (+47) 22 49 57 27

Rune Funch Søltoft

unread,
Apr 17, 2018, 1:57:11 AM4/17/18
to object-co...@googlegroups.com


> Den 16. apr. 2018 kl. 17.25 skrev Oleh Novosad <oleh.n...@gmail.com>:
>
> To me, MVC and DCI look analogous unless I miss something.

There’s quite the chance they are different when the inventor of both says they are different.

That said, I think the notion of class in DCI is about habit more than substantiated with theory. I can easily envision a language with out class as a keyword but a data keyword and a context keyword where objects are each a context. True to the recursive definition by Kay. In such a system V and C would be contexts.

Trygve Reenskaug

unread,
Apr 17, 2018, 2:47:04 AM4/17/18
to object-co...@googlegroups.com
If you read my talk on Personal Programing, you'll see that the class plays a minor role there and is merely one of several sources of objects. The essence of DCI and PP is the runtime, not the code that is compiled at build time. Ellen, the PP programmer in the talk, do not use a single keyword.

Matthew Browne

unread,
Apr 17, 2018, 8:10:35 AM4/17/18
to object-co...@googlegroups.com
I agree that classes are not necessary for DCI, and neither are mutable
data objects. It might be better off without either of these. Of course,
it would be possible to eliminate classes and still have mutable data
objects.

The main issue with immutability is that it changes many things
regarding how you work with objects and object identity, so it's harder
to integrate into existing apps and languages. And despite the many
negative side-effects that can happen when used without care, there is
still a certain simplicity to working with mutable objects. I have been
doing more programming with immutable objects lately and am enjoying the
benefits, but I'm still not sure that my ideal programming environment
would eliminate mutability 100%. That said, I'm still new to this approach.

Matthew Browne

unread,
Apr 17, 2018, 8:13:06 AM4/17/18
to object-co...@googlegroups.com
On 4/17/18 8:10 AM, Matthew Browne wrote:
> I have been doing more programming with immutable objects lately and
> am enjoying the benefits, but I'm still not sure that my ideal
> programming environment would eliminate mutability 100%
...even if we're just talking about data/domain objects and not other
stateful objects e.g. stateful Contexts.
Reply all
Reply to author
Forward
0 new messages