My attempts in playing with tail-recursion in python

Thomas Baruchel baruchel at gmx.com
Wed Aug 28 16:16:18 EDT 2013


Le 28-08-2013, Thomas Baruchel <baruchel at gmx.com> a écrit :
> The following functions are fully usable; I hope someone will enjoy using
> them.
>
> If you are not interested by the explanations, just jump to the end of the
> message and take my functions for using them.

Despite the very short size of my function, I made a module of it as a
convenience for my own use. I share here my "recursion.py" file in which
I also added some docstrings.

----------------- module "recursion.py" -------------------------------

"""
The recursion module provides convenient functions for handling
recursion with lambda functions.

The famous Y-combinator is provided as a convenience, but the most
distinctive function of the module is the B function for handling
tail-recursion.

Written by Thomas Baruchel
"""

Y = lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))

def B(func):
    """
    B(lambda) -> lambda

    Return a usable function from a lambda expression written with a
    tail-recursion style. The new function will be evaluated inside
    a loop with no recursive calls, allowing high depths of recursion.

    Since the internal loop evaluates the return of the function as long
    as it is callable, the function does not work with functions returning
    functions (at the end of the recursive calls); there is no restriction
    otherwise.

    E.g.:
      fac = lambda f: lambda a,b: b if a==0 else f(a-1,a*b)
      func = B(fac)
      func(5,1)
        --> 120
    or more shortly:
      B(lambda f: lambda a,b: b if a==0 else f(a-1,a*b))(5,1)
        --> 120
    """
    x = (lambda f: (lambda x: x(x))(lambda y:
          f(lambda *args: lambda: y(y)(*args))))(func)
    def wrapper(*args):
        out = x(*args)
        while callable(out):
            out = out()
        return out
    return wrapper



More information about the Python-list mailing list