Does polymorphism exist in DCI?

Skip to first unread message

Hai Feng Kao

unread,
Sep 15, 2024, 7:01:36 AM9/15/24
to object-composition

I asked Claude Sonnet 3.5 for an example of polymorphism in DCI, and the AI gave me the following Ruby code.

In the code, the "polymorphism" is just a "switch case" statement in the context object, unlike the polymorphism in OO, which defines the behavior in each class's definition.

Is the AI's answer correct? If so, why does DCI design "polymorphism" as a "switch case"?


# Data
class Animal
  attr_reader :name, :species
  def initialize(name, species)
    @name = name
    @species = species
  end
end

# Context:Flying
class FlyingContext
  def initialize(animal)
    @animal = animal
    case @animal.species
    when :bird
      @animal.extend(BirdFlying)
    when :bat
      @animal.extend(BatFlying)
    when :insect
      @animal.extend(InsectFlying)
    else
      @animal.extend(GenericFlying)
    end
  end

  def perform_flying
    @animal.fly
  end
end

# Interaction
module GenericFlying
  def fly
    puts "#{name} is flying."
  end
end

module BirdFlying
  def fly
    puts "#{name} is soaring through the air with its wings."
  end
end

module BatFlying
  def fly
    puts "#{name} is flapping its wings rapidly in the night sky."
  end
end

module InsectFlying
  def fly
    puts "#{name} is buzzing around with its tiny wings."
  end
end

# usage
sparrow = Animal.new("Sparrow", :bird)
bat = Animal.new("Fruit Bat", :bat)
butterfly = Animal.new("Monarch Butterfly", :insect)
penguin = Animal.new("Emperor Penguin", :bird)

[sparrow, bat, butterfly, penguin].each do |animal|
  context = FlyingContext.new(animal)
  context.perform_flying
end

Marius - Adrian Francu

unread,
Sep 15, 2024, 11:51:30 AM9/15/24
to object-composition
When I saw the title in the post I recalled a series of small videos from Japan where Coplien also talks about this aspect. Here is the link of the channel: https://youtube.com/@dcitokyo3554?si=9qNm5mOc4tsf2Ieg . Is about the videos from playlist "DCI Tokyo 2". Ilike a lot that content.

In short polimorphism, if I uderstood  and recall ok, is not the main actor is more like an effect after doing what is needed.  I will watch the videos again.

James O Coplien

unread,
Sep 15, 2024, 2:15:10 PM9/15/24
to noreply-spamdigest via object-composition
FORTRAN has polymorphism, and always has. “+” is a polymorphic binary operator.

I suspect you mean inclusion polymorphism like in C++ or Java. That’s a really impoverished kind of polymorphism (though better than overloading, which is the form of polymorphism of FORTRAN’s “+” operator.) Languages like CLOS have a more generalized kind of polymorphism that can select a method on the basis of the types of multiple arguments. Most languages select methods on the basis of just one.

Polymorphism just means “many forms.” Languages like C++ generate code that can choose from among several implementations (forms) of a method, all corresponding to the same method selector, depending on the type of the (usually zeroth) argument.

DCI goes further and manages a generic algorithm that cuts across objects, so the objects work together in a network to implement an algorithm. That is how Kay characterized object-oriented programming in his very early seminal work. We can talk about that algorithm in terms of the Roles that are played by the objects in that network. DCI formalizes the notion of a Role (a class-like entity without data and which cannot be instantiated), and you can find all of the use case flow in the methods of those Roles. At run time we just find objects to play those Roles to bear each one’s data and to do the fine work of weaving the object’s data together with the Role methods.

So there are many forms of each algorithm, and we get those forms by matching up Roles and objects at run time. Many different objects may be suitable for playing the same Role. That’s polymorphism. You can do everything you can do with delegation or inheritance, and more — it is run-time dynamic and, in languages like trygve, is type-safe. Further, one object can play multiple Roles. For example, if you have the roles Model, View and Controller, it is common to have one object which is the View-Controller, reflecting the tight coupling between them — while still separating the use case concerns of View and Controller in their respective Roles.

So, yes — DCI has polymorphism. It’s polymorphism is much better suited to what Smalltalk calls messaging than to what C++ calls virtual functions, though it is more powerful than either one of those. By DCI’s standards most other languages — other than perhaps CLOS — have only quite impoverished polymorphism models.

