[Python-Dev] RE: code blocks using 'for' loops and generators
jimjjewett at gmail.com
Wed Mar 16 02:41:41 CET 2005
It may be time to PEP (or re-PEP), if only to clarify what people are
actually asking for.
Brian Sabbey's example from message
*seems* reasonably clear, but I don't see how it relates in any way to
"for" loops or generators, except as one (but not the only) use case.
def add(thunk1, thunk2, other):
print thunk1(1,2) + thunk2(3,4) + other
with x,y from add(100):
also a,b: # yikes??
value a*b # this is thunk2
To make my own understanding explicit:
(1) Calls for "Ruby blocks" or "thunks" are basically calls for
placeholders in a function. These placeholders will be filled
with code from someplace else, but will execute in the function's
own local namespace.
(2) A function as a parameter isn't good enough, because the
passed-in function can't see bindings in the surrounding larger
function. (It still sees the lexical scope it which it was defined.)
(3) A function as a parameter isn't good enough, because the
passed-in function can't modify bindings in the surrounding
(4) A thunk could be used today be creating a string (rather than
a pre-compiled function) and substituting in the thunk's string
(rather than the code to which it would compile) before execution,
though this would be ugly.
(5) A thunk *might* be do-able with exec or eval if a function's
locals were still a dictionary.
(6) This has nothing whatsoever to do with for loops or generators,
except as a common use case. In particular, thunks may be used
to lock/unlock or unwind-protect some resource. Generators are
not the only place this is needed, but they have made the "what
do you mean, __del__ might never get called?" problem even worse,
and Ruby often solves these with a Ruby Block.
(7) A __leave__ or __exit__ special method really turns into another
name for __del__. It might still be useful if it came with semantics
of "I explicitly don't care what order cycles are broken; call me as
soon as my object is garbage and who cares if it gets resurrected."
There have been recipes (from Tim?) for emulating this by using
a proxy to the resource, so that no __del__ cycles can form.
More information about the Python-Dev