Hacker News new | ask | show | jobs
by dewster 2362 days ago
If you actually look at the way Forth works you'll see that every stack manipulation wastes code space and real-time. Since there is only one data stack there are a lot of stack manipulations going on. Forth programmers are aware of this and do their best to minimize them, which tends to make their incredibly cryptic code even more cryptic.

If the definition of a low level language is one that bedevils the programmer with minutiae, the Forth is the lowest of the low. I don't understand the fascination others have for it, and don't understand how anyone can like it after actually programming with it. It's horrible.

5 comments

It teaches you to set things up so that the code doesn't have to do stack manipulations and other minutiae in the typical case. Most other languages seem to encourage modules with general APIs and hard boundaries so that the caller has to unpack/repack/rearrange the data as it enters and leaves. Forth very deliberately encourages developing a holistic system, and it discourages wholesale code reuse from other projects and systems, which gives you the power and flexibility to refactor relentlessly, until only the essence of the computational solution remains.

Forth is definitely a difficult language to work with, particularly in a professional environment where managing turnover is massively important. When I dive in to some Forth code that I've written, to make even the smallest of changes, my brain has to be fully engaged, and that's a non-starter in most environments (Chuck probably thinks this is a good thing; why are we making changes to code we don't understand?). But I am still an avid proponent of learning and applying the principles of Forth, because of the results that it makes possible. It is quite eye-opening to see directly how a system can become 10x as powerful, with 1/10th of the code, if you are willing to do the work and embrace the "minimalist" (I would call it "essentialist") mindset.

One of Elbrus supercomputers was a stack machine that translated stack operations into out-of-order register operations, quite successfully. There was also a variant of Ada called El-76.

(see more about Pentkovsky for more interesting stories)

This means that you do not need to sacrifice speed for compactness.

Also, zero-operand ISA (stack machines are zero-operands) have what can be called normalizing property: if you have stack layout for inputs and outputs you have only one optimal way to achieve it. E.g., "( b a -- x) swap -" sequence won't be different in any place where you have to compute b-a (in the register's three operand typical RISC case there are 32^3 combinations). This means that if you can use something like [1] Sequitur algorithm to make code more compact than six bit per opcode.

[1] https://en.wikipedia.org/wiki/Sequitur_algorithm

This is, actually, what Forth programmers often do manually. And in untyped language, which will not complain about stack layout violations after refactoring.

But this does not mean that you cannot use, say, dependent types for Forth programs for better programming safety. And this does not mean that you can't benefit from single (or double) stacks or their alternatives. For example, Applicative class from Haskell's Prelude is good in expressing concatenative programs, just like ones in Forth, I think.

I have a hard time resisting the temptation of ROT >R myself at times, and it's true that I never pass arguments to the wrong function in C, while in Forth I do. Even assembly is less bug-prone in my experience. But I think there's probably a there there that I don't fully understand, and I want to.

Sometimes I wonder if Forth would be better off with no stack manipulation words. If you really need to swap, after all, you can X ! Y ! X @ Y @. Chuck left SWAP out of the x18 in the end.

I hear that repeated often.

What about 'Freude am Fahrvergnügen!' in a light sports car, vs. some wobbly limo or SUV?

Furthermore: [1] http://home.pipeline.com/~hbaker1/ForthStack.html

[2] https://news.ycombinator.com/item?id=12237539 [3] https://news.ycombinator.com/item?id=13154111

In a stack oriented language the stack manipulations are the logic. You could make a more complicated compiler to optimize them or use local variables but most people/projects don't bother.

>Forth programmers are aware of this and do their best to minimize them, ...

This has never been true in my experience. The effort goes into insuring that the stack manipulations are correct.