5 ms·
The difference is that in one case it's an implementation detail covered by an abstraction to make that fact irrelevant to the programmer, and in the other the
by boomlinde 6y ago
The difference is that in one case it's an implementation detail covered by an abstraction to make that fact irrelevant to the programmer, and in the other the language is fundamentally designed around the idea that the stack itself is exposed as a data structure to the programmer.
If you don't understand how the difference is significant, I suggest trying a language like Joy, Factor or Forth.
- throwaway_pdp09 6y agoI fully understand the difference but having read up on forth but never used it, I don't know if it's helpful in that sense. Exposing the stack fully is a weakness not a strength to me. I also understand that this is a formalisation that supports concatenative programming but from a user point of view, does it fit human comprehension as well as, or better than, a more conventional language. Honest question, thanks.
- vincnetas 6y agoclass Fun implements Function<Stack, Stack> { public Stack apply(Stack s) { return s; } } So this is Joy in Java. But as my neighbor comment asks. How does this benefits a language as tool for humans to get job done (c). From my perspective it only brings you down the abstractions ladder.
- vanderZwan 6y ago> it only brings you down the abstractions ladder. Ironically I'd say you're both right and wrong at the same time because of the somewhat paradoxical nature of concatenative languages: you're closer to the metal (especially with Forth) but at the same time working with Forth is an exercise in abstracting everything away. The strength/weakness is that it has only one hammer to do so: defining Forth words to manipulate the stack ("words" == Forth lingo for functions, more or less). It has a Lisp-like minimalism (you can almost think of it as postfix-Lisp in some sense). The Fun class you describe misses the point entirely of the minimalism of Forth or Joy - the complete lack of syntax is a feature that makes concatenative language inherently composable in ways that other languages can only dream of. In a language like Python, you could compose three function calls like so: y = foo(x) z = bar(y) w = baz(z) In a language like Joy (or Forth, or Factor) you would write: x foo bar baz .. where the x is only included if we assume it is a stored value that has to be put on the stack first. Ok, sure. But here is the thing: imagine that I wish to refactor calls to foo and bar into their own function (this particular example is childishly simple of course, but I think it gets the conceptual point across). Compare the Python and the Joy ways of doing that: def bla(x): return bar(foo(x)) DEFINE bla == foo bar The difference is small but significant. Because the concatenative languages have no function application, refactoring is often a simple cut/paste operation, followed by one big find/replace. You can literally split (almost) any piece of code into parts at any point, define those parts as new words, and the result would be valid code. Precisely because of the brutal minimalism at play here. The trade-off is an upfront cost of having to structure the entire program around stack operations, and thinking in a postfix way of doing operations. I'm not saying that makes them better - I like my type checking very much, and in the right amounts a bit of boilerplate makes code a lot more self-documenting. But I also think that learning how to solve problems the "Forth" way is a good programming exercise.
- aabbcc1241 6y agowould it be better if we have 'static-typed stack-based language'? But it seems stack based language only support numbers... Event string is treated as chars, which are the same as ints, which is hard to 'type check' statically?
- vanderZwan 6y agoForth is so minimal that you can implement an interpreter in hardware, which means it has no types. There are a few typed stack languages. Cat was the first, and Kitten is another one.
- astrobe_ 6y agoClimbing the abstraction ladder does not lead to Heaven. Rather to Noah's ark, according to the law of leaky abstractions. Java has this reputation of being a lot of boilerplate code, and indeed when you compare it to Forth code this is striking. For instance this is the code to square the top of stack: : square dup * ; I don't know much about Java, but I guess it something like: Stack apply(Stack s) { int tos=s.pop(); s.push(tos*tos); return s; } Of course this is not fair at all because Forth has no type checking, no OO and gets its terseness from the point-free style that stack-orientation allows. But this example is symbolic of one thing: Java needs a lot of baggage to be viable. A state-of-the-art GC. A state-of-the-art JIT. A complex lexer/parser. A mildly efficient Forth interpreter/compiler can be written by one teenager. If your job is to get some sort of interpreter running on a brand new hardware, then Forth is probably the fastest way to get that job done. Chuck Moore, the creator of Forth, has funded a company on this - company that is now more than forty years old. This extends to more common use cases. As most processors come on the market with a C compiler, if you have a Forth interpreter written in C, you can have it running right away. Even before you have an OS for it. But you can benefit from the OS and the large number of C libraries too. Writing library bindings for a Forth system is often trivial; the hardest part is to decide how the API should look like on the Forth side (often library APIs are too rich and you want to only expose the useful subset for you). So "stack-oriented programming" leads to simple interpreters and compilers, which in turns gives a lot of flexibility, which is very valuable to get things done.
- cdcarter 6y agoThank you for this! You concisely answered the question I kept having throughout the wikipedia page and these threads. Obviously there's a world in which stack programming lets you be productive, its flourished, but what is that environment? Bootstrapping, new hardware, working at pre-OS levels, these are all places I don't have to think very much about, so I appreciate the reminder and context for why Forth is powerful there.
- vincnetas 6y agoIf your job is to get some sort of interpreter running on a brand new hardware, then Forth is probably the fastest way to get that job done. Chuck Moore, the creator of Forth, has funded a company on this - company that is now more than forty years old. This one is really nice example of "getting things done"™. Thank you for your answer
- boomlinde 6y ago> So this is Joy in Java. No, it isn't. I assume that you are trying to make a point, but I'm not seeing it so please elaborate. > But as my neighbor comment asks. How does this benefits a language as tool for humans to get job done (c). That of course depends on the job. It might not benefit you at all. Some will probably argue that this simple model only benefits the implementer in getting their job done. Personally, I think the ability to quickly refactor code that a point-free sequence of stack operations affords can be useful. > From my perspective it only brings you down the abstractions ladder. Have you ever found it useful to take a step down the abstraction ladder?