Rambles around computer science
Rambles around computer science
Diverting trains of thought, wasting precious time
--><br>Mon, 10 Nov 2025
Reversing abstractions: an existential crisis
Computer science in general, and language implementation in<br>particular,<br>are founded on the idea of<br>realising abstractions<br>in a way I'll call<br>“forwards” and also “existential”.<br>This post is about how these aren't the only way to think about<br>programming infrastructure and abstractions.
The theory goes that<br>you pick some desired abstraction—it could be a programming language,<br>maybe an abstract data type, or something else.<br>Then you figure out the realisation.<br>In the case of a programming language, this could be<br>memory layouts, calling conventions and<br>a compiler that generates object code modelling these.<br>For abstract data types, it's some specific<br>concrete data structure and<br>the mapping from abstract to concrete operations.
That's the “forwards” part.<br>It's also “existential” when you<br>keep the details of the realisation to yourself.<br>Client code (e.g. source code in our new language)<br>knows there is a realisation<br>but the implementation choices themselves are hidden.<br>In turn this allows the implementer to change their minds,<br>while having indemnified themselves against any fallout<br>when this breaks things. (Cynical, me?)
I find myself drawing an ASCII-art diagram like this.
existential . abstraction<br>v / | \<br>v //|||\\<br>v . . . . . . . possible realisations -- pick one! hide it!
So far, so textbook.<br>However, this hiding isn't always done.<br>Examples of “opting out” of hiding<br>are ABIs and debuggers.
ABIs opt out of hiding in favour of a public convention:<br>certain implementation choices are documented publicly,<br>while also being embodied in code.<br>This allows independent implementations to interoperate.<br>(It's a pity ABIs aren't often defined in some more machine-readable,<br>declarative form.)
DWARF-style debugging, meanwhile, as I've written about before,<br>opts out of hiding by instead operating at the meta-level.<br>Debuggers consume machine-readable<br>descriptions of the implementation details,<br>generated by compilers.<br>Again, like ABIs, this is motivated by something about independent implementations<br>working together (but... wait).
The ABI example has simply dropped the existential<br>quantification and left us with something we could call<br>“propositional” i.e. a single, elaborated set of implementation decisions.
But the debugger's approach goes further.<br>It is the opposite of existential.<br>It is a “universal” program!<br>It consumes a description of<br>how to view the concrete, abstractly.<br>In principle it can recover the abstract view of any<br>concretion, within some domain of discourse.<br>It's universal, not existential.
universal . abstraction<br>^ / | \<br>^ //|||\\<br>^ . . . . . . . possible realisations -- recognise all!
Being universal and going backwards<br>are important but neglected abilities for a robust and flexible<br>infrastructure.<br>They seem necessary<br>for any solution to Licklider's<br>“communicating with aliens” problem<br>(a name actually due to paraphrasing by Alan Kay, I suspect).
Debuggers communicate with an alien language implementation.
(Admittedly, communication with debuggers is bootstrapped by a shared meta-level<br>convention, such as DWARF.<br>With true aliens this would not be realistic;<br>we should expect to share almost nothing at all.<br>Still, with debuggers we have eliminated<br>the need to share base-level knowledge,<br>i.e. knowledge of specific language implementations.)
I'd go so far as to say<br>the orthodox neglect of the universal<br>and the backwards,<br>in favour of the forwards and existential,<br>is part of the reason why software is not a soft material.<br>Programming artifacts remain brittle<br>because they are balanced on propositions that are both fixed and hidden—opaque<br>to other artifacts that would build on them, or interact with them.<br>These ideals go back to the dream of programming as a purely<br>mathematical entity.<br>Rather like a crystal<br>“grown” by logical inference,<br>traditional viewpoints aspire to software that is perfectly formed at all times.<br>We should “never need” to change it, because it's<br>perfect by definition!<br>But push it out of its intended alignment, and it will shatter.
Contrast this with biological organisms, which are<br>chock-full of mechanisms for probing and adapting to their environment.<br>Almost no software is like this.<br>(Notable exception: GNU autoconf. Stay with me on this.)<br>Similarly, phenotropic computing remains a distant<br>and unfamiliar idea. (The idea is Jaron Lanier's,<br>but Clayton Lewis's analysis, linked, is the best introduction I know.)
As a field, “programming languages”<br>research seems particularly averse to this “backwards” direction.
Its orthodox approaches are wedded to existentialism, and pay no regard to universality.<br>On floating the above concerns, of adaptability and...