# Self function

Chris Rebert clp2 at rebertia.com
Mon May 4 08:31:46 CEST 2009

```On Sun, May 3, 2009 at 11:29 PM, Arnaud Delobelle
> bearophileHUGS at lycos.com writes:
>
>> Sometimes I rename recursive functions, or I duplicate&modify them,
>> and they stop working because inside them there's one or more copy of
>> their old name.
>> This happens to me more than one time every year.
>> So I have written this:
>>
>> from inspect import getframeinfo, currentframe
>>
>> def SOMEVERYUGLYNAME(n):
>>     if n <= 1:
>>         return 1
>>     else:
>>         self_name = getframeinfo(currentframe()).function
>>         #self_name = getframeinfo(currentframe())[2] # older python
>>
>>         # only if it's a global function
>>         #return n * globals()[self_name](n - 1)
>>         return n * eval(self_name + "(%d)" % (n - 1))
>> assert SOMEVERYUGLYNAME(6) == 2*3*4*5*6
>>
>> Are there nicer ways to do that? I don't know.
>> If there aren't, then a way may be added.
>> An idea-syntax:
>>
>> def fact(n):
>>     return 1 if n <= 1 else n * inspect.self(n - 1)
>>
>> Or even a lambda, because you don't need the name anymore to call the
>> function:
>>
>> fact = lambda n: 1 if n <= 1 else n * self(n - 1)
>>
>> (If you have two or more recursive functions that call each other this
>> idea can't be used, but I think such situations are uncommon enough to
>> not deserve help from the language).
>>
>> Bye,
>> bearophile
>
> Here's an idea:
>
>>>> def bindfunc(f):
> ...     def boundf(*args, **kwargs):
> ...         return f(boundf, *args, **kwargs)
> ...     return boundf
> ...
>>>> @bindfunc
> ... def fac(self, n):
> ...     return 1 if n <= 1 else n * self(n - 1)
> ...
>>>> fac(5)
> 120
>>>> fac = bindfunc(lambda f, n: 1 if n <= 1 else n*f(n - 1))
>>>> fac(5)
> 120

Why am I reminded of the Y-Combinator...?

Cheers,
Chris
--
http://blog.rebertia.com

```