Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Can someone explain the concrete reasons why BDFL choose to make Python lambdas single line?

This is good:

lambda x: x**x

This results in an error:

lambda x:
    x**x

I understand that making lambda multi-line would somehow "disturb" the normal indentation rules and would require adding more exceptions, but isn't that worth the benefits?

Look at JavaScript, for example. How can one live without those anonymous functions? They're indispensable. Don't Pythonistas want to get rid of having to name every multi-line function just to pass it as an argument?

share|improve this question
    
Considering that you note the concrete reasons why Guido doesn't allow multi-expression lambdas and then dismiss them, I'm going to assume you're seeking validation rather than a real answer. –  Jason Baker Aug 7 '11 at 18:13
1  
Apart from saving seven characters, how is this any better than a def? It now has exactly the same visual structure. –  detly Aug 8 '11 at 1:28
    
add comment

3 Answers

up vote 15 down vote accepted

Guido van van Rossum answered it himself:

But such solutions often lack "Pythonicity" -- that elusive trait of a good Python feature. It's impossible to express Pythonicity as a hard constraint. Even the Zen of Python doesn't translate into a simple test of Pythonicity...

In the example above, it's easy to find the Achilles heel of the proposed solution: the double colon, while indeed syntactically unambiguous (one of the "puzzle constraints"), is completely arbitrary and doesn't resemble anything else in Python...

But I'm rejecting that too, because in the end (and this is where I admit to unintentionally misleading the submitter) I find any solution unacceptable that embeds an indentation-based block in the middle of an expression. Since I find alternative syntax for statement grouping (e.g. braces or begin/end keywords) equally unacceptable, this pretty much makes a multi-line lambda an unsolvable puzzle.

http://www.artima.com/weblogs/viewpost.jsp?thread=147358

Basically, he says that although a solution is possible, it's not congruent with how Python is.

share|improve this answer
1  
+1 thanks for the thread link -- but i would still appreciate multi-line lambdas -- they are invaluable -- look at JavaScript, PHP has them included also. –  good_computer Aug 7 '11 at 17:49
2  
@greengit You can just use a nested def. It isn't the same as anonymous functions, but they're close enough. –  jsternberg Aug 7 '11 at 17:58
    
nested defs don't help when passing functions as arguments -- that's the number one reason why i'd like multi-line lambds –  good_computer Aug 7 '11 at 18:03
1  
@greengit - I think you're better off taking this up with GvR than posting your comments here. –  Jason Baker Aug 7 '11 at 18:10
3  
@greengit: You do know that you can pass the function in as an argument to another function? You can't write it inline, but there is no programming technique that is not available to you. –  btilly Aug 7 '11 at 19:56
add comment

it's perfectly fine to do a multi line lambda in python: see

>>> f = lambda x: (
...   x**x)
>>> f
<function <lambda> at 0x7f95d8f85488>
>>> f(3)
27

the real lambda limitation is the fact that lambda must be a single expression; it can't contains keyword (like python2's print or return).

GvR choose to do so to limit the size of the lambda, as they normally are used as parameters. If you want a real function, use def

share|improve this answer
1  
multi line is about the insert of the '\n' character :D python does not have multi statement lambda. You really want to use def. Think about it: you really need a callable as a parameter of your function? And the users of that function aren't allowed to pass your default callable? How can they pass it if you don't give it to them? –  Vito De Tullio Aug 7 '11 at 18:14
    
btw, can you provide an example of your need of an anonimous function? –  Vito De Tullio Aug 7 '11 at 18:19
add comment

I know this is super old, but putting here as a reference.

An alternative to using lambda could be to use a def in a non-conventional way. The goal is to pass a def to a function, which can be done in only one circumstance -- a decorator. Notice that with this implementation def result does not create a function, it creates the result of reduce(), which ends up being a dict.

Shameless plug: I do a lot of this here.

>>> xs = [('a', 1), ('b', 2), ('a', 3), ('b', 4)]
>>> foldl = lambda xs, initial: lambda f: reduce(f, xs, initial)
>>> @foldl(xs, {})
... def result(acc, (k, v)):
...     acc.setdefault(k, 0)
...     acc[k] += v
...     return acc
...
>>> result
{'a': 4, 'b': 6} 

Note that multi-statement lambdas can be done, but only with really, really ugly code. However, what is interesting is how scoping works with this implementation (note the multiple usage of the name variable and the shadowing of the message variable.

>>> from __future__ import print_function
>>> bind = lambda x, f=(lambda x: x): f(x)
>>> main = lambda: bind(
...     print('Enter your name.'), lambda _: bind(
...     raw_input('> '), lambda name: bind(
...     'Hello {}!'.format(name), lambda message: bind(
...     print(message), lambda _: bind(
...     'Bye {}!'.format(name), lambda message: bind(
...     print(message)
... ))))))
>>> main()
Enter your name.
> foo
Hello foo!
Bye foo!
share|improve this answer
    
+1 for a monadic approach –  jozefg Nov 16 '13 at 13:54
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.