Just to add, this is a kinda complicated way of doing things. It’s easier to just build up a list clearly rather than doing the little dance you do with push
in this function. And in languages where you use recursion a lot, and you’re building lists, you normally reverse the result once you’ve unwound the stack (or use a reverse append function that reverses the list as you iterate), because generally lists are linked lists and it is much faster to append to the start of a list than it is to calculate length and add to the end every iteration. eg in JS (although not necessary, just as an example):
function count (n, current = 1, output = []) {
if (current > n) {
return output.reverse();
} else {
return count(n, current + 1, [current, ...output]);
}
}
But as arrays in JS are not linked lists, there isn’t a performance penalty to appending to the end so can just do like:
function count (n, current = 1, output = []) {
if (current > n) {
return output;
} else {
return count(n, current + 1, output.concat(current));
}
}
For comparison, Elixir:
defmodule Counter do
@moduledoc """
Produce a range of numbers from 1 to a given positive integer inclusive.
iex> Counter.count(10)
[1,2,3,4,5,6,7,8,9,10]
iex> Counter.count(0)
[]
"""
# Function head definition to, include default
# params to allow the function to be called
# with only `n`
def count(n, current \\ 1, output \\ [])
# Terminal case, counter value has passed the input number, return reversed output
def count(n, current, output) when n > current, do: Enum.reverse(output)
# Recursive case, push the current counter value into
# the output array and increment the counter
def count(n, current, output), do: count(n, current + 1, [current|output])
end
ReasonML:
let count = (n) => {
let rec loop = (current, output) =>
(current > n)
? List.rev(output)
: loop(current + 1, [current, ...output])
loop(1, [])
}