Conceding to complexity
2024-03-16, post № 284
complexity, design, #language, #lang:c, #lang:go, #lang:haskell
In learning natural languages at higher levels paralleled with learning about their rich histories interconnecting peoples across millennia, I came to realise how shallow programming languages truly are: in some sense, everything is C or embedded into a world resting on it. Quite possibly such is not to be surprised by in view of the immense limitations an encased die cannot circumvent in our real world: computing is all done in structures borne by information state, discrete and conceptually restricted as they are.
Possibly in growing up, I grew dull to the glamour: isomorphic notation chit-chattering about same old, grand abstraction promises shattering at the coasts of implementability. What’s left after peeling off all rouge, all blush seems to me to be but one: complexity itself.
Unveiled it stares at me, neither grinning nor sighing: unconcerned with oh so many human sightings, never able to contain it, engineering failures galore.
I had an experience of late which shook me to the core when a linearily implemented base64 decoder of mine in Haskell lead to a complete program crash due to memory exhaustion (on a system boasting 16 GiB RAM plus swap), most likely due to exorbitant thunk creation. Coupled with awfully obtuse dependency and test management, I began feeling overburdened with the thought of writing in this lovely and expressive tongue I held dear for so long.
While beautiful five lines long, shapen into systems on which the outside world may press, complexity oozes out of every nook.
Appreciating the intrinsic nature of complexity, it evermore bothered me the last couple of months what I wrote in 250. a) Its claim is factually wrong: due to the subtleties involving the interplay of interface satisfaction depending only on a method’s name, removed from its provenance, yet non-exporting fully isolating a name, implementing package-bound sum types is supported in contemporary Go: sumtype.tar
b) Of even greater concern, however, is its subliminal stance valuing feature implementation as a meaningful action to overcome felt shortcomings. Here of particular relevance is the comment that recursive ADT definitions are not implementable without indirection (as infinite types exceed any finite bit representation), excerting conceptual pressure on the value classification (meaning non-pointer syntax in a recursive setting would have to either be forbidden or implemented differently to how it looks on the page). It is oh so easy to get blinded by supposed features that amount to little as rewritings, serving as distractions from the tiny specks of complexity one is seldom lucky enough to woolily make out.
Hitherto exactly one tool has been found to contain complexity: ruthless adherence to simplicity. One shouldn’t give it up in exchange for but shinier polish.