this 2010 essay is a classic description of the chuck moore esthetic: its dry and yagni taken to their logical conclusion. chucks final forth system, which embodies his esthetic more than anything else, is colorforth: https://colorforth.github.io. check it out.
colorforth doesnt need a package manager, because the true craftsman builds their own forth system from scratch, writing the primitives in assembly language and the rest of the system in forth. forth is so simple that this is easy to do. dependencies are bloat, you dont need them.
colorforth doesnt need a build system. the compiler is so fast and there is so little source code that you can recompile the world from scratch almost instantaneously, so there are no binaries, executables, libraries, object files, or a linker. the entire system is stored as source code. this also means you can live edit all of the code in the running system, trivially.
colorforth doesn’t support unicode. unicode is bloated beyond human comprehension. it has 154998 characters, far more than you can ever learn or even be aware of the existence of. most people will never need to type even 1 per cent of these characters in their lifetimes. yagni. just the unicode character tables alone probably require more disk space and memory than an entire colorforth system. even ascii is bloated. uppercase characters are bloat. colorforth has 48 characters, thats all you need. conventional keyboards are bloated as well. colorforth uses a 27 key ergonomic keyboard.
This was hard to type! My first draft had apostrophes, quotes, parentheses, and a percent sign, none of which are in the colorforth character set. But it’s legible, and there are benefits. No apostrophes means no need to remember the difference between “it’s” and “its”. No uppercase makes it easier to break a run-on sentence into two sentences, because you don’t have to change between uppercase and lowercase.
Reminds me of historical writing systems, such as scriptio continua (neither punctuation nor spaces), or the early alphabets that lacked written vowels.
It’s hard to imagine such writing systems being usable for modern day English, or any other language which co-evolved with written vowels and word separators. But I can also imagine the perspective of an ancient Phoenician scribe. You can transcribe text twice as fast if you only write half as many symbols. Words become twice as easy to spell, maybe easier. The fact that run-on sentences even exist as a concept is a sign your writing system is overcomplicated: no sentence separators, no problem.
“You’re telling me you invented extra letters to go between the other letters, so you could capture the exact sound of each word?”
“Well, kind of. The sounds shifted over time. And loanwords have different pronunciation rules, which honestly is most of our words. And the letters don’t capture the exact sound: we repurposed *another* set of *different* symbols for that.”
“Seems like a lot of bloat. You’re recording how distant ancestors and cultures would have pronounced your words? Words you’re not even speaking out loud, and which your readers aren’t reading out loud? What a waste of wax tablet.”
the true craftsman builds their own forth system from scratch
I need a house. Being a ‘true craftsman’, those trees look good…solid, pretty straight. Hmm, I need an axe…so I need to mine some iron. So I need a shovel. And a wheelbarrow. And I need to start a fire hot enough. So I need some coal. And…
I really like Forth conceptually, and it’s pretty awesome when bringing up something bare metal and you’re desperate for it to do anything. OpenBoot was wildly underrated. I’ve written a kinda Forth or two, with one of Brodie’s books in hand, poorly I’m sure by the standards of the faithful. And I’m sure some forth acolyte will nitpick this (any) analogy to the point of absurdity, tell me saws are better than axes and and the language really doesn’t express wheels well so the wheelbarrow is out (which is a good thing…wheels are bloated and and a craftsman can move dirt better by striving for smaller definitions, er, handfuls…yagni, after all) and if I was really a true craftsman I shouldn’t want a house when I can dig a cave with my bare hands and a stick and a few hundred characters (only 48) of inscrutable code.
YAGNI until, you know, you do, and then you’re screwed. YMMV. I’m gonna go to Home Depot.
When you are reading text on a computer screen, lowercase is generally considered to be more readable than uppercase.
In uppercase text, all characters have the same height, baseline and topline. In lowercase text, there is more variability in shape, with ascenders and descenders. This means that lowercase words have a more recognizable shape, making them more readable.
If the characters are tiny enough, or your vision is blurry enough, then the relatively larger letter forms of capitals can make them easier to read. Eye charts for vision testing in an optometrists office are uppercase for this reason. However, this is not the normal or ideal situation for reading text on a screen.
After colorForth, Chuck worked on etherForth for a while, and he discusses other Forths and Forth-likes elsewhere in talks and such. He just doesn’t seem to care about releasing them any longer.
In his chip design tools, Chuck Moore naturally did not use the standard equations:
Chuck showed me the equations he was using for transistor models in OKAD and compared them to the SPICE equations that required solving several differential equations. He also showed how he scaled the values to simplify the calculation. It is pretty obvious that he has sped up the inner loop a hundred times by simplifying the calculation. He adds that his calculation is not only faster but more accurate than the standard SPICE equation. … He said, “I originally chose mV for internal units. But using 6400 mV = 4096 units replaces a divide with a shift and requires only 2 multiplies per transistor. … Even the multiplies are optimized to only step through as many bits of precision as needed.
This is Forth. Seriously. Forth is not the language. Forth the language captures nothing, it’s a moving target. Chuck Moore constantly tweaks the language and largely dismisses the ANS standard as rooted in the past and bloated. Forth is the approach to engineering aiming to produce as small, simple and optimal system as possible, by shaving off as many requirements of every imaginable kind as you can.
I’ve been practicing a similar philosophy with a recent C++ game dev project of mine, and man. Isn’t it fun to limit your requirements, so that you don’t have to write lines of code that accomplish nothing of value.
I think it’s super fun to do engineering in this way, following the philosophy that every line of code that accomplishes nothing of value to the final program should never be written. To face the truth, this is only really doable if you’re soloing a project, but it’s surprising how quickly you can get something working yet clean in a day or so this way. Because you’re not wasting time writing boilerplate or worrying about things that you don’t need yet.
As a simple example, I don’t yet have a hash map in this project. The closest thing I have to one is a flat array of struct Keyboard_Input_Mapping { SDL_Scancode scancode; int player; Input input; }; which maps keys on the keyboard to a player + virtual input button—but there’s like 5 or 6 entries in it, so why would I bother writing a hash-based lookup for it.
And the best part? Lines of code you don’t write don’t have to be compiled, so your compiler rips through them.
Consulting in the past, I loved clients who would trust and let me change the problem/requirements, enabling a more elegant solution. Sometimes, people just really want a chatbot on the website (always without a clear workflow/use for it nor prepared dialogue.) But sometimes you can talk to actual users, watch them visit new sites or use the client’s, understand their workflows, letting you leverage the low hanging fruit for all they’re worth! It’s so empowering, liberating ourselves from this cage of expectation and ceremony we’ve placed ourselves in!
why would I bother writing a hash-based lookup for it
Funnily, Clojure, the most vital such movement I’ve seen, just throws everything in a map and calls it a day!
This seems to convert Moore’s philosophy from mechanical sympathy to primitive set/toolset sympathy. You start with some tools and try to solve your problem/expand your user’s power with minimal extensions to your toolbox. Since software automates, we often distract ourselves by building more tools, trying to automate more (but not surfacing key inflection or decision points). Getting used to the tools we’ve built, we ossify and try to apply them everywhere.
…but matters of perspective. Ossifying with what our language already gives us or instead building ever newer primitive sets are what I rail against, so… This argument/tool also doesn’t simplify!
One reason not to use locals is that Chuck Moore hates them:
This is not entirely accurate as of the mid 2010s as far as I know: Chuck likes at least one local variable so much now that ArrayForth has words for two of them named a and b; the F18A CPU his company designed has registers for them; and his toy post-Forth Forths use registers out the wazoo (he talks about it here). I think the thing with Forth is you have to not try to be Chuck - he is a supergenius and you will never compare so don’t try. You have to write the code you want to run.
Multithreaded Forths constitute a large, concrete use case where it makes sense to use local variables. So I mentioned them after your example of Chuck using them in recent times, to provide another example.
Another reason not to use locals is that it takes time to store and fetch them. If you have two items on a data stack on a hardware stack machine, + will add them in one cycle. If you use a local, then it will take a cycle to store its value with { local_name }, and a cycle to fetch its value every time you mention local_name.
Well, ok, on a machine with no registers.
But on a machine with registers – or even pseudo registers like the 6502’s special 256 byte Zero Page – you should be mapping locals to registers, and they are faster than the stack and give random access to N variables without stack manipulations.
this 2010 essay is a classic description of the chuck moore esthetic: its dry and yagni taken to their logical conclusion. chucks final forth system, which embodies his esthetic more than anything else, is colorforth: https://colorforth.github.io. check it out.
colorforth doesnt need a package manager, because the true craftsman builds their own forth system from scratch, writing the primitives in assembly language and the rest of the system in forth. forth is so simple that this is easy to do. dependencies are bloat, you dont need them.
colorforth doesnt need a build system. the compiler is so fast and there is so little source code that you can recompile the world from scratch almost instantaneously, so there are no binaries, executables, libraries, object files, or a linker. the entire system is stored as source code. this also means you can live edit all of the code in the running system, trivially.
colorforth doesn’t support unicode. unicode is bloated beyond human comprehension. it has 154998 characters, far more than you can ever learn or even be aware of the existence of. most people will never need to type even 1 per cent of these characters in their lifetimes. yagni. just the unicode character tables alone probably require more disk space and memory than an entire colorforth system. even ascii is bloated. uppercase characters are bloat. colorforth has 48 characters, thats all you need. conventional keyboards are bloated as well. colorforth uses a 27 key ergonomic keyboard.
remember, yagni.
This was hard to type! My first draft had apostrophes, quotes, parentheses, and a percent sign, none of which are in the colorforth character set. But it’s legible, and there are benefits. No apostrophes means no need to remember the difference between “it’s” and “its”. No uppercase makes it easier to break a run-on sentence into two sentences, because you don’t have to change between uppercase and lowercase.
Reminds me of historical writing systems, such as scriptio continua (neither punctuation nor spaces), or the early alphabets that lacked written vowels.
It’s hard to imagine such writing systems being usable for modern day English, or any other language which co-evolved with written vowels and word separators. But I can also imagine the perspective of an ancient Phoenician scribe. You can transcribe text twice as fast if you only write half as many symbols. Words become twice as easy to spell, maybe easier. The fact that run-on sentences even exist as a concept is a sign your writing system is overcomplicated: no sentence separators, no problem.
“You’re telling me you invented extra letters to go between the other letters, so you could capture the exact sound of each word?”
“Well, kind of. The sounds shifted over time. And loanwords have different pronunciation rules, which honestly is most of our words. And the letters don’t capture the exact sound: we repurposed *another* set of *different* symbols for that.”
“Seems like a lot of bloat. You’re recording how distant ancestors and cultures would have pronounced your words? Words you’re not even speaking out loud, and which your readers aren’t reading out loud? What a waste of wax tablet.”
I need a house. Being a ‘true craftsman’, those trees look good…solid, pretty straight. Hmm, I need an axe…so I need to mine some iron. So I need a shovel. And a wheelbarrow. And I need to start a fire hot enough. So I need some coal. And…
I really like Forth conceptually, and it’s pretty awesome when bringing up something bare metal and you’re desperate for it to do anything. OpenBoot was wildly underrated. I’ve written a kinda Forth or two, with one of Brodie’s books in hand, poorly I’m sure by the standards of the faithful. And I’m sure some forth acolyte will nitpick this (any) analogy to the point of absurdity, tell me saws are better than axes and and the language really doesn’t express wheels well so the wheelbarrow is out (which is a good thing…wheels are bloated and and a craftsman can move dirt better by striving for smaller definitions, er, handfuls…yagni, after all) and if I was really a true craftsman I shouldn’t want a house when I can dig a cave with my bare hands and a stick and a few hundred characters (only 48) of inscrutable code.
YAGNI until, you know, you do, and then you’re screwed. YMMV. I’m gonna go to Home Depot.
[Comment removed by author]
When you are reading text on a computer screen, lowercase is generally considered to be more readable than uppercase.
In uppercase text, all characters have the same height, baseline and topline. In lowercase text, there is more variability in shape, with ascenders and descenders. This means that lowercase words have a more recognizable shape, making them more readable.
If the characters are tiny enough, or your vision is blurry enough, then the relatively larger letter forms of capitals can make them easier to read. Eye charts for vision testing in an optometrists office are uppercase for this reason. However, this is not the normal or ideal situation for reading text on a screen.
After colorForth, Chuck worked on etherForth for a while, and he discusses other Forths and Forth-likes elsewhere in talks and such. He just doesn’t seem to care about releasing them any longer.
I’ve been practicing a similar philosophy with a recent C++ game dev project of mine, and man. Isn’t it fun to limit your requirements, so that you don’t have to write lines of code that accomplish nothing of value.
I think it’s super fun to do engineering in this way, following the philosophy that every line of code that accomplishes nothing of value to the final program should never be written. To face the truth, this is only really doable if you’re soloing a project, but it’s surprising how quickly you can get something working yet clean in a day or so this way. Because you’re not wasting time writing boilerplate or worrying about things that you don’t need yet.
As a simple example, I don’t yet have a hash map in this project. The closest thing I have to one is a flat array of
struct Keyboard_Input_Mapping { SDL_Scancode scancode; int player; Input input; };which maps keys on the keyboard to a player + virtual input button—but there’s like 5 or 6 entries in it, so why would I bother writing a hash-based lookup for it.And the best part? Lines of code you don’t write don’t have to be compiled, so your compiler rips through them.
What a lovely comment; thank you!
Consulting in the past, I loved clients who would trust and let me change the problem/requirements, enabling a more elegant solution. Sometimes, people just really want a chatbot on the website (always without a clear workflow/use for it nor prepared dialogue.) But sometimes you can talk to actual users, watch them visit new sites or use the client’s, understand their workflows, letting you leverage the low hanging fruit for all they’re worth! It’s so empowering, liberating ourselves from this cage of expectation and ceremony we’ve placed ourselves in!
Perhaps also because: https://rakhim.org/user-is-dead/
Funnily, Clojure, the most vital such movement I’ve seen, just throws everything in a map and calls it a day!
This seems to convert Moore’s philosophy from mechanical sympathy to primitive set/toolset sympathy. You start with some tools and try to solve your problem/expand your user’s power with minimal extensions to your toolbox. Since software automates, we often distract ourselves by building more tools, trying to automate more (but not surfacing key inflection or decision points). Getting used to the tools we’ve built, we ossify and try to apply them everywhere.
…but matters of perspective. Ossifying with what our language already gives us or instead building ever newer primitive sets are what I rail against, so… This argument/tool also doesn’t simplify!
This is not entirely accurate as of the mid 2010s as far as I know: Chuck likes at least one local variable so much now that ArrayForth has words for two of them named
aandb; the F18A CPU his company designed has registers for them; and his toy post-Forth Forths use registers out the wazoo (he talks about it here). I think the thing with Forth is you have to not try to be Chuck - he is a supergenius and you will never compare so don’t try. You have to write the code you want to run.[Comment removed by author]
I don’t think I mentioned a multithreaded Forth.
Multithreaded Forths constitute a large, concrete use case where it makes sense to use local variables. So I mentioned them after your example of Chuck using them in recent times, to provide another example.
Well, ok, on a machine with no registers.
But on a machine with registers – or even pseudo registers like the 6502’s special 256 byte Zero Page – you should be mapping locals to registers, and they are faster than the stack and give random access to N variables without stack manipulations.
Wow, there are a lot of comments linked at the bottom of the page!
I especially liked seeing a Forth programmer’s code for computing mean and standard deviation. It’s a great example of how the original author’s use of many stack manipulation instructions indicates a need to refactor.