2024-08-03-Functional vs. Function-Based Thinking and Mono-paradigmatic Programming
I am more focussed on developers than on non-programmers. I feel that development has stagnated due to too much emphasis on “functions” instead of keeping all options open. Development is too much “inside the box”, due to the use of a single paradigm - function-based thinking.
I try to be careful to use the phrase “function-based programming” instead of “functional programming”. Function-based programming covers many more programming languages than functional-programming covers.
The issue is with the meaning of the word “programming”. I think of “programming” to mean solderless - quick and easy - reconfiguration of reprogrammable machines. At that low level, functions are not inherently supported by hardware - you have to add software and hardware to make “programs” work like “functions”, i.e. you have to add lots of inefficiency to allow manipulation of reprogrammable hardware to make the hardware expressible as mathematical equations written on paper.
I think that the paradigm of functions-grafted-onto-hardware is inappropriate for many modern problems, like internet, robotics, gaming, GUIs, etc. as witnessed by the invention of extreme gyrations and work-arounds such as thread libraries, promises, monads, etc.
Early FORTRANs and BASICs did not actually express hardware manipulation as mathematical functions although the notation used looks a lot like functions. Some of the purveyors of early programming languages may have wished that hardware was like mathematics, but, they didn’t achieve such nirvana. They used words like “subroutine” and “procedure” instead of words like “functions”. This apparently tiny detail belied the reality that CPU subroutines are not functions.
Early Lisps showed that grafting functions onto hardware was viable and was a productive paradigm. Sector Lisp shows just how clean and small the result is when the functional paradigm is respected.
Early games, though, showed that this kind of thinking was not necessary for producing useful results.
I feel that so-called “computer science” ran with only the one paradigm - inefficient, function-based thinking mapped onto hardware manipulation - at the expense of cutting off many avenues of problem-solving.
For the record, C and Pascal and Haskell and Python and JS and WASM and Scala and many other programming languages, are function-based, while PROLOG is not function-based, and, StateCharts are not function-based.
I think that the function-based mentality deeply affects developers and, therefore, affects what developers can invent for non-programmers.
For example, I think that spreadsheets present an excellent interface to computers for non-programmers.
I think, though, that spreadsheets are just a stop-gap technology. Spreadsheets are “the best” that programmers can provide for non-programmers given developers’ function-based mentality.
Mathematical 2D notation is OK for use with papyrus and clay-tablet media, but, is not necessarily the most appropriate way to think about reprogrammable electronic machines in 2024. So, in my mind, we need to change the culture of developers before even trying to imagine FoP (Future of Programming).
I think that The Mother Of All Demos (TMOAD) was not bound by the function-based paradigm and that function-based programmers hold TMOAD in awe because it looks to be non-understandable - like magic - from a mono-paradigmatic perspective. I think that it would behoove modern programming researchers to delve deeply into TMOAD and to see how it differs from function-based thinking.
Functional Programming Engines
The idea of treating CPU chips as function interpreters is valid, but, is extremely restrictive.
CPU chips don’t implement “functions”. CPU chips implement “subroutines”. We can use CPU chips to fake out functions, but, the cost is efficiency. We must add software - “context switching” and “traps” and “virtual memory” and “multi-tasking operating systems”. Often, we also add hardware, e.g. MMUs, at the expense of eating up die space on the chips which could be used, instead, for providing more CPUs, more memory, more registers, etc.
Is the expense worth it? In 1972, the game of Pong could be built with about $100.00 worth of chips on one circuit board, whereas in 2024, Pong needs megabytes of memory and a full-blown computer. 2024-1972 = 52 years. Hmm. Sounds like a bad investment, when put in those terms.
For some 40+ years, I’ve been vexed by the observation that hardware design seems to produce more reliable results than software design does. The problem, in my mind, isn’t what is presented to non-programmers, the problem is what developers use.
Developers base most of their thinking on the idea that CPUs must be used as function-interpreters. This is what I call “function-based programming”. Simple observation says that this kind of thinking ain’t working. 50+ years and we ain’t there yet. Where is “there”? Making something as cheap and as reliable as we did in 1972.
So-called “computer science” is a science about using reprogrammable electronic machines for expressing functional thinking, rather than a science about analyzing how reprogrammable electronic machines work.
Functional programming notation denies the existence of time. “Functions” can be manipulated faster than the speed of light. To employ “referential transparency”, you simply need to invert your pencil, erase a sub-function, then, replace it with a different function1.
Reprogrammable electronic machines can be employed for this kind of manipulation using macros at “compile time”. Hard-wiring the mechanisms for functional programming into the “run time” and announcing an edict that “programming” must be done this way, though, leads to gotchas2.
Until recently, the idea of “macros” was mostly relegated to the Lisp family of languages. With the advent of PEG parsing technology3, the idea of “macros” can be applied to many other programming languages (like Python, WASM, Haskell, Javascript, etc.).
So-called “functional programming” is just a way of forcing CPUs to act like macro processing engines at “run time”. Functional programming arises from function-based programming. Neither represent the full gamut of possibilities for programming.
References
The Mother Of All Demos: https://en.wikipedia.org/wiki/The_Mother_of_All_Demos#Notes
Sector Lisp: https://justine.lol/sectorlisp2/
Statecharts: https://guitarvydas.github.io/2023/11/27/Statecharts-Papers-We-Love-Video.html
Prolog: Prolog For Programmers
Mars Pathfinder: https://guitarvydas.github.io/2023/10/25/Mars-Pathfinder-Disaster.html
OhmJS: ohmjs.org
See Also
References: https://guitarvydas.github.io/2024/01/06/References.html
Blog: https://guitarvydas.github.io/
Videos: https://www.youtube.com/@programmingsimplicity2980
Discord: https://discord.gg/Jjx62ypR
Leanpub: https://leanpub.com/u/paul-tarvydas
Gumroad: https://tarvydas.gumroad.com
Twitter: @paul_tarvydas
Or, better yet, for extra marks, lay out your manipulation as a series of visible steps (aka “proof”).
E.g. The Mars Pathfinder fiasco, the belief that concurrency is difficult, etc.
My favourite PEG-based language is OhmJS.