Are you using two or three spaces of indentation? Yes.
Are you using two and three spaces of indentation? Yes.
Are you using two xor three spaces of indentation? No.
I don't know the coding conventions of Forth, but I'd personally prefer to see using four spaces (one tab) of indentation. Most importantly however, be consistent. </nitpicks> As far as I understand the Forth style conventions, three spaces should be used as indentation always.
I 3 MOD 0= I 5 MOD 0= 2DUP AND IF
This line is excessively long and contains a lot of different instructions, in my opinion this is unnecessarily confusing. By splitting it up I consider it easier to read and understand.
It can easily be split up to the following:
I 3 MOD 0=
I 5 MOD 0=
2DUP AND
IF
: FIZZBUZZ ( -- )
CR 100 1 DO
I'm not quite sure why you print a new line (CR) at the beginning of your function (sorry, your "word"). IMO it's better to print a new line after each iteration.
It would be easy to extract the 100 to be a parameter to your word instead of hardcoding it into it. That would give some flexibility at least, even though most Fizzbuzz challenges only goes to 100. This can easily be accomplished by removing the 100
at the beginning of your word.
Speaking of 100. Your current implementation actually excludes the number 100. This is easily fixed by adding 1 +
to the beginning of your word.
Your nested if-else-if-else-if-else-then-then-then is hard to follow when you're not used to how Forth works (yes, I am speaking from experience here). By only changing the indentation of it, it gets easier to follow along with it.
Although it still may look a bit strange that the THEN
is at the end, but that's not anything you can do something about :)
With the suggestions above, the code would look like this:
: FIZZBUZZ ( u -- )
1 + 1 DO
I 3 MOD 0=
I 5 MOD 0=
2DUP AND IF
." fizzbuzz" DROP DROP
ELSE
IF
." buzz" DROP
ELSE
IF
." fizz"
ELSE
I .
THEN
THEN
THEN
CR
LOOP
;
As for alternatives to using mod, even though it is possible to use two separate counters and decrease them and reset them once they hit zero, I don't think that would improve the code much.
Considering that I managed to understand your code and learn a bit of Forth, I'd say that's a compliment to your code. I believe that with some of the changes I've suggested here, it would be much easier for new Forth programmers to understand it.