This is always possible, because you can emulate the call stack yourself. However, it's not always easy to do.
The easy cases are tail recursion: these don't even require a stack. For example, this guy is trivially converted into a for
loop:
def countdown(n):
if n >= 0:
print n
countdown(n-1)
Even if the function is not strictly tail-recursive, you can sometimes still get away without a stack. For example, the classical factorial function:
def factorial(n):
if n <= 1:
return 1
else:
return n * factorial(n-1)
It gets harder when there are multiple recursive calls. Consider, for example, quicksort:
def quicksort(array):
if len(array) <= 1:
return array
else:
pivot = array[0]
left = quicksort([x for x in array[1:] if x < pivot])
right = quicksort([x for x in array[1:] if x >= pivot])
return left + [pivot] + right
Although it's definitely possible to do this without recursion, you'll have to build a stack yourself, and construct a while
loop that iterates until the stack is empty.