Here’s a version of FizzBuzz unlikely to be requested at a job interview. Forth is a stack-based language (like PostScript), which means you’ll be right at home if you’ve ever used a RPN-based HP calculator.
: fizzbuzz 101 1 ( note off-by-one top limit ) u+do i dup 3 mod if else s" Fizz" type 0 then i 5 mod if else s" Buzz" type dup if 0 then then dup if . else s" " type drop drop then loop ;
This one requires a bit of explaining, at least I think it does, since I had to read through it a few times myself to be able to explain every detail.
The loop construct is nothing special; u+do takes two numbers a and b off the stack (in reverse order; remember, it’s a stack) and repeats (b – a – 1) times (hence the off-by-one comment).
i is a special variable set to the current loop index. The loop execution starts by putting it on the stack – twice. (We’ll get to why shortly.)
Topmost copy of i gets immediately consumed by mod. If the result was something other than 0, the if does nothing. Otherwise (mod returned 0, i was divisible by 3) , the else clause pushes “Fizz” on the stack, prints (types) it, and pushes 0 on the stack. This is needed to keep track of whether we’ve printed something. Note that then marks the end of the if statement, which makes sense in a stack-based language but can be a bit confusing.
Another mod checks division by 5 in the same manner. The only difference is that 0 gets pushed on the stack only if the top object isn’t already a 0. (We only want to have a single flag to keep track of whether something has been printed.)
As we get to the the last line, the topmost object gets duplicated, since one copy is consumed by the final if check.
If it was something other than 0, nothing was printed on this iteration and we’ll have to print the object, which will be the i pushed on the stack in the very beginning of this iteration.
If it was 0, we’ll just print a space for legibility and – here’s the bit I had to read through a few times – we’ll drop the two topmost items from the stack. What are they? The topmost one is the 0 (the flag) we just copied. The one beneath it is the original i, which we no longer need.
The code would work without the two drop commands, but it would leave garbage on the stack, which might cause problems later – we might run out of stack space, which is never a good look.
Here’s the familiar output.
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz 91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz ok