0

Is it possible to do some anonymous recursion in Python ?

I mean, making a recursive lambda function, that does not call its name (so, it must work even if you don't assign the lambda).

Also, I know about the Y combinator (or other fixed-point combinators). I am aware that it is possible using different combinators. This is not what I am asking for.

I have read the wikipedia article https://en.wikipedia.org/wiki/Anonymous_recursion, that talks about how to do it with combinators, but I am searching for something more like the in APL, arguments.callee in JS or Recall in R (see the article).

Something like this :

fact = lambda n: 1 if n == 0 else n * ano_rec(n - 1)

would be perferct.

But, it could also be with a wrapper :

fact = ano_rec_wrapper(lambda n: 1 if n == 0 else n * ano_rec(n - 1))
  • 1
    There's nothing like from `∇` APL or `arguments.callee` from JavaScript. The [inspect](https://docs.python.org/3/library/inspect.html) module is probably your only hope. [Python Stack Frames and Tail-Call Optimization](https://towardsdatascience.com/python-stack-frames-and-tail-call-optimization-4d0ea55b0542). Otherwise you will likely need to write your own evaluation context like `loop..recur`, demonstrated in [this Q&A](https://stackoverflow.com/a/46268042/633183), or `loop..call` as seen in [this Q&A](https://stackoverflow.com/a/66379893/633183). – Mulan Mar 25 '23 at 17:35
  • the loop-recur construct is cool and it is the answer in this case, I would say. – Gwang-Jin Kim Apr 22 '23 at 15:58

1 Answers1

-1

Why don't you just define:

fact = lambda n: 1 if n == 0 else n * fact(n-1)

?

you can't use ano_rec or let's call it recur, without having defined it.

You could probably do:

recur = lambda n: 1 if n == 0 else n * recur(n-1)

Or, you could do:

def make_recursive(func):
    def wrapped(*args, **kwargs):
        return func(wrapped, *args, **kwargs)
    return wrapped

fact = make_recursive(lambda ano_rec, n: 1 if n == 0 else n * ano_rec(n - 1))

print(fact(5)) ## 120

It comes close - but it has just the not so nice mistake that you have to pass ano_rec or self as first argument to your lambda always.

Gwang-Jin Kim
  • 9,303
  • 17
  • 30
  • The main usage of anonymous recursion is because, as the pyflakes say, you should'n assign a lambda to a name : lambdas are made mostly to create function that are immediately used. That is why they are anonymous fonctions, and why anonymous recursion would be usefull. – Oskar 79 115 99 97 114 80 108 Apr 30 '23 at 17:51
  • In this case, `make_recursive` is really a combinator, so it doesn't enter in the scope of the question. – Oskar 79 115 99 97 114 80 108 Apr 30 '23 at 17:51
  • not giving a name is for a recursive function bullshit. You have weird imagination how lambdas should be used. Or how recursive functions should be used. Plus, Python's lambda is a very crippled form of a lambda - just one expression allowed. So the normal way in Python is to generate a normal named function and to refer to it using a name. I don't care what one author of some Python package says or says not. - Usually you don't creat on-the-fly a recursive lambda. Never seen that. Coming from a functional language. – Gwang-Jin Kim May 01 '23 at 22:30
  • The only case of a recursive lambda I encountered was the Y combinator. – Gwang-Jin Kim May 01 '23 at 22:37
  • 1
    I get your point, and I'm nobody to say what is a good practice or not, and what is or isn't used. But what I can say is that E731 from the flake8 rules tells that you shouldn't assign a lambda to a variable, and use a def instead : https://www.flake8rules.com/rules/E731.html . Plus, lambdas are "anonymous functions", because they have no name. If your intent is to assign them to a variable, then it is weird and quite pointless to use an anonymous function, and then give it a name. Lambdas are made to be defined "on-the-fly" as you say. – Oskar 79 115 99 97 114 80 108 May 04 '23 at 22:29
  • You are right. the very definition of an anonymous function is to have no name :D. Totally agree. - another point would be however, that usually anonymous functions are not recursive - in functional languages you don't see recursive anonymous functions. - Usually recursive functions have a name by which they call themselves. So this is a draw situations of our two standpoints :D . – Gwang-Jin Kim May 05 '23 at 16:59