Brief followup thoughts on the previous article. Read that first.
Classes are really just techniques to help construct objects. In an “Assemblage” language the Assemblage or Pattern itself is the way you construct the objects. The grammar explains how to parse a plain EDN or JSON-like data-literal into the assemblage.
So perhaps we don’t need classes in our Assemblage language.
Much of the experience of the last four decades is that inheritance is almost more trouble than it’s worth. The “brittle base-class” problem etc. OO practice tends towards re-use through delegating to components, rather than inheritance.
As Charles Scalfani says here, in the real world, containment / ownership relationships are far more common and far easier to reason about and work with than class or type hierarchies.
So why do OO languages emphasize, and provide special infrastructure resources to help with, inheritance hierarchies but not containment hierarchies?
Good question. The + sigil in my suggested Assemblage language is explicit language support for containment. Perhaps there could be more. And we can dispense with inheritance.
Our Assemblage language can use prototypes when something like inheritance is absolutely necessary.
Defining module boundaries, loosening coupling at boundaries and data-hiding to prevent leakage of dependency through module boundaries are obviously good practices. But making each individual class a hard bounded module is a mistake. One of the pains of Java is that classes which are inevitably and rightly highly interdependent are obliged to be more stand-offish and formal with each other than they need to be.
In Assemblage programming, the Assemblage is the natural module. An entire Assemblage would likely live within a single file. The brief, elegant grammatical description of the assemblage in a single place means that it’s easy to understand the structure of the assemblage and, if necessary, when changing it, to understand that change everywhere in the assemblage’s code.
So it makes no sense to decouple objects within the assemblage from each other. Or to hide the details of the inner structure of one object in the assemblage from others in the same assemblage.
Data hiding / privacy, if supported / enforced at all by the language, should be at the level of the assemblage and not the individual objects.
At the same time, stricter, fine-grained control over mutability is more useful. Explicitly immutable fields within objects make data-hiding less of an issue as it’s impossible for other parts of the assemblage to make unexpected changes to it.