# a = b = 1 just syntactic sugar?

Steven Taschuk staschuk at telusplanet.net
Sun Jun 8 08:27:29 CEST 2003

```Quoth junk:
[...]
> If you care, I wrote a little function that will return the current
> function within a block.  This means, you can have anonymous recursive
> functions like this:
>
> import selfref
> factorial = lambda x: ((x==0)*1) or (x * selfref.myself(x-1))

This is certainly clever, but imho good style demands writing even
so simple and familiar a function more directly.  Besides the
simple loss of clarity, I don't see how (without helper functions
defined more sensibly) you'd add a check to the above that x >= 0
(raising a ValueError if it isn't).  Or a docstring, for that
matter.

I can't think offhand of a useful recursive function simple enough
to be clear when written this way; in other words, I can't think
of a case where I'd actually use this.

> Here is the code:
>
> def myself(*args):
>     prevFrame = sys._getframe(1)
>     myOwnCode = prevFrame.f_code
>     myOwnFuncObj = new.function(myOwnCode, globals())
>     return myOwnFuncObj(*args)
>
> The only thing this doesn't do is to capture default arguments!!!
[...]

I don't see the problem with default arguments:

>>> f = lambda a, b=5: (b<1 and 1 or a*selfref.myself(a, b-1))
>>> f(3)
243

Am I missing something?

Keyword arguments are definitely missing, of course, but that lack
is easily remedied:

def myself(*args, **kwargs):
prevFrame = sys._getframe(1)
myOwnCode = prevFrame.f_code
myOwnFuncObj = new.function(myOwnCode, globals())
return myOwnFuncObj(*args, **kwargs)

I'm fairly sure you don't want to use globals() here, though.
Here's why:

>>> import selfref
>>> x = 3
>>> f = lambda n: n < 1 and 1 or x + selfref.myself(n-1)
>>> f(2)
Traceback (most recent call last):
[...]
NameError: global name 'x' is not defined

What you want is, I expect, prevFrame.f_globals.

--
Steven Taschuk                             staschuk at telusplanet.net
"I may be wrong but I'm positive."  -- _Friday_, Robert A. Heinlein

```