In lazy programming languages, you can have recursion that doesn't define an end point. The result could be an infinite data structure, but that's OK as long as you don't try to use all of it. For example, a common way to define the entire fibonacci series in Haskell is this:
fibS = 1:1: zipWith (+) fibS (tail fibS)
This translates into the following English: the Fibonacci series is 1, followed by 1, followed by the series which is the element-wise sum of the Fibonacci series and the Fibonacci series without its first element.
This sounds like a recursive definition, rather than recursive function calling, but in Haskell there is no big distinction - the above is just a 'nullary function' (one that takes no arguments).
Normally to use this, you would just use the first N elements of fibS. You can in fact use all of it (e.g. print it all), as long as you are happy with your program running forever :-)
For a more useful example of using 'all' of an infinite recursion, a web server might have a 'main loop' that runs forever defined using a recursive function that does not terminate.
EDIT: These principles can certainly be applied to other languages if some element of 'laziness' is present. Here is the above implementation of fibS ported to Python using generators:
def zipWith(func, iter1, iter2):
while True:
yield func(iter1.next(), iter2.next())
def tail(iter):
iter.next()
for x in iter:
yield x
def fibS():
yield 1
yield 1
for x in zipWith(lambda x,y: x + y, fibS(), tail(fibS())):
yield x
# Test it by printing out the first n elements.
def take(n, iter):
while n > 0:
yield iter.next()
n = n - 1
print list(take(10, fibS()))
Don't expect it to be as efficient as the Haskell version! You could make it more efficient using some hacks and global objects of some kind. But notice the lack of explicit termination conditions.