6 ms·
I feel a rant coming on... This is a _fantastic_ article which should be read by anyone interested in stack languages. Though it wasn't my first programming l
by pauldirac137 16y ago
I feel a rant coming on...
This is a _fantastic_ article which should be read by anyone interested in stack languages.
Though it wasn't my first programming language, Forth was certainly the first programming language I loved. I read Starting Forth and was blown away by the elegance of the language and by how easily you could get the language to modify itself. It also started a fascination with stack languages that persists to this day.
However, when I tried to actually do anything useful with Forth, I kept banging my head against a wall. The typical problem is that stack juggling is just too hard for most problems, and even when it isn't, it's more work than just writing down an algebraic expression would be. Stacks work well for some problems, but evaluating arbitrary algebraic expressions isn't one. Why would I want to do that? asks the Forth zealot. Because I do! Because I don't want to have to worry that I won't be able to do that easily in the future when I do need to. So even though I've designed my own Forths and other stack languages since then, rule #1 is always: support local variables. Even if I don't need them, I want them. If you don't believe me, translate this problem into Forth or some other stack language in a clear, intuitive way without using local variables:
# python code to compute solutions of a**2*x + b*x + c == 0:
def solve_quadratic_equation(a, b, c):
# assume a >=0, no complex roots
d = math.sqrt(b * b - 4.0 * a * c)
return ((-b - d) / (2.0 * a), (-b + d) / (2.0 * a))
Three lines of code, completely transparent. Now see this thread: http://osdir.com/ml/lang.concatenative/2005-01/msg00023.html http://osdir.com/ml/lang.concatenative/2005-01/msg00023.html. You'll
see how difficult this is to do without local variables in a stack language. The reason is easy to spot: you are using values in a pretty random-access way, not in a streamed way. This is common in algebraic equations. And it's not stack-friendly.
Another thing I hate about pure Forth is that floating-point values, if they exist at all (they often don't) are put on a different stack, which means you have to duplicate all the operators with different names (I call this "operator underloading") and this can lead to hilariously obscure bugs because the two stacks are independent.
Basically, the attitude that the hard-core Forthers have reminds me of analogous statements that have been made about communism, or moonieism or whatever extreme -ism is promoted as the cure to all problems: if you are having problems, it's because you haven't gone far enough down the road yet. Only by committing 1000% to the approach will you ever get anything done. This is pure cult behavior.
And yet: Forth does have a valid and useful niche, in embedded systems, and it is a fascinating language, one well worth studying. But I don't think it's a coincidence that none of the software that people use everyday (other than very low-level stuff like e.g. the boot proms) on their computers is written in Forth.
Here's a challenge: I would really love to see someone write a full-featured web browser (at the level of a Firefox, Chrome or Safari) in Forth. You can do that in C, C++, Java, Python, and probably in dozens of other languages I could name. The beauty of this problem is that you can't go and bitch that you shouldn't have to support something like (say) CSS or embedded video because you think it's unnecessary; it's part of the problem domain and you don't get to complain about it. I think that any web browser that anyone attempted to write in Forth (without local variables, naturally!) would never get finished. But maybe I'm wrong, and I just haven't reached Forthlightenment yet. If so, prove me wrong.
- pauldirac137 16y agoI've re-read the article, and now I think it's even more fantastic than I did at first. There are just so many deep insights in it, I'm in awe. Kudos to the author. I especially like this statement: "Because you need superhuman abilities to work without layers." The extreme Forth approach described in the article is all about doing away with all abstraction layers and optimizing everything at all layers simultaneously as much as possible, much like (brilliant analogy from the article) bacteria optimize every base pair in their DNA. But humans _don't_ optimize every base pair in their DNA. The author didn't pursue this, so I will, because it's important: humans don't do this because you couldn't evolve a system anywhere near as complex as a human _without_ having abstraction layers and the (unfortunate) lack of optimality that this entails. The layers mean that the subsystems can evolve in a reasonably independent fashion (like software engineers not needing to change the hardware), but you sacrifice ultimate optimality for that. It's a worthwhile trade-off: you get scalability. With extreme-Forth you don't, which is why Forth programs solve small-scale problems, and Forth programmers simply avoid large-scale problems (or on a bad day, whine about how those large-scale problems shouldn't exist, yadda yadda). Again, I point to my web browser problem; you may think that CSS is completely unnecessary, but it's a layer that makes life easier for people who do not have the time or expertise to optimize software or hardware, so it's part of the problem domain, deal with it! Gimme my abstraction layers! Seriously, I've seen Chuck Moore quoted as saying that we shouldn't name constants but use raw (magic) numbers instead, because by naming them we throw away valuable information that could be used for optimization. That is serious layer-hatred going on there. I personally am interested in stack languages for a completely different reason: stacks allow you to compose functions in a way that is much more cumbersome without a stack, and I think that's neat. Not world-shaking, but neat. I like to have the option to use local variables if that's the natural way to decompose the problem (an expression graph, as the article describes) and use the stack if _that's_ the natural way to decompose the problem (expression trees). Why have only one tool in your toolbox when you can have two?
- jacquesm 16y agoHey Paul, thank you for those two super comments. I have some experience with stack languages as well, wrote my own little forth a long time ago and just posted a comment which (while much shorter than yours) tries to defend forths 'raison d'etre' as being limited to embedded systems, bootstrapping new hardware and pretty much nothing else. The forth zealots are running out of steam very quickly when the programs and data structures get more complex, I've yet to see a program in forth longer than a few hundred lines (though I'm sure they exist). If anybody ever wrote a bookkeeping system in Forth then I'm not aware of it. (and if they did it probably deals with whole dollar values only and is limited to a certain turnover). Once long ago I worked on a project that contained the 'NOVIX', then brand spanking new and top of the line, a high level language directly executed on a chip. The project started off really well, it contained a PC component and an embedded component, the other programmer was to write some image processing software for the NOVIX chip and it would output a high level representation of the image sensor data through the bus to the 386 which would do the presentation. In the end I wrote the image processing code as well simply because the problem was too hard to solve in forth in a reasonable time, so we would simply pump raw image data across the bus (fortunately we had enough bandwidth for that). The time to write the image processing component in C was exactly a single day. Forth is at the other end of expressiveness compared to most languages, if the language matches your problem well it's amazingly compact and short, but if there is an impedance mismatch between the language and the problem at hand then you may very well end up in trouble you can not get out of. There are only so many DUPs and ROT3s you can see before your eyes glaze over, and even if local variables help they are not going to solve the underlying problem that Forth tends to force the programmer and the problem to adapt to Forth rather than the other way around. Edit: Another thing I really like about Forth besides it being such a tiny core is the fact that any program in Forth is essentially a DSL. If someone could remove the roadblocks that stop Forth/Factor projects from going above a certain size then that might ignite a more mainstream interest in to stack based languages.