Less is Moore

Simple problem

My experiments with concatenative programming have led me to learn a bit about about the philosophy of Chuck Moore, creator of Forth and all-round programming language badass. What makes him such a powerful and strange force in the programming world is his opposition to generality in software design. While the dizzying heights of the Java 90s taught as all that there can be a thing as too much abstraction, Moore sits at the exact opposite end of the spectrum: not an architecture astronaut, but a software ascetic.

I think the canonical reference for his philosophy is an unpublished book available on his website called Programming a Problem-Oriented Language. In the first chapter he defines and expands on the "Basic Principle": Keep it Simple. Some quotes should reveal what I mean about asceticism:

As the number of capabilities you add to a program increases, the complexity of the program increases exponentially. The problem of maintaining compatibility among these capabililties, to say nothing of some sort of internal consistency in the program, can easily get out of hand. You can avoid this if you apply the Basic Principle.
Do not put code in your program that might be used. Do not leave hooks on which you can hang extensions. The things you might want to do are infinite; that means that each one has 0 probability of realization. If you need an extension later, you can code it later - and probably do a better job than if you did it now.
The conventional approach, enforced to a greater or lesser extent, is that you shall use a standard subroutine. I say that you should write your own subroutines. [...] Although it takes hundreds of instructions to write a general-purpose subroutine, you can do what you need with tens of instructions. In fact, I would advise against writing a subroutine longer that a hundred instructions.

In a more general sense, Moore's philosophy rejects frameworks and other overgeneralisations. Computers are general-purpose so your programs don't have to be. If you're solving problem X and realise "hang on, that's actually a special case of problem Y", it's actually the single most dangerous point in the development of your solution; you're only one step away from the logical conclusion of "I should solve Y instead". Now you're solving the wrong problem. Maybe a more interesting problem, maybe a more generally applicable problem, but not the problem you set out to solve. Simple solution?

I came into contact with a version of this philosophy even earlier, in The Mote in God's Eye by Larry Niven and Jerry Pournelle. In the story, there are aliens called Engineers who only build special-purpose things. To them, there's no such thing as a generic chair. They would instead build a Sam-chair to my exact proportions. If those proportions changed because of a series of brownie-related incidents, they'd rebuild the chair. Every item in their world is custom-made for its particular purpose.

Both Moore and Niven's specialisation philosophies came from resource-constrained environments: the Engineers because of the limited physical resources on their home planet, and Forth from a time when computers were slower and less forgiving. I don't think this is a coincidence. Constrained environments require efficiency and elegance in design. There's no space for extra abstraction flab; each idea has to pay rent for the cost of keeping it.

But is that true of the modern era? Communicating this text on a system probably 10+ layers removed from the bare metal, it's hard to argue that you don't get a lot done by just embracing all of the frameworks and platforms, efficiency be damned. I think this is a significant factor that makes Moore, like Forth, a fairly fringe player in the programming language scene. However, it would be wildly incorrect to conclude that either of them should be ignored. Writing your own block-level storage might be going too far, but I guarantee you feel the consequences of going too far the other way on a regular basis.

When you take on a framework, you're like a consumer buying a product: if it does a hundred things you don't need, or doesn't do things the way you want, well, tough. That's what we've got for sale. But as a programmer you're not a consumer. You're a producer. You aren't forced to accept an abstraction that doesn't work for you, or solves a problem you don't have. The option to build the Engineer-style specialised solution that conforms exactly and only to your needs is always there.

And I think software development would be a better place if we learned from Chuck Moore and took a look at that option a bit more often.