by astrobe_ | 2025-08-27 17:53:08+00:00
> Look at that stack wrangling! It's really hard to follow what goes where without the detailed comments showing the stack layout on the right of each instruction (a common practice for Forth programs).

The proposed definition is not particularly difficult to follow. This a readability argument, and we know it is 90% subjective. OP could be a rookie Lisper and I could be a grey beard Lisper: I don't see a problem here, cause I don't see the parens any more.

Second, Forth as 2 stacks, and it shouldn't be overlooked:

: +! dup >R @ + R> ! ;

Of course, this will still be opaque to those here not familiar with Forth, but basically this definition copies the address you need twice to the "other" stack, fetches the memory value, adds, then retrieves the memory address to store the result.

Third, stack comments are as common as training wheels on bicycles. Ok, a bit more common actually. But you get the idea: you need them when you have not yet learned to feel forces and balance your weight accordingly. This is also a key point which is not visible because it is not syntax nor semantics, but design. Forth programmers are very insistent on simplification and factoring for this reason. Take them seriously. If you see 2+ instances of the same sequence of words, don't worry about execution speed, factor it.

Moore explained that definitions are like abbreviations except they can take a parameter or two. Follow that. He also isn't joking when he says than messing with more than two parameters on the stack (like the proposed +!) is already too much. The author even agrees, in a way.

When you do all that, this is when you can make cherries rain on your cake: you can rewrite in machine code the critical definitions, and it is easy to do because they are so short and simple. You can make up for the cost of interpretation and the cost of convenience factoring, if needed.

> How can you know the arity of the functions without adding explicit comments?

Oh, the classic example with foo and bar that give zero clue about what they do. Compare with the "+!" proposed by the author himself - any Forth programmer instantly knows it most likely takes 2 arguments and returns nothing. If it doesn't they will argue that it is as terrible name and you should know better.

This is one of the biggest challenges of Forth: stop FUDing yourself with "what ifs". They won't happen. Ok, sometimes they do happen. But by this time you will have built some confidence, stopped guarding against alien invasions from the next multiverse (which simplifies coding a lot), and you will be able to deal with those unexpected turn of events.

I won't pretend the problem doesn't exist at all, though. But it is far smaller than this type of argument makes it seem to be. It can be a problem when reading someone else's code who has an unfamiliar coding style, granted. But I have written thousands of lines of Forth and I rarely have this problem.

Also, a note on the C equivalent: again, it is focused on the syntax, but we know that semantics are where the fun is: do foo or bar have nasty side effects? Doesn't bar return a signed integer when foo expects an unsigned? I would argue that C's more "natural" syntax creates an illusion of understanding which makes it more friendly than it really is. Maybe you've felt it if you reviewed some code once, and then later had to debug or adapt it.