--
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/9b2d5bd3-c984-4986-af6e-bdfdd1469f35n%40googlegroups.com.

Matthew Browne

unread,
Sep 18, 2024, 5:45:47 AM9/18/24
to object-co...@googlegroups.com

Cope's answer is great (Cope = nickname for James Coplien, if you didn't know).

I think it might also be worth mentioning that designing objects with polymorphism can have downsides too, even in DCI (mainly in the "data" part where in most languages you still have classes and inheritance), if it's overused or used inappropriately. The main tradeoff to think about is how difficult it will be to determine where a method call actually ends up at run-time. I feel that the name of this group speaks to this a bit - often you can accomplish polymorphism in a clearer way using composition rather than inheritance.


Matthew Browne

unread,
Sep 18, 2024, 5:45:47 AM9/18/24
to object-co...@googlegroups.com

P.S. Inheritance isn't always bad, in case it sounded like that's what I was saying.

Marius - Adrian Francu

unread,
Sep 18, 2024, 5:45:47 AM9/18/24
to object-co...@googlegroups.com

When I saw the title in the post I recalled a series of small videos from Japan where Coplien also talks about this aspect. Here is the link of the channel: https://youtube.com/@dcitokyo3554?si=9qNm5mOc4tsf2Ieg . Is about the videos from playlist "DCI Tokyo 2". Ilike a lot that content.

In short polimorphism, if I uderstood  and recall ok, is not the main actor is more like an effect after doing what is needed.  I will watch the videos again.


--

Lund Soltoft

unread,
Sep 18, 2024, 5:45:47 AM9/18/24
to object-co...@googlegroups.com
This is by no means DCI.   What polymorphism accomplishes in class oriented programming DCI accomplishes through contexts BUT they are very different and should generally not be equated. A context is sufficiently generic for potentially multiple different types of objects to play a role. Yet contexts are also specific enough for them to be reasoned about without knowing the concrete type of the RolePlayers. 

Mvh
Rune

Den 15. sep. 2024 kl. 13.01 skrev Hai Feng Kao <khai...@gmail.com>:


--

Hai Feng Kao

unread,
Sep 20, 2024, 4:03:07 AM9/20/24
to object-composition

Regarding the definition of polymorphism:

Polymorphism means that the sender of a stimulus does not need to know the receiving instance’s class. The receiving instance can belong to an arbitrary class.

(Object-Oriented Software Engineering: A Use Case Driven Approach, p.55)

This definition emphasizes that the sender of a stimulus doesn't need to know the receiving instance's class. In DCI, while there's flexibility in which objects can play which Roles, the Context object does have knowledge of the specific instances it's working with, as it's responsible for assigning them to Roles.

I think you and Ivar Jacobson have different views about what polymorphism is, but I don't have the knowledge to judge which definition is more correct.

Cope 在 2024年9月16日 星期一凌晨2:15:10 [UTC+8] 的信中寫道:

James Coplien

unread,
Sep 20, 2024, 4:13:42 AM9/20/24
to object-co...@googlegroups.com


Sent from my iPad

> On 20 Sep 2024, at 10.03, Hai Feng Kao <khai...@gmail.com> wrote:
>
> I think you and Ivar Jacobson have different views about what polymorphism is, but I don't have the knowledge to judge which definition is more correct.

I write code. Ivar writes methods. Polymorphism is a coding thing.

The English meaning is for an animal to be able to change sex to be able to support reproduction, as earthworms and some lizards do.

Peter Wegner wrote the seminal OOPSLA paper that defined and classifies the four kinds of software polymorphism. Go beyond collecting opinions and do a bit of research.

Kay notes that he never considered inheritance central to OOP (and he is the source of the term). If polymorphism is what I think you imagine it to be, it’s almost irrelevant in my world. Yes, you can still use it to create classes that are instantiated as role-players but it makes the code less readable.

Matthew Browne

unread,
Sep 20, 2024, 6:47:24 AM9/20/24
to object-co...@googlegroups.com

@Hai is there an actual problem you're aiming to solve, or perhaps to evaluate if you can solve it better with DCI than other approaches? This discussion seems very abstract, and I can't tell what you're driving at.


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

