On 01.06.2016 15:53, M.-A. Lemburg wrote:
On 01.06.2016 15:19, Sven R. Kunze wrote:
On 01.06.2016 01:46, Ian Foote wrote:
This is the first syntax I've seen in this thread that seems reasonably intuitive and pythonic. I don't mind particularly the keyword used (def or something else), but this structure draws the right parallels in my mind.
Still nobody explained why it needs a special syntax at all.
Normal assignment could do it as well as long as the assignment tells the RHS under what name it will be referred to.
Right. Essentially, we'd only need a way to tell the compiler to invoke e.g. a method on the RHS object which gets called with the name of the variable it binds (and perhaps the line number to allow for e.g. recording the order of definitions).
I think that's the way I would think of it. Although I don't know if I would prefer a two-step solution (that's what you've described), or a one-step solution (like an implicitly set magic variable); cf. my reply to Paul): https://mail.python.org/pipermail/python-ideas/2016-June/040677.html
In terms of usability, I think the magic variable is easier but it might be harder to optimize.
The current byte code for:
x = obj
reads like this:
2 0 LOAD_GLOBAL 0 (obj) 3 STORE_FAST 0 (x)
so if we could get the compiler to generate a method call right after the assignment, e.g. obj.recordbinding('x', 2) (taking as arguments the name of the variable and the line number) we could do lots of interesting stuff.
This could be done via a decorator:
@recordbinding x = obj
to result in the compiler generating the following code:
x = obj obj.recordbinding('x', 2)
Alternativey, you could do all this without any changes to the interpeter by using a trace function which traces the execution of a block:
start_recordbingings() # enable trace function x = obj # trace function detects assignment and calls # obj.recordbinding('x', 2) stop_recordbindings() # disable trace function
However, this is very slow.
A second option would be to place the above into a function definition and have a decorator apply the byte code manipulations to implement the implicit call:
@recordbindings def code(): x = obj
but this would create problems with the local/global namespaces.
I hope that's not the only way to optimize it. :(
I am not that deep into CPython development in order to find a better solution but I think it should be possible for the compiler to find out whether a callee actually USES that information or not without any special decoration or something.