Alternatives to OOP in D

Peter C peterc at gmail.com
Fri Nov 14 03:39:11 UTC 2025


On Monday, 1 September 2025 at 22:45:58 UTC, Steven Schveighoffer 
wrote:
>
> ...
> And also note that structs already support encapsulation. They 
> just don't do inheritance/polymorphism.
>

True, but 'structs + templates' is a usable pattern for 'static 
polymorphism' - the effect of which, is to allow interchangeable 
objects, but without having to use inheritance or virtual method 
tables.

In this example below, any type passed to the templated utility 
function 'calculateTotalArea', must have a callable area() method.

The templated utility function is actually very fast, because the 
compiler hardcodes the exact function call (rect.area() or 
sq.area()). That is, it creates a completely new function 
optimized specifically for the data type T.

However, there is a limitation. You can only use the templated 
utility function to process an array of Rectangles, and then 
again, to process an array of Squares.

Of course, with runtime polymorphism you could make a single, 
unified call - but then you have some overhead associated with 
the need to make complex decision-making during runtime execution.

If you're process a large collection of simple shape objects in a 
tight loop, then the performance of static polymorphism will 
likey win - primarly because you reduce the likelihoood of branch 
prediction failures, and having the data (value types) laid out 
contiguously in memory is ideal to fully utilize the various CPU 
cache levels.


// -------------------------------------

module mymodule;
@safe:
private:

import std.stdio;

struct Rectangle
{
     int width;
     int height;
     int area() const { return width * height; }
}

struct Square
{
     int side;
     int area() const { return side * side; }
}

int calculateTotalArea(T)(T[] shapes)
{
     int total = 0;
     foreach (s; shapes)
     {

         total += s.area;
     }
     return total;
}

void main()
{
     writeln("--- Shape Calculations (D) - Templates (Final) ---");

     Rectangle[] rects = [
         Rectangle(10, 5),
         Rectangle(20, 3)
     ];
     int rectsArea = calculateTotalArea(rects);
     writeln("\nTotal Area of Rectangles: ", rectsArea);

     Square[] squares = [
         Square(7),
         Square(12)
     ];
     int squaresArea = calculateTotalArea(squares);
     writeln("Total Area of Squares: ", squaresArea);
}

// -------------------------------------



More information about the Digitalmars-d-learn mailing list