Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

recursive lambda-expressions possible?

I'm trying to write a lambda-expression that calls itself, but i can't seem to find any syntax for that, or even if it's possible.

Essentially what I wanted to transfer the following function into the following lambda expression: (I realize it's a silly application, it just adds, but I'm exploring what I can do with lambda-expressions in python)

def add(a, b):
   if a <= 0:
      return b
   else:
      return 1 + add(a - 1, b)

add = lambda a, b: [1 + add(a-1, b), b][a <= 0]

but calling the lambda form of add results in a runtime error because the maximum recursion depth is reached. Is it even possible to do this in python? Or am I just making some stupid mistake? Oh, I'm using python3.0, but I don't think that should matter?

like image 353
Eric Lifka Avatar asked Jul 29 '09 21:07

Eric Lifka


People also ask

Is it possible to write a recursive lambda expression?

But a lambda cannot be recursive, it has no way to invoke itself. A lambda has no name and using this within the body of a lambda refers to a captured this (assuming the lambda is created in the body of a member function, otherwise it is an error).

Can lambda calculus do recursion?

Used in this way, the Y combinator implements simple recursion. In the lambda calculus it is not possible to refer to the definition of a function in a function body. Recursion may only be achieved by obtaining the function passed in as a parameter. The Y combinator demonstrates this style of programming.

Can lambdas call themselves?

Bookmark this question. Show activity on this post. A regular function can contain a call to itself in its definition, no problem.

Can lambdas be templated?

From the various lambda improvements, template parameters for lambdas are my favorite ones. Lambdas support with C++20 template parameters, can be default-constructed and support copy-assignment, when they have no state, and can be used in unevaluated contexts.


2 Answers

Maybe you need a Y combinator?

Edit - make that a Z combinator (I hadn't realized that Y combinators are more for call-by-name)

Using the definition of the Z combinator from Wikipedia

>>> Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))

Using this, you can then define add as a completely anonymous function (ie. no reference to its name in its definition)

>>> add = Z(lambda f: lambda a, b: b if a <= 0 else 1 + f(a - 1, b))
>>> add(1, 1)
2
>>> add(1, 5)
6
like image 107
Ben Lings Avatar answered Sep 30 '22 18:09

Ben Lings


Perhaps you should try the Z combinator, where this example is from:

>>> Z = lambda f: (lambda x: f(lambda *args: x(x)(*args)))(lambda x: f(lambda *args: x(x)(*args)))
>>> fact = lambda f: lambda x: 1 if x == 0 else x * f(x-1)
>>> Z(fact)(5)
120
like image 24
Barry Kelly Avatar answered Sep 30 '22 18:09

Barry Kelly