First, `isLt100`, `isDivBy3` and your other functions are vaguely named. Better name them fully and meaningfully. There's no harm done with the extra keystrokes in the name. Looking at your `fizzbuzz`, it appears that `loop` is impure as it is mutating something from the outside of the function. You're doing a `push` inside `loop` to `result` which is outside the `loop`. Also, you're mutating `i` as well. Also, you would want to make your range flexible. Now, as far as I know, functional programming fans prefer a "range" function to iterate through. This makes it easy for iteration functions like `reduce`, `map`, `filter` etc. to go through. Since there's no such thing in JS, [this SO answer provides us one][1]. It's essentially just creating an array of `n` length. Next is your fizzbuzz. Since we have an array of numbers thanks to `range`, all we need to do now is just map these values with numbers, fizz, buzz or fizz buzz. We can use the native `map` array method to do that. We just need to provide the number to `fizzBuzzTest` and return it's result to `map` to create our new array of numbers, fizz, buzz or fizz buzz. *Warning: I'm using ES6 syntax. [Run snippet in browser that supports at least arrow functions.][2]* <!-- begin snippet: js hide: false --> <!-- language: lang-js --> function range(n){ return Array.apply(null, Array(n)).map((_, i) => i); } function fizzBuzzTest(n){ var by3 = n % 3 === 0; var by5 = n % 5 === 0; return by3 && by5 ? 'fizz buzz' : by3 ? 'fizz' : by5 ? 'buzz' : n; } function fizzBuzz(n){ return range(n).map(x => fizzBuzzTest(x + 1)).join(', '); // A non-OOP approach would have the same, except function calls are nested rather // than chained (Python) // return ','.join(map(lambda x: fizzBuzz(x + 1), range(100))); } // SE really needs something elegant to print stuff with on snippets document.write(fizzBuzz(100)); <!-- end snippet --> [1]: http://stackoverflow.com/a/10050831/575527 [2]: http://caniuse.com/#feat=arrow-functions