Functionalism and mechanicalism
Identifying the two broad branches of computer science you probably haven’t heard of before.
Established theoretics is exhausted
If you study much at all in the throes of programming language theory, you probably know a lot of ins and outs about functional programming, or FP. You’re likely to have at least a cursory understanding of Lisp, and odds are high the focus of your study has a lot to do with type systems.
It’s not a disparagement to this type of person that I find it crucial now to break out and work beyond such things. Nor am I alone in harbouring this sentiment; fellow researcher Charles Rosenbauer also concurs:
It’s unlikely that any future seismic shifts in the possibilities in programming will come from changes to syntax or type systems.
In case it wasn’t obvious already, C*
— the programming language I am creating and speak of so much on this blog — has no concept of a type system at all. It’s very much like ANSI C in that it has variables that represent numerics, and struct
s for declaring the form of more complex data. C*
leans into this concept very hard, in the opposite direction of what most competitors of C do, imposing type theoretics and trying to “fix” the “mistakes” of how the old languages were modelled. C*
is a foray into the possibility that the way things originally were with C were not actually a mistake at all. Sure, it’s an incomplete model, but what C*
finds missing from it is not what every other language finds missing from it.
A new, positive framing for this foray
Rosenbauer does well to identify the object of research focus among us in the most exacting and general terms. Perhaps I am more poetic then, but I find it necessary to introduce a broad but still concrete distinction about what is new here. I want to present a positive framing — that is, a name for what this is, rather than what it is not — and that framing is the dichotomy called functionalism and mechanicalism. We’ll first go over the more familiar functionalism, and then contrast to define mechanicalism. At the end we’ll look to why this distinction is important in programming language design today.
Enter functionalism
Functionalism is one of two “broad branches” of computer science, chiefly concerned with abstract machines and mathematical computing. It is a broad grouping that originated with the lambda calculus, and is commonly known to programmers today under the banner of functional programming, although it includes purportedly multi-paradigm languages too, such as C++ and Python.
In computer science, there are two kinds of programming: one dealing with abstract machines, and the other dealing with real machines.
Abstract machines have imaginary properties that may not correspond to any real world object such as a transistor or a circuit path, and commonly include “objects” such as tuples, lists, numbers and so on. These abstract machines are then simulated on real computers by some sort of runtime, usually provided by the developers of the language the program is written in.
Functionalism is the sole cornerstone of experimental research in computing. It is the method for approaching unsolved problems, both imaginary and real world, thanks to its unparalleled ability to model in the abstract.
Functionalism is, however, a lot less useful for solving concrete problems with computers. This is because it encourages unchecked growth of complexity through its providing of abstractions that can be used to “stand in” for a complex function so that the programmer need not care about how it works.
This unchecked growth of complexity makes the systems unstable, and this causes their usefulness to become limited, as programming integrity-critical applications — such as those in aeronautics or finance — are placed permanently out of reach. With present levels of complexity abound, it is inevitable that such a system will have a bug that allows a catastrophic exploit — that is, an exploit that falsifies the abstract model provided by the functional system, which all its users and programmers depend on holding true.
Enter mechanicalism
Mechanicalism is the other “broad branch” of computer science. It is concerned with the engineering of computer software where computers are regarded as concrete machines, as opposed to abstract machines as dealt with in functionalism.
Mechanicalism takes a simplistic view of computers as machines, whose purpose is the transmission and modification of data. The idea strongly takes to a tenet from Richard Fabian’s book, Data-Oriented Design: “data is all we have”. A strong conceptual separation between code and data is adopted, in contrast to the functionalist drive to make functions “first-class objects”. Instead of making modelling an abstract idea the focus of programming, mechanicalism makes the processing of data the primary focus.
So, the approach of mechanicalism is highly dependent on the authorship of manuals and documentation to explain and narrate the machine’s actions. It is less concerned with “code reuse”, treating the task of writing code as cheap while treating the authorship of code as expensive – this is the contrapositive of what is done in functionalism, where authorship is cheap and writing is expensive.
Mechanicalism provides the sole basis for creating well-behaved and fault-tolerant systems. This makes it the only paradigm suitable for mission critical computing, such as that involving finance or military use. The concept is also indispensable for approaching bare metal silicon in order to maximise performance – this was demonstrated in the weird architecture of Parallela’s Epiphany-V processor. Often times functionalist systems are built dependent on rigid assumptions about the underlying real machine that makes their runtimes unable to cope with such architectures as the Epiphany-V. This is an obvious loss of capability on their part.
On the other hand, mechanicalism is ill-suited for experimental programming of any kind, due to its heavy focus on manual correctness and thorough ideation of the system prior to programming. It relies a lot on “doing one’s homework”, that is to say, a mechanicalist will write more about their code in English than they will write of the code itself. It is more capital-intensive in the senses that it demands more time and expertise out of a programmer than would be required in a functionalist approach.
Even so, its greater reach of use often makes this irrelevant. Re-use is a non-issue thanks to the writing so thoroughly explaining the machinery involved. Once a mechanical system has been fully ideated, writing it over again is an intellectually trivial exercise.
What’s the importance?
Computer programming has been a long journey of discovery for me since I can remember. I spent my teens learning many programming languages, and I went considerably far: learning D was my first foray into study without the help of search or QA sites, and it wasn’t long until I broke past languages entirely and learned how real computer hardware worked on the GBA, motivated by a fan game I was developing concurrently with my learning years ago.
As my pursuits wore thin on pushing the frontier of code, I turned my attention to creating projects and ideas that could bring me money or notoriety. The first thing I did was create that fan game anew as its own real video game, called Project Trinity, and I laboured intensely to implement it in code.
This endeavouring pained me endlessly due to the seeming inscrutability of modern computers in our day. Programming soon revealed itself to be an exercise in brute force, not reason, and I was resolute in my opposition to accepting this state of affairs at face value. I had already seen too much with the GBA, and with old computers in general – I knew that something was wrong and I changed my sights to look into why.
I spent years thinking and working through a lot of weird questions that I have heard nobody ask before. Starting with my decision to work with C over C++, I carried forward to ask more fundamental questions about what exactly is wrong with C++ that isn’t an issue with C. Soon I found some key essays like Some Were Meant For C by Stephen Kell, and the famed book of Data-Oriented Design mentioned before.
This soon led to my realisation that my hunch was right about the need for a new programming language. I had been unsure for years, but after finding these new ideas, it made me realise that the key to making systems well-behaved lies not in apprehending the correctness of code (formal verification), but merely in apprehending the correctness of data (law & order). C*
was born, and the rest was history.
Identifying functionalism and mechanicalism as distinct schools of thought is the next step after all of this. It is to generally formulate what is different about C*
and my approach to programming and why – with descriptions and principles that don’t relate to any specific programming language.
This is an important part of defining what is being done here under the general logos of Rosenbauer’s “expanding the possibility frontier”. We know the existing theoretics are limited, and this is a positive definition of one thing (probably among many we don’t yet know) that is next outside of those exhausted theories.
This has been another free post from Alexander Nicholi. I wanted to give this one away because it’s such a hugely applicable concept in many other writings I’ve made, threads I’ve tweeted and things I’ve yet to write. I would feel quite silly to not have it at the ready to point to when I need to furnish context but haven’t the bandwidth or energy to expend.
Real conversations are rarely good opportunities for talking like this, so thank you for reading! If you haven’t considered it already, I invite you to do so now: I run paid subscriptions for this Substack, where I strive to give away about a third of my articles. A paid subscription only costs $5.55 per month, and it helps me out tremendously in continuing to work on these things. I also take custom patronage via GitHub sponsorship if you would prefer. Thanks again!