You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Bug in compiling lambda default argument values #36
Transcrypt has a bug in the way it compiles code for default values of arguments to lambda functions. The bug is serious, because the ability to close on several different values in callback functions for ajax calls is crucial for ajax programming.
Python closures capture variables, not their values. The hack in Python to create a closure that captures the value of a variable rather than the variable itself is like this:
When the above javascript code is run it will call deselect() on the last value assigned to row as many times as there were loop iterations, which isn't what it should be doing.
Thank you for taking such quick action on this, and thanks also for Transcrypt. It's very nice to be able to write client-side code in Python instead of ES5.
Well, to be honest, currently I am quite immersed in the source maps, so I'm afraid it will still be some time before the next version rolls out. I will try to do all the bug fixes in one go. Don't know if that succeeds.
Unfortunately I currently don't know a good and compact mechanism to make this work properly.
A workaround is to create a separate inner scope for your lambda:
results = []
for i in range (10):
# results.append (lambda: i) # Will never work
# results.append (lambda j = i: j) # Works in Python
results.append ((lambda j: lambda: j) (i)) # Works in Transcrypt and Python
print (results [3] ())
I'll add this to the docs. For now consider the necessity of this workaround a limitation of Transcrypt. I've added the workaround as a testcase to the autotest including the comments, to document it for future moments of brightness...
Activity
elgow commentedon Apr 15, 2016
To make matters worse, Transcrypt moves evaluation of arguments into the function, which is wrong.
becomes when compiled:
proper behavior is shown by this code
which will print
JdeH commentedon Apr 15, 2016
Thanks for the thorough testing and analysis!
I'll try to fix this in the next version.
elgow commentedon Apr 15, 2016
Thank you for taking such quick action on this, and thanks also for Transcrypt. It's very nice to be able to write client-side code in Python instead of ES5.
JdeH commentedon Apr 15, 2016
Well, to be honest, currently I am quite immersed in the source maps, so I'm afraid it will still be some time before the next version rolls out. I will try to do all the bug fixes in one go. Don't know if that succeeds.
JdeH commentedon Apr 21, 2016
As a first step I've tried to construct a minimal example to experiment with this:
which generates:
JdeH commentedon Apr 21, 2016
Unfortunately I currently don't know a good and compact mechanism to make this work properly.
A workaround is to create a separate inner scope for your lambda:
I'll add this to the docs. For now consider the necessity of this workaround a limitation of Transcrypt. I've added the workaround as a testcase to the autotest including the comments, to document it for future moments of brightness...