Hai Feng Kao

unread,
Sep 23, 2024, 6:54:41 AM9/23/24
to object-composition
It is indeed very abstract. I am preparing my talk about DCI in iPlayground 2024. 

Take turtle graphics as an example: the turtle can "move forward", "turn left", and "turn right"

If I want to add a new action for the turtle
In OOP, just add new action class and inherits from "Action". I don't have to change other parts of the program. 
In DCI, I will add a new enum value to ActionEnum. Then I have to update all switch cases in relevant contexts to handle the new enum value. 

Implement a single object and done 
vs
Add a new enum value and update all context objects

Uncle Bob: You should be able to extend the behavior of a system without having to modify that system.
https://blog.cleancoder.com/uncle-bob/2014/05/12/TheOpenClosedPrinciple.html

I think inclusion polymorphism is more aligned with the Open-Closed Principle.


mbro...@gmail.com 在 2024年9月20日 星期五下午6:47:24 [UTC+8] 的信中寫道:

Matthew Browne

unread,
Sep 23, 2024, 7:31:58 AM9/23/24
to object-co...@googlegroups.com

Hi Hai,
I really think you are going about this the totally wrong way. If you mention DCI in your talk, I think you should just be honest and say you're still learning DCI (and haven't ever used it on a real project? If that's the case), so you don't give people the impression you're an expert and unfairly represent DCI. I certainly wouldn't let AI-generated code influence your thinking or your presentation in any way. To the extent that LLM-based AI ever "understands" code, it's extremely unlikely to "understand" DCI code because DCI code isn't widespread, and the DCI code on the web is a mix of good DCI code as well as some code labeled as DCI but either isn't DCI at all (due to people not understanding the importance of object identity and just trying to implement it in an existing programming language in a naive way), or code that is from someone just learning it or trying it out for a trivial example.

I have been in this group for many years now, and have never even seen DCI code like the FlyingContext example the AI came up with. It's really hard to talk about that AI example because I don't even know what problem it's trying to solve, but if there were a real problem I'm fairly certain that DCI programmers would solve it in a very different way.

And it's just generally true in life that if you really want to understand something and go beyond the most surface-level knowledge (or misunderstanding), you have to really dig into some concrete examples - and in the case of DCI, write plenty of code - and not only think in the abstract. I know that if you're trying to give a summary and contrast different approaches, that part of your talk might need to be abstract, but the way that's supposed to work is that you understand the topic concretely yourself and *then* summarize it abstractly, and perhaps offer a very simple concrete example so your audience can start understanding it too.


Hai-Feng Kao

unread,
Sep 23, 2024, 8:15:19 AM9/23/24
to object-co...@googlegroups.com
You are right. I need a simple concrete example.
Flying example is just a standard example to explain inheritance of
OOP to university students. It is interesting that you have never seen
the corresponding example in DCI.

So what is the right way to implement the turtle graphics in DCI? How
would you design it?

Matthew Browne <mbro...@gmail.com> 於 2024年9月23日 週一 下午7:31寫道:
> To view this discussion on the web visit https://groups.google.com/d/msgid/object-composition/CAJA9FQ9-AXQhJmv0N31gEiWucZY%3Dnxy-do58x9W2_ZBkHnnL_w%40mail.gmail.com.

Serge Beaumont

unread,
Sep 23, 2024, 8:40:03 AM9/23/24
to object-co...@googlegroups.com
As a suggestion for your own journey, forget about DCI for a bit. Forget about the creation and wiring logic and all the coding specifics.

I'd start with the user's interaction with the system, as if you're writing the user manual. What are the scenarios that this user is trying to achieve? When you have those listed, then realize that each of these "stories" is a first class citizen in a DCI system. Analogous to a play, you'll then identify the roles specifically within the context of that play, and the interactions between them. In Romeo and Julia you don't care about what they do or say outside the context of the play. Only then you may start with a connection to "data".

What I hope to convey with this bad example that in class based OOP we were all raised on we always went Data => Behaviour, by defining classes and then writing code that lets the behaviour emerge. My suggestion is to think the other way around: Behaviour => Data, start with the "stories" as first class citizens and then let that inform you on what "Data" you may need.

