4 ms·
It's a very good language to play with to get a glimpse of "just the computer". It's still an interpreter environment, but it's one that crashes spectacularly b
by crq-yml 3y ago
It's a very good language to play with to get a glimpse of "just the computer". It's still an interpreter environment, but it's one that crashes spectacularly because you accidentally swapped your arguments and wrote to address 3.
The most fundamental difference in feel when programming Forth for an application vs C is that you don't have a stack frame. A stack frame is what lets you throw 10 arguments and 20 local variables into a function, because the compiler binds them all to names and you fire away and then it's cleaned up automatically when you're done.
In Forth, you do not want to do that because every stack variable you use, you have to manually bring to the front with stack manipulation words(e.g. SWAP to flip the position of the top-most and second, ROT and -ROT to shuffle the top three). It's
a pretty big deal, and if you let that define your application, you're cooked. You can define temporary buffer or register spaces instead and do some load and store from those to the stack to get through the nastier bits of computation.
But in exchange for that, you get some fascinating possibilities to do tacit(point-free) programming instead. That is, because you've removed names from everything except word definitions(which are just sequences of calls to other words), your stack operations now compose together without needing any additional ceremony. And because you can instruct the interpreter to switch modes between "compile" and "execute" at will, you have a Lisp's degree of metaprogramming, so things like strings and formatted numbers are implemented as modes that jump out of the regular interpreter and wait for an end character to show up in the buffer. This extends even to stuff like IF ELSE THEN(control flow is negotiated with the help of a separate stack).
So it's wildly powerful in particular ways, but boring algorithmic code is often just as hard to write as the metaprogramming stuff, because every time, you have to work through your stack positions and try to break it down to a reasonable composition. And by the time you do that, you have a ton of confidence in having written a very exact spec, but also, the thing you did was probably something like "print a fixed point number".
So it's a very good language to use to make you detail-oriented and build up a personalized way of working. It really doesn't lend itself to flinging things around and telling the rest of the team "the code is self-documenting".