[Python-Dev] Let's just keep lambda (original) (raw)
Guido van Rossum guido at python.org
Thu Feb 9 19:33:10 CET 2006
- Previous message: [Python-Dev] Let's just *keep* lambda
- Next message: [Python-Dev] Let's just *keep* lambda
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Enough already.
As has clearly been proven, lambda is already perfect.
To those folks attempting to propose alternate syntax (e.g. x -> y): this is the wrong thread for that (see subject). Seriously, I've seen lots of proposals that just change the syntax, and none of them are so much better than what we have. My comments on some recent proposals:
for Smells to much like a loop. And what if there are no formals? Also the generalization from a generator without the "in " part is wrong; "f(x) for x in S" binds x, while the proposed "f(x) for x" has x as a free variable. Very odd.
-> The -> symbol is much easier to miss. Also it means something completely different in other languages. And it has some problems with multiple formals: (x, y -> x+y) isn't very clear on the binding -- since '->' is an uncommon operator, there's no strong intuition about whether ',' or '->' binds stronger. (x, y) -> x+y would make more sense, but has an ambiguity as long as we want to allow argument tuples (which I've wanted to take out, but that is also getting a lot of opposition).
lambda(): This was my own minimal proposal. I withdraw it -- I agree with the criticism that it looks too much like a function call.
Use a different keyword instead of lambda What is that going to solve?
If there were other proposals, I missed them, or they were too far out to left field to be taken seriously.
To those people complaining that Python's lambda misleads people into thinking that it is the same as Lisp's lambda: you better get used to it. Python has a long tradition of borrowing notations from other languages and changing the "deep" meaning -- for example, Python's assignment operator does something completely different from the same operator in C or C++.
To those people who believe that lambda is required in some situations because it behaves differently with respect to the surrounding scope than def: it doesn't, and it never did. This is (still!) a surprisingly common myth. I have no idea where it comes from; does this difference exist in some other language that has lambda as well as some other function definition mechanism?
To those people still complaining that lambda is crippled because it doesn't do statements: First, remember that adding statement capability wouldn't really add any power to the language; lambda is purely syntactic sugar for an anonymous function definition (see above myth debunking section). Second, years of attempts to overcome this haven't come up with a usable syntax (and yes, curly braces have been proposed and rejected like everything else). It's a hard problem because switching back to indentation-based parsing inside an expression is problematic. For example, consider this hypothetical example:
a = foo(lambda x, y: print x print y)
Should this be considered legal? Or should it be written as
a = foo(lambda x, y: print x print y )
??? (Indenting the prints so they start at a later column than the 'l' of 'lambda', and adding an explicit dedent before the close parenthesis.) Note that if the former were allowed, we'd have additional ambiguity if foo() took two parameters, e.g.:
a = foo(lambda x, y: print x print y, 42)
-- is 42 the second argument to foo() or is it printed?
I'd much rather avoid this snake's nest by giving the function a name and using existing statement syntax, like this:
def callback(x, y): print x print y a = foo(callback)
This is unambiguous, easier to parse (for humans as well as for computers), and doesn't actually span more text lines. Since this typically happens in a local scope, the name 'callback' disappears as soon as as the scope is exited.
BTW I use the same approach regularly for breaking up long expressions; for example instead of writing
a = foo(some_call(another_call(some_long_argument, another_argument), and_more(1, 2, 3), and_still_more())
I'll write
x = another_call(some_long_argument, another_argument) a = foo(some_call(x, and_more(1, 2, 3)), and_still_more())
and suddenly my code is more compact and yet easier to read! (In real life, I'd use a more meaningful name than 'x', but since the example is nonsense it's hard to come up with a meaningful name here. :-)
Regarding the leakage of temporary variable names in this case: I don't care; this typically happens in a local scope where a compiler could easily enough figure out that a variable is no longer in use. And for clarity we use local variables in this way all the time anyway.
Parting shot: it appears that we're getting more and more expressionized versions of statements: first list comprehensions, then generator expressions, most recently conditional expressions, in Python 3000 print() will become a function... Seen this way, lambda was just ahead of its time! Perhaps we could add a try/except/finally expression, and allow assignments in expressions, and then we could rid of statements altogether, turning Python into an expression language. Change the use of parentheses a bit, and... voila, Lisp! :-)
-- --Guido van Rossum (home page: http://www.python.org/~guido/)
- Previous message: [Python-Dev] Let's just *keep* lambda
- Next message: [Python-Dev] Let's just *keep* lambda
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]