It's not necessarily how DCI systems need to be made, but I think it may be a good exercise for you to help you understand the paradigm shift.
> To view this discussion on the web visit https://groups.google.com/d/msgid/object-composition/CAF0aJ5ecUuzdvWT3HdntLO%2BEa6E%3DhBMSa%3D2aHsREpXU5cHyC-A%40mail.gmail.com.

Matthew Browne

unread,
Sep 23, 2024, 9:05:27 AM9/23/24
to object-co...@googlegroups.com, Hai-Feng Kao
On 9/23/24 8:15 AM, Hai-Feng Kao wrote:
So what is the right way to implement the turtle graphics in DCI? How
would you design it?

I have some concept of turtle graphics and know that example has been around forever, but I personally haven't implemented them because they weren't part of the tutorials when I was first learning to program or the computer science classes I took. Not that I would need to be familiar—I'm sure looking at it with fresh eyes could be helpful.

But I would start by saying not to assume that it should even be written in DCI in the first place. DCI takes OO to a new level but OO is still the foundation, and some use cases are simple enough (from the role-behavior perspective) that there isn't a need to introduce DCI. In his book "Lean Architecture: for Agile Software Development", Cope makes a distinction between an "atomic event architecture" and a DCI architecture. Simple object-oriented systems like a drawing program to draw various shapes on the screen would be an example of an "atomic event architecture" that doesn't really need DCI. In those cases, you can just put the behavior and data together in the same code construct (usually a class) and have no problem, because the behavior and data are naturally coupled and don't diverge like they do in many other use cases. I could point you to some more resources about this if you're interested.

There are plenty of folks in the group (myself included) who are interested in a programming model where you only have DCI contexts and no classes, but even in that case you'd still have a separation between the data part—which is much more static—and the dynamic behavior part where roles are more prominent. And there could very well still be behavioral parts of the system that are more like "atomic event architecture" and end up looking a lot like traditional OO even in the absence of a "class" keyword or inheritance.

Lund Soltoft

unread,
Sep 23, 2024, 9:59:55 AM9/23/24
to object-co...@googlegroups.com
A little exercise in understanding the expressive power of DCI. 

How would you in a class oriented language sensibly use a vector to represent any animal?

I think the answer is you wouldn’t but it’s indeed possible with the DCI mechanics that I commented on earlier. You can break down any type to its fundamental properties, such as its position for an animal. You can add “Move” as a method to a context and have a vector play the role of position. 
Den 23. sep. 2024 kl. 15.05 skrev Matthew Browne <mbro...@gmail.com>:



Hai-Feng Kao

unread,
Sep 23, 2024, 12:42:24 PM9/23/24
to object-co...@googlegroups.com
@Lund
No, the position is not enough to determine animal type. Different
animals may have different ways of moving. If I want to implement a
MoveContext to update the animal's position, I still need an animal
type.
In OOP, I can just call the animal's move method, let it update its
own position without knowing the animal type. In DCI, the context
needs to know the animal type to assign a proper role.

@Matthew
I have to admit that I only read the DCI chapter of "Lean
Architecture: for Agile Software Development". I have full of
questions after I read it. That is why I am here.
I do believe that I can write an entire program using DCI. It's a
programming paradigm, like OOP or FP. It should be able to write any
program.
DCI may make code more complicated in a simple scenario. I think it
is a very important part of learning DCI.
But the books written by Cope or Trygve miss this part -- "When not to use DCI"
Programming paradigms are not silver bullets, they are tools. Every
tool has pros and cons. I cannot master a tool until I know when not
to use it.

@Serge
Yes, behaviors. Even for a simple program like turtle graphics, I can
come up with different kind of behavior designs.
I can model each command "forward", "turn left", "turn right" as
context objects.
Inside the context, the pen, canvas and turtle's position will
interact to draw the graphics.

Or I can model the commands as data.
Let DrawContext assign the proper roles to these commands. Let the
pen, canvas, turtle's position, and the command interact to finish the
drawing.

Or I can model the commands as both context and data objects.
Let DrawContext assign the proper contexts to these commands and
assign these contexts as roles.

Or I can just use OOP and model the whole program as a turtle object.
Each command corresponds to a method of the turtle. The turtle's
position is private and will never be accessed by anything outside the
Turtle class.

