Special concern for precise definitions, clarity and brevity (omitting of what is clear from the context), high level of abstraction, and proper generality (just like Sets or Numbers).

Both algebraic types (“products” and “sums”), could be used “like tables”, with new columns being added without affecting any code that is already out there.

This implies a by name instead of position-based (offset) access.

This, in turn, is the fundamental, definitive property of structs over tuples.

There is a named-tuple abstraction, which deemphasize the structural properties and order of fields.

This is a universal principle (not using an offset for access and using symbols and implicit lookup tables or maps instead).

It is possible to pretend (or restrict oneself) that both the actual order of names (slots or “columns”) and of the “rows” is immaterial.

Proper, necessary restrictions do wonders.

This is similar in properties to Sets (a most general unordered collection) and to the strict Relation Model (of Codd).

Subclassing in OO languages corresponds to the set-subset relation (\(\in\)).

Literally a set of interface is a proper subset of the set of interfaces of the superclass (isomorphic to \(A \subset B\), if you will).

This was a major “innovation” back then and huge redundant hierarchies has been built. Smart people back then said it is too rigid.

A trait is just a named set of interfaces to be implemented in order to exhibit a particular behavior (quack like a duck and walk like duck).

Composition of traits corresponds to concatenation (without nesting).

Remember that a function composition is nesting (and braces) “under the hood”.

This is a subtle but crucial difference – with composition of traits we perform Duck-typing, and do not have to become a subclass (a proper subset).

This eliminates the idiocy of having to invent a subclass for having legs.

Arguably, the most fundamental recurring pattern in all programming is nesting, in particular, wrapping.

The famous “/everything can be solved with another level of indirection” is about wrapping, which is nesting.

We wrap and nest interfaces, which is the main strategy for managing necessary complexity.

The idea is to wrap a complex, specialized interface in a higher-level, simpler, generalized, one.

The classic example is how a specific clout storage APIs can be wrapped as separate plugins (interexchangeable implementations).

This particular technique – to have specialized plugins – is a high-level (system-level) modularity “pattern”.

At a system level having stable interfaces is the universal principle, which works even at the level of molecular biology (and is actually the main underlying principle).

There is a remarkable, outstanding example of the principles at work:

Tavis Ormandy has been “ported” the old binary distribution of the classic Lotus 1-2.3 program to completely different platform from the future (literally).

https://github.com/taviso/123elf

He was able to do so because the actual CPU architecture is backward-compatible and the ABI was standardized and still supported.

What he essentially did is wrapping, conceptually at the level of interfaces, while working with the “object files” which represent compiled functions (again, the ABI is similar and the actual binary format was COFF i386).

Adding another level of indirection, (around certain functions) indeed.

This achievement is so remarkable because it proves by example (although no such prof are necessary) the validity of the universal principles behind proper non-leaking ADTs of Barbara Liskov, and all the ways back to Numbers (as defined by the Piano axioms) and the Set Theory, and through them, all the way back to the Ultimate Reality, which modern Chuds replace with arbitrary bullshit of the Mind.

Again, by properly generalizing the building blocks of Life Itself, we (well, the old Princeton and MIT guys) came up with closures (lambdas), bindings (and necessary environments), general recursion (based on the principle of mathematical induction) and branching (conditionals).

From these universal (properly generalized) building blocks everything could be made.

All the conceptual build-up from a \(+1\) to a Functor, Monoid and Matrices is, of course, not arbitrary or accidental.

Coming back to the mundane realms, the proper non-leaking abstraction (as per Barbara Liskov’s ADTs) allow not just multiple representations and multiple implementations, but mapping implementations by nesting functions, which, is an operational definition of a function composition.

Last but not least, the “dots and arrows” diagrams from the Category Theory (much hated because Chuds infested it like flies) would give one a proper insight into what is actually going on at the procedure level with all these object files, while abstracting away all the file formats and other implementation details.

It is not just a call-graph, but all the arrows between Sets (types).