Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clever streams-based python program doesn't run into infinite recursion

I was playing around with clever ways to create a python generator for sequence A003602

This appears to work, but I can't figure out why. It seems to me like it should hit infinite recursion. Is python doing some lazy evaluation somewhere that I don't recognize?

def N():
    i=1
    while True:
        yield i
        i+=1

def interleave(a,b):
    def result():
        x=a()
        y=b()
        while True:
            yield next(x)
            yield next(y)
    return result

def RZ():
    return interleave(N,RZ)()

gen=RZ()

To me it seems like since RZ instantly calls the method returned by interleave which in turn calls b which is RZ (before the first call to yield), this should be infinite recursion. But this actually seems to work. Can anyone explain why?

like image 830
dspyz Avatar asked Jun 17 '12 01:06

dspyz


People also ask

Does infinite recursion make a program run forever?

In most programming environments, a program with an infinite recursion will not really run forever. Eventually, something will break and the program will report an error. Infinite recursion is the first example we have seen of a run-time error (an error that does not appear until you run the program).

How do you fix infinite recursion?

A recursive function is a function that makes a call to itself. To prevent infinite recursion, you need at least one branch (i.e. of an if/else statement) that does not make a recursive call. Branches without recursive calls are called base cases; branches with recursive calls are called recursive cases.

How infinite recursion works in Python?

Every recursive function must have a base condition that stops the recursion or else the function calls itself infinitely. The Python interpreter limits the depths of recursion to help avoid infinite recursions, resulting in stack overflows. By default, the maximum depth of recursion is 1000 .

How do you fix a recursion error in Python?

The “maximum recursion depth exceeded in comparison” error is raised when you try to execute a function that exceeds Python's built in recursion limit. You can fix this error by rewriting your program to use an iterative approach or by increasing the recursion limit in Python.


1 Answers

Generators (any function with a yield statement) are lazy. This means that result() will not start processing until you request the first value from it, which you don't do.

The root cause here is that you ask for a value from x first. This means that the generator never gets to asking it's child generator until at least the second value asked for. Consider the simpler example:

def test():
    yield 1
    a = test()
    while True:
        yield next(a)

a = test()
for i in range(10):
    print(next(a))

This works, just as yours does. It has the potential for infinite recursion, but will only get that far if you ask for that many values. All you have to do is remove the yield 1 to get the expected behaviour. In yours, just switch N and RZ and ask for the next value - you will get the expected recursion.

like image 58
Gareth Latty Avatar answered Sep 30 '22 07:09

Gareth Latty