2009
03.03

My second (and much nicer) version of a tail call optimization trampoline in python

class recur(object):
    def __init__(self, *args):
        self.args = args

    def __call__(self, func):
        return Inner(func)

class Inner(object):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args):
        result = recur(*args)
        call   = self.func

        while True:
            result = call(*result.args)

            if isinstance(result, recur):
                if result.args and isinstance(result.args[0], Inner):
                    call = result.args[0].func
                    result.args = result.args[1:]
            else:
                return result

        return result

if __name__ == "__main__":

    # recursively sums a list of integers
    # calling itself for each item

    @recur()
    def req_sum(lst, n=0):
        return n if not lst else recur(lst[1:], n+lst[0])

    print req_sum([1,2,3,4])

    # You can also recurse
    # with another function
    # here you have ping and pong
    # calling eachother forever

    pings = 0
    pongs = 0

    @recur()
    def ping(n=0):
        global pings
        print "pong ponged %d times, now I'll ping" % n
        pings += 1
        return recur(pong, pings)

    @recur()
    def pong(n):
        global pongs
        print "ping pinged %d times, now I'll pong" % n
        pongs += 1
        return recur(ping, pongs)

    # if you uncomment this next statement and
    # run the code it will loop forever  

    #ping()

Again, self explanatory.

1 comment so far

Add Your Comment

  1. MedicamentSpot.com. Canadian Health&Care.Best quality drugs.Special Internet Prices.No prescription online pharmacy. High quality drugs. Buy drugs online

    Buy:Lasix.Female Cialis.Buspar.Wellbutrin SR.Lipitor.Advair.Nymphomax.Ventolin.Zocor.Female Pink Viagra.Benicar.Lipothin.Amoxicillin.Prozac.Seroquel.SleepWell.Cozaar.Aricept.Acomplia.Zetia….