Programming Is Multi-Paradigmatic
2025-04-27
Some of the paradigms that we’ve developed:
functional programming - Lisp, Sector Lisp, etc.
Relational programming - Prolog, miniKanren, datalog, etc.
Concatenative programming - Forth, Postscript, etc
OOP - Smalltalk
Prototype-based - Self,
Function-based programming - C, and, most popular programming languages. This paradigm needs virtual memory, and needs preemption and operating systems, and is a precursor to FP
State-based - Statecharts, Actors
Flowcharts
Drakon (similar to flowcharts, but more structured)
Structured programming - eschew GOTO, and scoping (which any kindergarten child knows as “not colouring outside of the lines”)
Sequential - line-by-line, with addition of subroutine calling
Recursive - lisp-y, instead of line-by-line evaluation, function-within-function
Garbage Collection - Java, Javascript, Python, Lua, Lisp. Garbage collection by default is explicitly omitted by languages like C, Odin, etc.
Asynchronous - internet, robotics, not really implemented in any programming languages - most only provide “assembler-level” access to the async paradigm
Transporter beam control flow manipulation via exceptions and setjmp/longjmp
Any of the above paradigms can be reduced to run on CPU-based hardware, which means that the paradigms must be transpiled into sequential machine code. To emphasize: CPUs do not implement these paradigms, but, sequential opcodes can be used to construct processors for these paradigms. When such processors are implemented as hardware, they run faster. Lispers often wish for “lisp machines”. Today, we have “FP machines” that implement the function-based paradigm in hardware and accompanying software (such as operating systems). Note that ideas like virtual memory are not indigenous to CPUs, but are only required to reasonably implement the function-based paradigm. Many of the above paradigms don’t actually need virtual memory, but, we have become accustomed to using virtual memory due to our use of FP machines.
At least some of the above paradigms can be reduced to run on non-CPU-based hardware. We could transpile to hardware, FPGAs, GPUs, etc. We are beginning to back into this idea, with GPU-based games and GPU-based LLMs.
Over-emphasis on a single paradigm is unhealthy and a distortion of the concept of programming. SICP encourages single-paradigmatic over-emphasis, leading to implementations of other paradigms on top of the sequential, function-based paradigm. For example, Smalltalk rests on top of the sequential, function-based paradigm. So-called “message passing” in Smalltalk is not message-passing between asynchronous units of code, but is only sequential, function-based, method calling. Most modern programming languages implement various paradigms, like relational programming, on top of the sequential, function-based paradigm. This, in my opinion, is due to the prevailing concept that “programming” is “programming of FP machines”. This is an overly limited view of programming.
Programming actually is more than just “programming of FP machines”, but, this aspect of reality as been muddied by over-emphasis on the deep exploration of the function-based paradigm.
Most popular programming languages are just mashups of various paradigms, with the common denominator being that they are all erected on top of a single, sequential, function-based paradigm. This is unnecessary. The machine needs this if it the machine is CPU-based. Humans don’t need to be restricted in this way. Squeezing every paradigm into the function-based mold leads to contortions. For example, FP is not suited to asynchronous programming nor to mutation, but, we have injected these very ideas into FP at the expense of causing bloatware. Even C, which is incorrectly purported to be “close to the hardware” over-generalizes all CPU subroutines as being “functions” instead of underlining the fact that they are only callable subroutines that might, or might not, have side-effects and might, or might not, cause mutation of memory cells. This seemingly simple wording inaccuracy has led to the belief that the epitome of programming is to ensure function purity and to eschew mutation. This causes cognitive dissonance given the fact that CPUs use mutation as a core principle of their operation - CPUs must be bolted to memory chips and must use at least some mutable RAM memory, by definition, to work.
See Also
Email: ptcomputingsimplicity@gmail.com
References: https://guitarvydas.github.io/2024/01/06/References.html
Blog: guitarvydas.github.io
Videos: https://www.youtube.com/@programmingsimplicity2980
Discord: https://discord.gg/65YZUh6Jpq
Leanpub: [WIP] https://leanpub.com/u/paul-tarvydas
Gumroad: tarvydas.gumroad.com
Twitter: @paul_tarvydas
Substack: paultarvydas.substack.com


C is function based? not imperative/procedural. How does this differ from functional programming?