def fib(n):
    if n == 0:
        return 0
    if n == 1:
        return 1
    return fib(n-1) + fib(n-2)

def identity(x):
    return x

def cps_fib(n, k = identity):
    if n == 0:
        return k(0)
    if n == 1:
        return k(1)
    def first_fib_done(n_minus_one):
        def first_and_second(n_minus_two):
            return k(n_minus_one + n_minus_two)
        return cps_fib(n-2, first_and_second)
    return cps_fib(n-1, first_fib_done)


def pogo(bouncer):
    while callable(bouncer):
        print "boing!", bouncer
        bouncer = bouncer()
    return bouncer


def bounce(f, *args):
    print args
    return lambda: f(*args)


def bcps_fib(n, k=identity):
    if n == 0:
        return bounce(k, 0)
    if n == 1:
        return bounce(k, 1)
    def first_fib_done(n_minus_one):
        def first_and_second(n_minus_two):
            return bounce(k, n_minus_one + n_minus_two)
        return bounce(bcps_fib, n-2, first_and_second)
    return bounce(bcps_fib, n-1, first_fib_done)
