[Python-ideas] Allow lambda decorators
Guido van Rossum
guido at python.org
Mon Feb 9 18:09:18 CET 2009
On Sun, Feb 8, 2009 at 8:08 PM, Carl Johnson <carl at carlsensei.com> wrote:
>
> On 2009/02/08, at 5:29 pm, Guido van Rossum wrote:
>
>> I'm sorry, but you are using two nested lambdas plus a list
>> comprehension, and three nested functions here, plus one more list
>> comprehension for showing the result. My brain hurts trying to
>> understand all this. I don't think this bodes well as a use case for a
>> proposed feature.
>>
>> I'm not trying to be sarcastic here -- I really think this code is too
>> hard to follow for a motivating example.
>
> I will admit that this is getting a bit too functional-language-like for its
> own good, but (ignoring my proposed solution for a while) at least in the
> case of the nested scope problem, what other choices is there but to nest
> functions in order to keep the variable from varying? I myself was bitten by
> the variable thing when I wanted to write a simple for-loop to add methods
> to a class, but because of the scoping issue, it ended up that all of the
> methods were equivalent to the last in the list. At present, there's no way
> around this but to write a slightly confusing series of nested functions.
Are you unaware of or rejecting the solution of using a default argument value?
[(lambda x, _i=i: x+i) for i in range(10)]
is a list of 10 functions that add i to their argument, for i in range(10).
> So, that's my case for an each_in function. Going back to the @lambda thing,
> in general, people are eventually going to run into different situations
> where they have to write their own decorators. We already have a lot of
> different situations taken care of for us by the functools and itertools,
> but I don't think the library will ever be able to do everything for
> everyone. I think that the concept of writing decorators (as opposed to
> using them) is definitely confusing at first, since you're nesting one thing
> inside of another and then flipping it all around, and it doesn't entirely
> make sense, but the Python community seems to have adapted to it. For that
> matter, if I think too much about what happens in a series of nested
> generators, I can confuse myself, but each individual generator makes sense
> as a kind of "pipe" through which data is flowing and being transformed.
> Similarly, metaclasses are hard to understand but make things easy to use.
> So, I guess the key is to keep the parts easy to understand even if how the
> parts work together is a bit circuitous. Maybe @lambda isn't accomplishing
> that, but I'm not sure how much easier to understand equivalent solutions
> would be that is written without it. Easy things easy, hard things possible?
I don't see what @lambda does that you can't already do with several
other forms of syntax. The reason for adding decorators to the
language is to have easier syntax for common
manipulations/modifications of functions and methods. A decorator
using lambda would be a one-off, which kind of defeats the purpose.
For example, instead of this:
>>> def func_maker():
... @lambda f: [f(i) for i in range(10)]
... def fs(i):
... def f():
... return i
... return f
... return fs #Warning, fs is a list, not a function!
...
I would write this:
def func_maker():
def fi(i):
def f():
return i
fs = [fi(i) for i in range(10)]
return fs
In regard to the proposal of "bind i" syntax, I have a
counter-proposal (as log as we're in free association mode :-):
Define new 'for' syntax so that you can write
[lambda: i for new i in range(10)]
or e.g.
fs = []
for new i in range(10):
def f():
return i
fs.append(f)
The rule would be that "for new <name> in ..." defines a new "cell"
each time around the loop, whose scope is limited to the for loop. So
e.g. this wouldn't work:
for new i in range(10):
if i%7 == 6:
break
print i # NameError
I'm not saying I like this all that much, but it seems a more Pythonic
solution than "bind i", and it moves the special syntax closer to the
source of the problem.
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-ideas
mailing list