|
5
|
Replacement for lambda that uses language features new to Python 2.4. One implementation has a neat (ab)use of sys._getframe(); the other is portable.
Guido has expressed the desire to remove "lambda" for Python 3000. There was a discussion on comp.lang.python about what new language feature (if any) should replace lambda. Some of the proposed syntaxes led me to try a pure-python implementation. The basic idea is to use a generator expression to implement an "expression object". The function "fn" (the name is taken from the Arc language) wraps the generator in a callable and returns it. The wrapper is responsible for feeding its arguments to the genexp; this is done by cooperating with the genexp's input iterator. In the first (CPython-specific) implementation, the cooperation is simple: the wrapper just needs to name its parameter "args". The iterator reaches up the stack to extract the local variable. In the second implementation, the wrapper stores its args in what amounts to a global variable, and the input iterator "args2" almost immediately consumes it. There is no way for an anonymous function to execute between the time args.value is set and the time it's consumed; thus the use of global state is safe. However, the fact that the implementation is stateful at all makes it unsafe in the presence of threads. To make it safe, one would have to make SingleElementIterator put "value" in thread-local storage. This is left as an exercise for the reader :-). This is never explicitly an issue for these implementations, but it's worth keeping in mind that a genexp's outermost iterator is evaluated immediately. References: * Pep 3000 http://python.org/peps/pep-3000.html * comp.lang.python thread http://groups-beta.google.com/group/comp.lang.python/msg/41713ae1c0d7385a |
3 comments
Add a comment
Sign in to comment
Download
Copy to clipboard

using namespace for args. This doesn't try to solve the threading problem, but I think I prefer a solution that keeps 'args' in the 'fn' namespace, like:
which would then be used like:
That way 'args', which is intimately joined with 'fn', appears as such namespace-wise.
Perhaps a little prettier:
Also has the benefit of naming "functions" generated by fn as "fn":
Good points. I originally used a class for the "portable" version but got stuck because I didn't remember __new__. I'll update the recipe when I get a few tuits; thanks!