
On Sat, Aug 6, 2011 at 11:36 PM, Steven D'Aprano <steve@pearwood.info> wrote:
Eric Snow wrote:
Of the three code blocks, functions are the only ones for whom the
[grammar police] "Whom" is for people. You want "which". [/grammar police]
(I don't normally correct people's grammar, but to me, this error broke the flow of the sentence like being hit in the face with a sock with half a brick in it.)
I aim to please! <wink>
resulting object and the execution of the code block are separate. So a code object could be executing for the original function or a different one that is sharing the code object.
Fairly unusual, but I grant it could happen. I've done it myself :)
Why not bind the called function-object to the frame locals, rather than the one for which the code object was created, perhaps as "__function__"?
I'm afraid I can't interpret this (which may be my ignorance rather than your fault).
No, the fault is likely mine. But it seems so clear to me. :)
The only guess I can make is based on what you say later:
"One new implicit name in locals().
so I presume you mean that the function should see a local variable (perhaps called "me", or "this"?) that is bound to itself.
One called __function__ (or the like). A "dunder" name is used to indicate its special nature and limit conflict with existing code. The function that was called would be bound to that name at function execution time. Keep in mind that I am talking about the frame locals, not anything stored on the code object nor on the function object. Not to overdramatize it, but it would happen at the beginning of every call of every function. I don't know what that overhead would be.
Presumably if a function wants to use that same name as a local, nothing bad will happen, since the local assignment will just override the implicit assignment. But what about code that expects to see a nonlocal or global with the same name?
What happens when two functions, sharing the same code object, get called from two threads at the same time? Are their locals independent?
I'm afraid I don't know. I expect that each would get executed in separate execution frames, and so have separate frame locals.
For most uses, standard recursion via the name is good enough, it's only a few corner cases where self-reflection (as I call it) is needed. And I say that as somebody who does want a way for functions to know themselves. I don't think that use-case is so important that it should be implicitly added to every function, on the off-chance it is needed, rather than explicitly on demand.
For me the use case involves determining what function called my function. Currently you can tell in which execution frame a function was called, and thereby which code object, but reliably matching that to a function is not so simple. I recognize that my case is likely not a general one.
To finish things off, bind to every new code object the function for which it was created, perhaps as "co_func". That way you will always know what function object was called and which one the code object came from originally.
What benefit will this give? Have you ever looked at a code object and said, "I need a way of knowing which function this is from?" If so, I'd love to know what problem you were trying to solve at the time!
You caught me! :) I don't already have a use case for this part. I had only considered that without this you could not determine where a code object came from, or if a function had borrowed another's code object. This is certainly only useful in the case that one function is using the code object of another, which we have all agreed is not that common. However, with a co_func I felt that all the bases would be covered.
Code objects don't always get created as part of a function. They can be returned by compile. What should co_func be set to then?
None, since there was no function object created along with the code object. Same with generator expressions.
Finally, if the function has a reference to the code object, and the code object has a reference to the function, you have a reference cycle. That's not the end of the world now as it used to be, in early Python before the garbage collector was added, but still, there better be a really good use-case to justify it.
(Perhaps a weak reference might be more appropriate?)
Good point. Mostly I am trying to look for an angle that works without a lot of trouble. Can't fault me for trying in my own incoherent way. :) -eric
-- Steven
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas