6 ms·
I have tried Forth and failed many times. The biggest problem for me was the amount of effort needed to keep track of "local" variables. Was I missing somethi
by dottedmag 4y ago
I have tried Forth and failed many times.
The biggest problem for me was the amount of effort needed to keep track of "local" variables.
Was I missing something? Is there a way to let Forth keep track of where on the stack "foo" lives if it is needed several times in a subroutine instead of always shuffling the stack or counting the elements on it?
- JadeNB 4y ago> Was I missing something? Is there a way to let Forth keep track of where on the stack "foo" lives if it is needed several times in a subroutine instead of always shuffling the stack or counting the elements on it? I'm not a Forth novice, much less an expert, but my impression is that the answer is that if you spend much time thinking about the location of variables, then you're "doing it wrong"—to steal the phrase, trying to write C in Forth, rather than to write Forth. My understanding is that the emphasis is on building highly domain-specific languages out of many small words, each of which is re-factored so much that it never needs to keep much track of any, or much, shuffling of variables on the stack.
- dottedmag 4y agoSo basically "use it as a language for combinators", right? But combinator languages are pretty hard to read no matter what one does, don't they?
- kragen 4y agono forth is ruthlessly imperative c: x = a[n-1]; n += y * x; plot(x, y, n); forth: : foo n @ 1- a @ x ! ; \ ‡ : bar y @ x @ * n +! ; : baz x @ y @ n @ plot ; : quux foo bar baz ; naming each line of code allows you to do things like bar n ? to see what n is after you bar in exchange for the somewhat rebarbative syntax and lack of typing you get turing-complete macros (with full compiler access, without the pitfalls of string-replacement macros) and an interactive repl that fits into almost the smallest microcontrollers because you have total freedom to redefine the syntax you can construct whatever dsl you prefer it is nothing like combinatory logic except that you can occasionally write a point-free function ______ ‡ this assumes a is defined as something like this : array create cells allot does> swap cells + ; 20 array a so that 3 a computes an &a[3] suitable for @ and !, etc.
- kragen 4y agoWas I missing something? yes use variable or value for variables, not the stack the stack is for expression evaluation roughly everyone has this problem at first if you'd put it in a local variable in c or js, 85% of the time you should put it in a variable in forth. start with 100% or 110% and scale back from there yes this means your words aren't reentrant by default this is ok, most subroutines aren't recursive never shuffle the stack or count the elements in it. if you find yourself doing that, put the elements you wanted to access in a variable or value then you can access them by name. this is much easier the possibility of shuffling the stack is an attractive nuisance, like a tar pit. an occasional dup or swap or r@ is okay, but start by not using them literally write square as variable x : square x ! x @ x @ * ; or value x : square to x x x * ; if that's what it takes to stop tying your code in knots it is ok to name a variable x, its scope only extends to the next definition of an x. it's not like in c where every x needs to either be local to a subroutine or a single global unique x used by the entire program (or at least source file) later you can graduate to sometimes replacing one local variable with the return stack and another one or occasionally two with the operand stack, but it is better for your code to be kind of boring and verbose than an incomprehensible soup of 2dup -rot tuck forth is maybe not better than c but there is no reason to make it worse
- dottedmag 4y agoThis is roughly equivalent to C using "static globals" instead of named local variables, right?
- kragen 4y agothere are some important differences i just edited in a note about one of them, the scoping for large programs forth has namespaces (vocabularies or wordlists) similar to static file scope in c an important similarity between standard forth variables and c static variables is that they don't support recursion. in the occasional case where you do need recursion you can use the operand stack to save and restore your variables manually x @ y @ ... recurse ... y ! x ! which would not be possible in c with universal use of static global variables also though typically when you are stepping through forth you are doing it by typing names of words, while in c you use the debugger, which can see and change local variables
- bowsamic 4y agoI tried to write a simple program in Forth that needed to keep track of a list of pairs of numbers and after coming up against many issues I asked online in a Forth group and was told that Forth simply isn't suited for such programs (programs that need to work with dynamically sized amounts of arbitrary data). Maybe this is also true for your case
- kragen 4y agothat is maybe an exaggeration but forth is certainly more designed for reactive systems than transformational ones video games and motor controllers rather than computer algebra systems the difficulties are the same as in c: you have to do your reallocation and deallocation and probably hashing manually a surprising number of such problems turn out to work well enough if 'dynamically sized' becomes '1 billion or less' which simplifies the memory management dramatically and you can write theorem provers and optimizing compilers and stuff in forth; it just isn't its strong point