On Sat, May 2, 2020 at 10:17 AM Terry Reedy <tjreedy@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 be fine.
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 require names.)
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. ChrisA
participants (1)
-
Chris Angelico