Adventures in Forth, part 2
2007-10-19 / 17:42 / dave
Via email
I first played with retroforth (and forth the language) about two days ago. I think the problem you had with MAX in retroforth is because retroforth is not an ANS compatible forth by default. It seems like there is an ANS compatibility layer though ( http://quartus.net/retro/rfans.zip, also linked to on the retroforth web page). If you use that, this is what you get:
D:\sw\retroforth>rf-windows.exe -f rfans\retro-ans.fs
: FLOOR5 ( n — n’ ) DUP 6 < IF DROP 5 ELSE 1 - THEN ;
ok
3 FLOOR5 .
5 ok
5 FLOOR5 .
5 ok
9 FLOOR5 .
8 ok
: FLOOR5 ( n -- n' ) 1- 5 MAX ;
ok
3 FLOOR5 .
5 ok
5 FLOOR5 .
5 ok
9 FLOOR5 .
8 okHope that helps,
Jeff
Thanks Jeff! That helps a bunch.
So now I know that “1-” (and “1+” which appears later in the Wikipedia article) are valid. But how does that jive with this quote (also from Wikipedia):
Forth parsing is simple, as it has no explicit grammar. The interpreter reads a line of input from the user input device, which is then parsed for a word using spaces as a delimiter; some systems recognise additional whitespace characters. When the interpreter finds a word, it tries to look the word up in the dictionary. If the word is found, the interpreter executes the code associated with the word, and then returns to parse the rest of the input stream. If the word isn’t found, the word is assumed to be a number, and an attempt is made to convert it into a number and push it on the stack…
(emphasis mine)
There seem to be two obvious answers:
- There’s special parsing for numbers
- 1+ and 1- are increment decrement words
10 1+ . 11 ok 10 1- . 9 ok 10 2+ . Error: 2+ is undefined
#2 it is.
Optimization?
So now the “why is this valid” question is replaced with “why did they make a word that saves a single space?” 1+ saves a single space over 1 + at the cost of introducing confusion: i.e. if 1+ works, why does 2+ give an error? In contrast, i++ is noticeably easier than i = i + 1 and not as misleading, unless you’re prone to try i+++.
I’m guessing it’s a performance optimization. Platforms with a fast increment instruction can save time over general addition; it seems kind of silly but I suppose it could add up, especially inside large loops.
Further poking reveals a few others:
10 2* . 20 ok 10 3* . Error: 3* is undefined 10 10* . Error: 10* is undefined 10 2/ . 5 ok 10 3/ . Error: 3/ is undefined
So multiplication and division by 2–which can be substituted by left and right shifts–are also provided.
In the context of Richard Jones‘ statement that “FORTH is in some ways the ultimate in low level programming” this makes perfect sense. And it’s not a dangerous syntax: 1 + is correct, just not optimized and 2+ produces a clear error message. So this is probably an obvious choice for those who grok Forth even though it confused my Python brain.
But I guess that’s why it’s important to learn new languages, right?
