Moving Past Functions To Cats
Cats address a number of computing problems by moving beyond 1960s era "functions" to Minecraft-style "crafting"
Preface
The intended audience is probably a senior industry veteran or crypto fan that is open to radical new ideas about building software. If that’s you, you are in the precious minority. Congrats, you are about to read the Greatest Sh*tpost In The History Of Computing™
Towards Real Disruption
The ability to create great software is ultimately constrained by the human imagination - but also the friction involved in moving ideas to running code. If you have unlimited budget, you can just throw more people at it. But for everyone else, we desperately need a major simplification in how we currently ‘assemble’ and ‘integrate’ software. The advent of the internet helped us dramatically increase scale, but the core task of moving algebraic symbols around on a screen remains largely unchanged since the 1960s. The original terminal dimensions were about 80x25. Fifty years later, a Visual Studio editor window in front of me is about 160x50. This is not the sort of progress that will support the next Space Age.
So when something shiny and new comes along, it creates a buzz. A few years ago, I started to question the latest programming fad - almost a cargo cult - of Functional Programming (FP). Functional Programming tends to attract some very intelligent people who suspect something really big is lurking in the general vicinity of FP, even if they can’t put a finger on it. FP kinda opened Pandora’s Box because it questioned some long-held notions about how we should assemble code. However, I felt that FP was largely doomed to suffer the same fate as Object-Oriented (OO) because FP - like OO - had buried itself behind pedantic jargon while ignoring the elephant in the room: Category Theory.
Despite lurking in the shadows for decades, Category Theory is poorly understood by the industry, and Silicon Valley has developed a curious blind spot in this regard. At the same time, there is rising pushback against continued industry dominance by an increasingly oppressive US west coast - which only highlights the need for new thought leadership.
Putting it another way, if you wanted to disrupt Big Tech, you would probably want to start here and look for areas of vulnerability because it could dislodge the very foundation their entire trillion dollar tech stack rests upon.
Introduction
First of all, let’s motivate why you would even want to consider categories (“cats”) as part of your toolbox.
Everyone these days seems to agree that something is kinda janky with how we write software:
Hard to see what is going on
Hard to refactor and reuse code
Hard to deploy
Hard to integrate with other systems
The term “monolith” is often used to describe some impenetrable body of tightly coupled code, but how and why did it get that way? Sure, microservices goes a long way in breaking things into more manageable chunks, but they introduce their own baggage.
Worse, none of this stuff seems to have a pathway to AI automation. Isn’t it funny how every other industry is terrified of robots stealing their jobs but programmers are totally complacent, even as they watch Microsoft trying reverse-engineer some AI out of Github, because they know coding is such a mess. Fine, let Satya Nadella have his fun. We all probably need to be building something new anyway.
The root of the problem goes almost to the bedrock of computing, almost to the underlying math. Has computer science failed us? Yes I believe it has. But therein lies the opportunity.
TL;DR
My bold brash claim is that the obsession with “functions” in computing is doomed to suffer the same fate as OO. They will still be around of course - but maybe no longer having the central role in programming they once enjoyed.
What if we could reduce or avoid the use of functions entirely?
Hah hah hah! Write code without functions?? WTF does that even mean? u eastern europeans r sooo dumb. At this point you may want to stop, shut out the noise of the world and whatever Nancy Pelosi is insider trading this week and read that last statement again.
What if we could reduce or avoid the use of functions entirely?
Clearly, this is not going to be your usual Hacker News pablum article. We’ve already lost most of the west coast audience by now so we can grab a coffee and continue in peace.
Note that you already can write a shell script or SQL script without writing a single function, yet somehow get work done. AI certainly does not need functions. So clearly, computing can survive without functions.
Yes, computing can live without “functions”.
But computing cannot live without “cats”.
Cats? First of all, functions - as you know them - are just one flavor of “cat” or “category” and a somewhat inferior one at that. Some in Estonia - obviously crazy people - think that cats and categorical crafting - based on the insights of a Russian mathematician named Vladimir Voevodsky - are really the future of computing.
A trend toward Minecraft™-style crafting (at the code level) is a vision of what a post Silicon Valley world might look like.
Crafting? What a stupid idea, right?
Hence this crazy plan might just work.
Cat Theory
Cat are an emerging and almost opposing view of traditional computer science. Cats come from Category Theory (CT), which - at least for computing - studies the transformation of code into a runtime. You can think of CT as Compiler Theory on steroids / drugs.
But while classic compiler theory just focuses on compiling your code, CT considers the larger “holistic” problem of building software: from programming language algebras to Developer Experience (DX) to the notorious “monads” crunching your code to the difficult task of deploying all that crap to hardware in the cloud. CT also considers the data side too, which often gets ignored. The blockchain - a strange mix of code and data - is very much a cat. In that sense, CT is a “convergence” technology.
Convergence seeks to identify common overlap and resolve redundancies … which means if you solve one problem you might be able to solve a whole bunch of others at the same time ... including the problem of how to dislodge Big Tech.
Cats address a number of thorny edge cases where traditional computing falls short:
Greater code reuse
Greater ability to reason about what code is doing
Better system integration
Greater interactivity with external systems such as robotics, databases, crypto, APIs etc.
Leverage “convergence” hardware such as NVRAM
AI automation
One heck of an ambitious list. I should mention that convergence has a stormy past in the industry because our brains like to compartmentalize, not converge - which is like thinking in the opposite direction. Unless you are on some good drugs, the brain usually cannot hop between compartments fast enough to see how things might be connected, much like the parable of the Blind Men and the Elephant. Worse, we are all so deep in our day-to-day tech weeds we no longer see the forest for the trees. So if you are already getting a headache, please bear with me!
Cats vs Functions
First of all, let’s define a cat as a runnable chunk of statements or instructions. Common examples of cats are things like scripts or code snippets. They might live within the context of a larger system or separately but they are generally smaller than entire “programs”. For readability purposes in this paper, I will interchange “instructions” and “cats”.
Unfortunately, having lots of individual instructions or scripts lying about creates a management nightmare.
Hence, most of your programming career has probably been focused around things called functions. In the early days of computing, managing ever increasing piles of computer instructions and punchcards became overwhelming for humans. In the 1950s, functions were introduced by FORTRAN and became wildly popular as the de facto way to organize instructions almost regardless of programming language.
The Functional Programming (FP) community has elevated the venerable “function” to almost religious status - but that just might be the final blowoff top, much like the fate of OO before it. I’m not going to waste too much time on FP terminology since the hardcore FP zealots will just strawman all day instead of directly answering the tough questions. Most developers don’t care about FP anyway.
Cats just view functions as glorified instruction containers. Yes, functions can still play an important role but not quite as central as you think. Thanks to automation, we can now consider alternate ways to manage piles of instructions without always having to resort to functions.
The Problems With Functions
Functions have obviously served the computing industry well for 70 years, so clearly they work in most situations. However, they are starting to show their age.
Code Reuse
To glue two functions together, you generally need to rely on a third “wrapper” function that shuffles output from one function to the other. This approach is generally put under the heading of lambda calculus and famously credited for allowing programmers to reuse mountains of code.
However, it still has a number of drawbacks that become apparent over time:
Functions do not scale across hardware or programming languages because they are hard-wired - and so you eventually end up with the notorious “monolith” until you break things up into services. But now your programmers are having to deal with things you normally pay an operating system to handle
Functions place the burden on the caller to manage the parameters needed to call the function. So while you achieve better code reuse, the benefit is largely offset by having to explicitly manage all the parameters between functions. This wiring tends to be pretty dumb too - you can’t even query it like an RDBMS - so you have to treat it much like a 1960s era network database with glorified pointers everywhere. Imagine a rat’s nest of cables. Great if you are a C programmer but not so much fun for everyone else since you’ve moved a lot of problems outside the function where it’s harder to diagnose
Functions have a structural reuse limitation: a single entry/exit - you either take all of the instructions or nothing, there is no middle ground. In many situations that’s fine but what if it’s a big function and you just need a few lines … not the entire thing … ? You must manually break up the function via “refactoring”
To its credit, FP tries to avoid the use of explicit wrappers by letting you chain instructions directly (almost like mini-scripts) but since these chains are also hardwired, it’s hard to see much advantage.
Reasoning About Code
Monoliths are infamous for being mysterious black boxes because functions by themselves give almost no visibility into what’s going on unless you break things up or write print statements to a log.
Because functions have math-y roots from FORTRAN, it is tempting to treat code almost like math proofs e.g. prove that code is doing what you think it is doing. In practice, this has mixed success. Certainly compilers, type checkers and program verification tools do this sort of stuff anyway but the average developer does not have a math degree and risks not getting the math right. So in many cases, introducing math either increases overall complexity or just moves the problem. Debugging strange errors in your type system can be really difficult.
Here’s the issue: the math folks have been warning programmers for years that computer functions are not really the same as math functions. Yeah they look the same but trying to overly conflate the two eventually leads to trouble. It might be more intellectually honest if we at least called them ‘procedures’ instead.
Sure, advanced type theory is trying to study this problem but if you go far enough down this rabbit hole, you will eventually get to academic stuff like dependent types and Idris and eventually something that looks suspiciously more like crafting, not functions.
System Integration
Despite the benefit of code reuse, functions don’t “integrate” well at all. After all, you can’t integrate two functions by simply throwing another function at it - you are just moving the problem.
Everything about functions starts to break down when doing integration:
The order to run things may depend on the situation
The caller is often unclear
Integration is a different beast entirely. From a CT perspective, it is mathematically different. You need an entirely different approach.
Categories - The Aha Moment
Instead of always trying to “break code” down into more manageable chunks, maybe we should take a more bottom-up approach. That is, what if we could assemble chunks of instructions instead? This is a decidedly categorial viewpoint because I’m not even considering functions anymore.
And what if we could assembly these instructions on the fly ?
Greater Code Reuse
Essentially cats toss aside traditional functions and just consider the underlying instructions as a big phat dependency graph. Now you can reuse code at a much more granular level. Sure you might still have functions, but mostly as a nexus for things other than managing instructions.
For starters, an inventory / crafting approach no longer forces you to start at the beginning of a function. If you already have some items, you can skip steps. Thanks to the notion of “inventory”, caching becomes automatic.
Now close your eyes and imagine your codebase like a database - some imaginary glowing network floating in cyberspace - and then imagine your ‘program’ as a ‘query’ of sorts that zaps around this mesh. I realize this is a bit radical because code is usually glued together in such a way that there is really only mainline “path” in the runtime and any “branching” is also glued in advance. But think of all other potential code paths out there waiting to be unlocked.
Your code starts to act more like a brain.
Greater Interactivity = Ability to Reason
By assembling and running statement on the fly, you get the sort of “adhoc” interactivity associated with databases or REPLs, without losing the richness of traditional programming.
Greater interactivity as you build software dramatically lowers cognitive load because you can literally see what’s going on - you don’t need math proofs or a good imagination. Why use Postman to test an API when you can just write a snippet of code directly and see what it returns? You basically have a debugger that is constantly doing hot module reloading every time you change a line of code … across the entire stack.
Suddenly, working with stateful systems like robotics or databases becomes fun and intuitive again because you can just write mini commands and see what happens, without all the overhead of traditional programming.
The Silicon Valley stack is hopelessly outdated in this regard. Obviously we are talking our book here but if we plan to colonize space someday, then programmers should not be burdened with Docker or Kubernetes every time they need to change a line of code
Better System Integration
Cats - almost by definition - are particularly good as “joining” things because they must be able to assemble code on the fly. To pull this magic off, we need to start thinking of code more like data than text. At the math level, CT shares a lot in common with Relational Theory from the database world, except we can apply a lot of these concepts to code instead of data. No more need for Zapier-esque vendor tools.
Because crafting is more declarative than imperative, you can even issue crafting requests over a network. Why not just type or speak a command and let the computer decide if a distributed operation is needed? Now we have something that starts to look like real cyberpunk.
Convergence Hardware
Next-generation convergence hardware such as persistent memory and NVRAM makes almost no sense to programmers stuck in the outdated world of transient memory, but suddenly makes a world of sense when you starting working with cats.
System integration? Putting things in persistent memory is a natural common ground as you try to tie things across various enterprise systems.
Hotloading? Persistent memory becomes almost necessary when you need to cache things between hotloads.
AI automation
Crafting and inductive reasoning and basic AI go almost hand in hand. Instead of programming, you submit a crafting request and let the machine figure out all the details. If your “inventory” falls short, the computer will let you know what skeletons you need to slay next.
As far back as 1972 we knew that you could run a straight line from a dependency graph to relations to Armstrong’s axioms to Prolog inference rules to basic artificial intelligence. Any modern incremental type checker must mentally “run” your code to verify you didn’t do something illegal. Well, if the type checker can do all that why not have it just take over program execution entirely? Now you have real leverage.
The Categorical Machine
As you might have guessed, all these magical cats need to live somewhere. Managing a bunch of instructions without getting into the same trouble as the 1950s requires a futuristic virtual machine that is more “category-smart”. Depending on who you ask, we would call this a categorical abstract machine (CAM) or simply a cat machine. And if you are hotloading into the cloud, a cat machine displaces the common industry notion of operating system.
Replacing operating systems now? Where is this all going?
The Smartphone Story
This is where convergence really starts to disrupt things. The “smartphone” is famous for replacing a bunch of legacy physical devices - and it bankrupted many of the companies and industries that made those devices. But convergence is not easy. Before there was Apple, there was a company called General Magic that laid most of the tech groundwork but ran into typical Silicon Valley politics.
My thesis is that a categorical machine is the “smartphone” for computing. But if you think the smartphone was amazing for replacing a bunch of legacy devices, you better sit down. Hundreds if not thousands of existing cloud software packages can be essentially rendered obsolete by a good cat machine - not to mentioned cloud platforms like AWS and Azure - and more than a few programmers shown the door by AI automation. This is how Big Tech gets taken out.
Multics and Multix
Naturally, I’m talking my book here, namely “Multix” which is a distributed cat machine (a reference implementation, if you will), named after an earlier fateful and highly controversial convergence computing project - 1960s MIT Multics.
Even today, Multics remains a mysterious, almost taboo subject in computer science. Why is that? Again, if you want to go after Big Tech, this is the sort of thing where you want to start looking.
The Pitch
Rather than listen to a bunch of Twitter and Reddit armchair“experts” trash talk categories, why not just judge for yourself? Yes things are still half-baked and the training videos are still forthcoming but I hope you see the vision. I’m just looking for a few brave cat lovers.
The “catbox” demo is just a way to get your paws wet to motivate you enough to download the VS Code extension and start getting familiar w the ergonomics. The demo doesn’t seem all that impressive, but then again Google is just a single HTML input field. I will reveal things as we go. Ideally, we would want to run some hackathons in Eastern Europe, far away from the Microsoft Amazon mafia cartel and west coast groupthink (I spent a lot of my career on the west coast and it was a wonderful place at the time but it has changed).
For the math purists, I think that Minecraft-style “crafting” is a reasonable middle ground so that mainstream developers don’t have to learn advanced algebraic geometry, dependent type theory, cubical type theory, algebraic topology etc. and all the other arcane math presented at Lambda Conference, Strange Loop etc.
You can find more info on Multix at the very retro-esque portal here: https://portal.multix.catatonic.ai/
Okay if I get more budget I will make the site better but I am generally sticking with a retro theme to troll Silicon Valley.
On Twitter at @multix_labs
Some tutorial videos are here but crafting has not yet been revealed
Multix is just one highly Estonian take on cats meow meow. I strongly recommend every computer science department start building their own categorial machines!! Yes Big Tech is probably reading this article but so are the Chinese and the Russians
Algorithms and systems that match data with relevant ontologies, which then categorize data into...
So I agree, the "which then categorize data" part of the statement above is what you're after. The part before about those algorithms, systems, ontologies - still a great deal of work to be done, and not a lot of people even aware of the problem set and domain itself. Not even those of us up here in the senior full-stack ether.
Interesting stuff, it appeals to me as someone who learned programming in an interactive environment (Winamp AVS visuals had persistent memory), used Lisp a lot and now works on enterprisey data integration projects