Or I can just use procedure codes, no objects. I think the procedure
codes is the most intuitive and clean way to implement turtle
graphics.

But if I add new use cases, e.g. UndoContext, RedoContext, and
RecordCommandHistoryContext, the advantage of DCI will begin to show
up. DCI makes each use case very obvious and it won't create a huge
turtle object.
Too bad I don't find any books to teach me this kind of stuff.

Lund Soltoft <lunds...@gmail.com> 於 2024年9月23日 週一 下午9:59寫道:
> To view this discussion on the web visit https://groups.google.com/d/msgid/object-composition/268336BB-F008-4EB0-B40E-9B10E2A0BA5E%40gmail.com.

Matthew Browne

unread,
Sep 23, 2024, 12:54:20 PM9/23/24
to object-co...@googlegroups.com
One quick thought on this for now: in DCI, most likely you would still just have one turtle object that can do anything a turtle can do - same as OOP. In other words, you wouldn't have a "moving turtle", "undo/redo turtle", "resizable turtle" etc as separate objects. That behavior might exist in different parts of the source code in DCI (the turtle might participate in different interactions in many different Contexts), but remember thet there's a big difference between compile-time and run-time. One of the difficulties with class-oriented programming is that it conflates the two.

James O Coplien

unread,
Sep 23, 2024, 4:31:59 PM9/23/24
to object-co...@googlegroups.com


On 23 Sep 2024, at 18.54, Matthew Browne <mbro...@gmail.com> wrote:

One quick thought on this for now: in DCI, most likely you would still just have one turtle object that can do anything a turtle can do - same as OOP.

Lay defined object-oriented programming as a cooperation by a network of objects cooperating to implement some algorithm.

What in the heck is the network of objects in a turtle program?

Aren’t you just doing abstract data types?

Kay used turtles to underscore the role of messaging, and to underscore that it was natural to teach it (e.g., to children.) DCI implements messaging. Not all so-called OO languages do.

But OO is more than messaging (and certainly more than polymorphism). If you’re giving a lecture either on OO or on DCI I think that turtles is hardly a suitable example.

I do believe that I can write an entire program using DCI. It's a
programming paradigm, like OOP or FP. It should be able to write any
program.

It is also true that you can write FORTRAN in any language.

If you want to learn DCI well enough to give a talk on it, I suggest downloading the trygve environment from GitHub (jcoplien/trygve) and evaluating the self-organization example. It is probably the most object-oriented program you can find.

James Coplien

unread,
Sep 24, 2024, 6:48:08 AM9/24/24
to object-co...@googlegroups.com
Yes, Matt: this is a good characterization of the self-organization example. Individual turtles (why not?) in this example know their location and can be asked to move to a new location; and they know primitive qualities such as their color and name.

However, the algorithm to decide where to move the turtles, and when to move them, is in the CurrentTurtle Role. That Role has this method:

boolean checkAndAdjustPosition() {
    boolean somethingMoved = false
    List<Player> neighborList = Neighbors.of(this)
    Player player1 = neighborList[0], player2 = neighborList[1]
    double distance1 = distanceTo(player1), distance2 = distanceTo(player2);
    if (Math.abs(distance1 - distance2) > GameData.DELTA) {
        PlayerMoveCount.incrementCountForPlayer
        moveToSameDistanceFromNeighbors(player1, player2)
        somethingMoved = true

        // tail recursive
        for (Player p : myWatchers()) {
            CurrentPlayer = p
            CurrentPlayer.moved
        }
    }

    return somethingMoved
}

It also has the method moveToSameDistanceFromNeighbors(player1, player2) to evaluate the location to which it should move to realize the program goal. The object knows how to calculate this given the locations of other players (which it can obtain from its connections). However, the class Turtle does not know. Turtles in general don’t know how to do this calculation; we have to teach them, and we teach them by connecting them to the Role they play. The Turtle does not need to know this if we are just using it in turtle soup, so we don’t want to burden the turtle with all the baggage it needs for this use case and the millions of other use cases in which turtles might be involved. It may change Roles and therefore in the responsibilities it supports even during the execution of a program. This is why messaging is important.

