On Monday, 1 September 2025 at 15:59:24 UTC, monkyyy wrote:
On Monday, 1 September 2025 at 13:58:23 UTC, Brother Bill wrote:
I have heard that there are better or at least alternative
ways to have encapsulation, polymorphism and inheritance
outside of OOP.
With OOP in D, we have full support for Single Inheritance,
including for Design by Contract (excluding 'old'). D also
supports multiple Interfaces.
What would be the alternatives and why would they be better?
I assume the alternatives would have
1. Better performance
2. Simpler syntax
3. Easier to read, write and maintain
If possible, please provide links to documentation or examples.
claims to not start flame wars
Its the wrong question you should answer 3 questions:
1. where is the data
2. how does data mutate
3. how do I control flow
oo is bad because its answers all three questions as **a
noun**; "Im just going to vistor pattern my gamestate manager
with my mailboxes"
to *start with* Id suggest 2 different styles:
1. going full ranges(standard)
This is a mostly functional style, theres nothing enforcing you
to be pure, but first class functions is just how `.map` works.
"Ranges are views of data", so the data stays where it started,
if you start with a File(...).byLineCopy, the data is in the
file, same with a json parser that provides a range interface.
You mutate data with maps and reduces, and you manage control
flow with take, drop and sort
2. plain old c
You have global scope, malloc and goto. You can at any time
make all your data in global scope write a giant function; if
you must allocate, call malloc, you just go edit data directly
and you can do any control flow with goto as its the only thing
hardward can do.
The answers the the 3 questions are mix and matchable.
---
Polymorphoism isn't remotely owned by oo, templates are more
polymorphic, usually "upgrades" to templates like "generics"
are about **preventing** their full polymorphic; contracts,
generics, all this talk about function attributes, all of it is
trading off the flexibility of templates to chase some safety.
*If* the problem domain is in the real world, and not the
computational world, then your proposed Data-Oriented Design
(DOD), which intentionally breaks an entity apart into its
constituent data components, effectively destroys the natural,
cohesive identity we assign to real-world objects, making
high-level reasoning more fragmented.
When I'm in a meeting with customers, I'm discussing "Customers,"
"Orders," and "Invoices" (OOP concepts), which is far more
natural and clearer than discussing "data streams".
The model that best facilitates human thought, design clarity,
and communication in the real world, is the Object-Oriented
model. It is clearly the most effective model for describing the
world.
So why would I break an OO view of the world into a DOD view of
the world?
Well...to better fit the computational world.
Of course then you are trading off design clarity for execution
performance.
My point: Neither OOP nor DOD is bad.
In an encapsulated model, you have strong cohesion refecting a
real-world entity.
In an data-oriented model (where the goal is to process data as
efficiently as possible) data is separated from behaviour, and
behaviour acts upon these separated data sets, in order to
prioritise computational efficiency over real-world object
cohesion.
Rather than calling methods on individual objects one at a time
(which can have a computational disadvantage - e.g. a a cache
miss), the CPU is can be fed a smooth, continuous stream of work.
So while DOD excels at computational efficiency, it introduces a
significant cognitive trade-off for the programmer, by shifting
from an Object-Oriented (OO) view to a Data-Oriented Design (DOD).
This can make the code harder to read and reason about.