Comment:
Brad R @ Thursday 24 May 2012 - 12:10:32
I'm maintaining some code that was written by several other Forth programmers of varying expertise. Some of it is quite elegant. Other parts, not so much. You can usually tell an new-to-Forth programmer by several signs:
- excessive use of variables for temporary results
- overly long routines
- failure to factor common subexpressions into new words
- failure to extend the language
Here's an example of the latter: I've found many occurrences of the form
variable @ 1- 0 MAX variable !a seven-word sequence clearly intended to decrement the named variable to, but not beyond, zero.
After working with Forth for a while, most programmers would say, "This is a common operation. Perhaps it should be factored out into a distinct word."
But a more experienced Forth programmer would not think in terms of the
langauge; he would think in terms of the
application. Clearly "decrement-to-zero" is an operation that this application frequently requires. Why not add that operation to the language?
: DECREMENT ( adr -- ) DUP @ DUP IF 1- THEN SWAP ! ;
variable DECREMENTNow, any self-respecting C programmer would be aghast at the idea of defining a new function to decrement a variable. That's a language function! But the point of an extensible language, like Forth, is that you can
extend it to provide the functions you need, not just the functions the language designer gave you.
And that's one way you can tell a Forth programmer from a C programmer writing Forth code.
Notes:
- DECREMENT is an improvement over the unfactored code, in that it allows the variable to have any unsigned value, rather than requiring a positive signed value.
- As shown, there's a superfluous store in DECREMENT if the counter is zero. Alternative definitions are:
: DECREMENT ( adr -- ) DUP @ ?DUP IF 1- SWAP ! ELSE DROP THEN ;
: DECREMENT ( adr -- ) DUP @ ?DUP IF 1- OVER ! THEN DROP ;
- As it happens, DECREMENT was such a useful function that I made it a CODE word and added it to the kernel.