The Turtle Role also knows that it must notify the two other Turtles watching it when it moves, so they in turn can awake and update their location. That knowledge owes to the Turtle’s involvement in the use case (its Role) rather than to its Turtle-ness (its class). That makes it possible to reuse the same use case code for Yertles as we wrote for Turtles — without any editing or even recompilation. I think your approach requires adding the same code to any animal you desired to be subject to this algorithm.

The thing about the self-organization example is that it models a use case. Your grandfather’s object-oriented programming was good for trivial operations, which is why so many books use examples of a shape-drawing program where each object can act autonomously. There is no real use case entailed either in changing the color of an object, or in changing its location or size.

You have mentioned no use case for your turtle example. It may well be that there are many use cases that could use primitive turtles (maybe you could have them self-organize…). In the absence of a use case you indeed are just as well off to use your grandfather’s style of objects.

We call that “abstract data types” or “class-based programming.” Kay defined object-oriented programming to entail an algorithm (use case) which a network of objects cooperate to implement (as in the self-organization example=.

So, Hai-Feng, I don’t see any of your responses venturing into this territory. I hope this helps you understand the difference between what you are trying to do, and what we are trying to do to implement the visions of Alan Kay and Trygve Reenskaug.

 
On 23 Sep 2024, at 18.54, Matthew Browne <mbro...@gmail.com> wrote:

Hai Feng Kao

unread,
Sep 24, 2024, 11:16:56 AM9/24/24
to object-composition
@Cope

I have already learned this territory from your and Trygve's book. I want to explore outside this territory.

I do not treat DCI as a design pattern. I think DCI is a programming paradigm; it should be able to build all kinds of programs.

But I don't know how.

That is why I am trying to convert textbook examples from OOP into DCI.

I should be able to build logging systems, data repositories, and plugin architectures using DCI.

Maybe DCI is a very unsuitable paradigm for this kind of stuff, but I should still be able to do it.

That is what I am trying to explore.


Cope 在 2024年9月24日 星期二下午6:48:08 [UTC+8] 的信中寫道:

Lund Soltoft

unread,
Sep 24, 2024, 1:45:34 PM9/24/24
to object-co...@googlegroups.com
@Hai
I believe you can model all the programs you want to in DCI including all the classical class oriented examples. However, approving it from the class oriented perspective will provide some weird looking DCI code that isn’t really DCI. 

To me there a several flavours of contexts. One and probably the one that makes DCI so unique is the one that bridges the gap between the developer mindset and the user mindset. Ie the type of contexts that expresses a use case. 

But there are other types where the interaction between to objects is what makes it interesting. Ie the two values “Store Kannikestræde” and 18 are kinda boring but combine them and you have an address. The relation (there’s no real interaction) is what provides most of the important value. Combine it with a name like Charlie Brown an it’s even more interesting. It’s no longer an address it’s the address of Charlie Brown. You can keep building these small collection where small pieces of generic data interact and where the interaction is what provides most of the value. Each of the steps can be both extremely generic (like when you start modeling an animal by just its position) but at the same time be very expressive about the intended behaviour.  

I find it far easier to get to DCI code from a class oriented example if I start as Sarge suggested. From the outside. Forget about the model used in the class oriented example. They are often wrong any ways (you can’t derive a square from a rectangle because that would violate the invariant of a square, yet a square is-a rectangle). 
From the outside find the elements that interact to create the value, where each element is generic enough to be used in a different scenario while also being specific enough to communicate the role it plays in your specific scenario. 

For each of those elements see if they too can be divided into something that’s both generic and specific. At some point you end up with immutable values like numbers, strings and booleans and how you’ve defined your types will likely look very different from the OO example yet being able to express the same and a lot more than just that example



Mvh
Rune

Den 24. sep. 2024 kl. 17.16 skrev Hai Feng Kao <khai...@gmail.com>:

@Cope

James Coplien

unread,
Sep 24, 2024, 3:54:58 PM9/24/24
to object-co...@googlegroups.com


On 24 Sep 2024, at 17.16, Hai Feng Kao <khai...@gmail.com> wrote:

That is why I am trying to convert textbook examples from OOP into DCI.

That’s kind of like trying to convert textbook examples of automobiles into airplanes.

James Coplien

unread,
Sep 24, 2024, 3:55:55 PM9/24/24
to object-co...@googlegroups.com

On 24 Sep 2024, at 17.16, Hai Feng Kao <khai...@gmail.com> wrote:

I should be able to build logging systems, data repositories, and plugin architectures using DCI.

Why?

Maybe DCI is a very unsuitable paradigm for this kind of stuff, but I should still be able to do it.

Indeed. DCI is Turing-complete.

Matthew Browne

unread,
Sep 27, 2024, 11:16:38 AM9/27/24
to object-co...@googlegroups.com
On Mon, Sep 23, 2024, 7:59 AM Lund Soltoft <lunds...@gmail.com> wrote:
A little exercise in understanding the expressive power of DCI. 

How would you in a class oriented language sensibly use a vector to represent any animal?

Hi Rune, I think this could be an interesting exercise to explore (and hopefully Hai is interested in it too), but first I wanted to check if I understand correctly... When you say using a vector to represent an animal, do you mean like a line drawing of an animal represented as a series of X-Y coordinates?


Lund Soltoft

unread,
Sep 27, 2024, 12:36:18 PM9/27/24
to object-co...@googlegroups.com
Hi Rune, I think this could be an interesting exercise to explore (and hopefully Hai is interested in it too), but first I wanted to check if I understand correctly... When you say using a vector to represent an animal, do you mean like a line drawing of an animal represented as a series of X-Y coordinates?

In a graphical environment like a game or an animation. The sole attribute I can think of, that is needed in all contexts (pun intended) is the position of the animal. Without that drawing it in relation to the scene isn’t possible, moving it is insensical (what’s movement without position?) and so on and so forth. Conversely all behaviours are built, potentially incrementally, on the position. One way to represent a position is a coordinate. However a vector has direction as well, so by using a vector we get the position as well as the direction with very little extra cost. 

In the context of movement all we need to do is move the vector or turn the vector. Both simple math operations and so generic that it can be reused for a lot of things. If we can move an object and we know the weight (another role) then we can apply physics. Still in a very generic sense but where all the relevant information is expressed very clearly if you know the context. Ie force of gravity, velocity, drag an so forth makes sense even if you don’t know whether it’s a turtle or a bullet. 

If we then what to animate the objects motion we would need a geometric shape (or a combination of) and a skin as well as the position at a given frame. To know the position at the next frame we’d need to know the present, as well as perform the physics calculation and lastly move the object to the new location by updating the vector. 

What the user sees and what the animator is working with fits there mental model (my cousin used to be an animator for Disney studios and I actually got inspired for this example by seeing her work).
 Similarly the person doing the physics modelling can work with the tools of some one with a major in physics ie express it in math/their mental model. Each step in the built up from a vector to an animal (potentially) represents a new mental model. 
A mental model suitable for the consumer and it does so without loosing expressive power. On the contrary because it can use the mental model of the consumer it can be sufficiently precise in its expression. 

Matthew Browne

unread,
Oct 14, 2024, 9:51:42 AM10/14/24
to object-co...@googlegroups.com

Hi Rune,
I've been busy, so just now starting to think about this again...

First of all I want to give the disclaimer that I know next to nothing about how computer graphics are calculated (I've been spoiled by letting the web browser do all the work for me ;) ), so this is all new to me.

In terms of updating system state, are you essentially suggesting that there would be a "current position" vector and then a second vector used to calculate the new position every time you want to move the animal?

And just to make sure we're on the same page about vectors, instantiating a new vector would mean something like the following, correct?:

new Vector(distanceToMoveHorizontally, distanceToMoveVertically)

Lund Soltoft

unread,
Oct 14, 2024, 3:43:18 PM10/14/24
to object-co...@googlegroups.com


> Den 14. okt. 2024 kl. 15.51 skrev Matthew Browne <mbro...@gmail.com>:
>
> In terms of updating system state, are you essentially suggesting that there would be a "current position" vector and then a second vector used to calculate the new position every time you want to move the animal?

That is in broad strokes how the physics engine works yes.

Matthew Browne

unread,
Nov 15, 2024, 8:52:25 AM11/15/24
to object-co...@googlegroups.com

Hi all,
It turns out that turtle graphics might be an interesting use case for DCI after all, if you want the app to be extensible to support other moving objects besides turtles.

@Rune I don't know if this is quite what you had in mind, but here's the example I created, inspired by your idea:

https://codesandbox.io/p/sandbox/turtle-graphics-dci-example-6p6zsj

I decided to modernize it a bit by also including a feature to make the turtle go somewhere simply by clicking where you want it to go.

I have no prior background in vector math or game development, so I'm happy to take any suggestions to improving that implementation, but naturally I was mainly interested in the DCI aspects here. It's just a POC and has some flaws (which could probably be fixed without too much effort), e.g. it will happily let you move the turtle off the screen entirely.

The interesting DCI parts about this are:

1. It's polymorphic, i.e. it would work with any kind of object that you want to be moveable in a similar way

2. It reflects more than one mental model thanks to a nested context (LinearMotionIntent is the outer context and LinearMotionPhysics is the nested context that implements the actual movement).

This is also the first time I've I instantiated a nested context in a dynamic way: rather than passing a LinearMotionPhysics instance to LinearMotionIntent, you pass the LinearMotionPhysics context declaration (could be any Context that implements the necessary methods):

https://github.com/mbrowne/dci-examples/blob/e39b9f08d969a416ae9d53ae5adfc5b382df61d2/turtle-graphics/LinearMotionIntent.js#L19-L30

...So LinearMotionIntent takes care of the implementation details of how to instantiate LinearMotionPhysics (in this case just passing the body argument, but I could imagine this being a generally useful pattern for cases like this).

Let me know what you all think! :-)

Lund Soltoft

unread,
Nov 18, 2024, 3:59:59 AM11/18/24
to object-co...@googlegroups.com
Hi Matt,
Being somewhat unfamiliar with the code style/tooling it took me sometime to read but from what I gather I think you got my idea, which to be honest was about showing the expressiveness of DCI. How DCI captures the concept all programs are build on. They start (or end depending on your model) at the binary level and then we keep compressing. ASM is a level of compression on machine instructions, programming languages are another the OO paradigm sought to be another level of compression and DCI makes this vision possible of continual compression with a specific domain in mind.

In computer games there's a visualization domain and a motion domain. They have some common dependencies, like position but how they use position is independent. The intention of going to the extreme of modeling from a vector was to try and show how adding levels of compression even to primitive types can fulfil even the complexity game engines. Personally I think it expresses the domain better than inheritance because depending on where your work is and where your mental model is, there should be a level of compression that fits you


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

Matthew Browne

unread,
Nov 18, 2024, 7:38:42 AM11/18/24
to object-co...@googlegroups.com

Hi Rune,
Yes, that's what I was going for - the LinearMotionPhysics context is the lower-level mental model in this case, and LinearMotionIntent (meant to reflect the mental model of an animator or designer, and in this case is also simple enough to match the mental model of the game player) builds on and is a compression of the LinearMotionPhysics context.

I'm not sure how one could implement an example like this with just a single vector as the main shared role player between the two mental models, which is what I initially thought you were suggesting, so that's why I created the Body2D class based on something I had seen in another game example, which was mainly useful as a way to encapsulate position (a vector) and angle (stored as just a number in my example) together. I'm sure there's more than one way of modeling a vector, and it could be interesting to explore an alternative model if you had one in mind, but either way I think the way the turtle/object is shared in these two very generic contexts helps show the usefulness and potential of DCI.

Thanks,
Matt


Matthew Browne

unread,
Nov 18, 2024, 7:43:02 AM11/18/24
to object-co...@googlegroups.com

Oh, and one other detail I forgot to mention: the LinearMotionPhysics context uses role re-binding a lot, but it would also be possible to implement it with immutable role bindings / creating a new context every frame of the animation where the object changes position. I'm not sure which would be better in this case, but re-binding seemed simpler to me while writing it.

Lund Soltoft

unread,
Nov 18, 2024, 9:05:18 AM11/18/24
to object-co...@googlegroups.com
If you model a vector as an origin. A length and an angle you’d get what you need. A change in velocity would be a change in length, a rotation would change the angle and a change in time would change the origin (a long the vector)

Mvh
Rune

Den 18. nov. 2024 kl. 13.43 skrev Matthew Browne <mbro...@gmail.com>:


Reply all
Reply to author
Forward
0 new messages