On Sat, May 2, 2020 at 10:17 AM Terry Reedy <tjreedy(a)udel.edu> wrote:
> On 5/1/2020 7:30 PM, Chris Angelico wrote:
> > @static(called=0)
> > def other_function():
> > me.called += 1
> > ...
> > Obviously the name "me" can't be used, as it'd break a bunch of code,
> > but conceptually this would be incredibly helpful. It'd also be a
> > reliable idiom for recursion optimization - any "me()" is guaranteed
> > to be recursion and may potentially give info to an optimizer.
> > Perhaps, if Python had a way to identify the current function, it
> > would feel less odd to attach attributes to it.
> As one might imagine, something so 'obvious' has been proposed multiple
> times. Reasons for repeated rejection.
> 1. Function bodies are compiled to code objects. There is no function
> to 'bind' to and there might never be. (compile(code_body, ...)).
True, but that's a bit of an edge case. I'm sure there are other edge
cases too - what happens with a 'nonlocal' if it's in a code object
outside of a function? (Or in the CPython implementation, what happens
with the corresponding cell lookup?) If <me> causes a RuntimeError if
used in such a context, or if the compilation of <me> creates some
sort of reference that simply doesn't work outside of a function, it'd
> 2. Python does name resolution on function bodies when called. If early
> binding of <me> were possible, it would be an exception.
It would have to be a keyword of a sort. Not necessarily an actual
keyword, although that would definitely work.
> 3. Recursion without names is really hard; hence the special
> head-spinning combinator to do that.
And that's a good reason to have compiler support for it. It would
make true recursion simple. (Obviously mutual recursion would still
> 4. The post-compile function object address would only be useful for
> CPYthon, not for implementations that move objects around.
Why? It's an object. It should be possible to reference it.
> 5. The automatic conversion of recursion to a while loop only works for
> linear tail recursion. In Python, such cases are usually better written
> directly as a for-loop.
True, and that would probably only be a small advantage anyway. But
it's also a clarity thing, and it means you don't have to name your
function inside the function and then remember to rename it.
There is another objection though:
6. Decorated functions would behave differently based on whether you
call by name or call by <me>.
I don't have an answer to that, other than that giving programmers the
option isn't a bad thing. People would just have to be aware of the
distinction and know which one they want.