Why Concatenative Programming Matters
The problem with stack languages for me has always been in typing. I find it difficult to track the exact stack effects of each word (function), particularly if these functions are pushing, popping and applying functions that themselves modify the stack. Even when dealing with something as simple as optimized x87 code, I would annotate all the FXCH etc. to keep track of the bits of the arithmetic expression on the stack, as I tried to keep multiple operations in flight.<p>Yes, I know Christopher Diggins' Cat is statically typed. The problem isn't in compiler diagnostics, it's in readability.<p>In a stack language, an expression as simple as 'a b c d' is cryptic. If c consumes two arguments, in applicative terms it would be d(c(b, a)); if b consumes one argument and c only one, then it would be d(c(b(a))); if d consumes two arguments, b one, and c none, then it would be d(c, b(a)). And this ambiguity makes it very hard for me to read the code unless I'm intimate with all the individual words. You have to understand everything to understand anything.<p>Unfortunately, I suspect that concatenative languages tend to derive their power from this ambiguity, because the lack of specificity leaves considerable flexibility for what the words can do with the stack.<p>So my considered opinion for now - and this article doesn't really change that, it is mostly a tutorial - is that stack languages are best as a compiler target rather than a human source form.