
I don't like how in Python 3.x, you can't do this: lambda (x, y): whatever It's quite useful in Python 2 if I understand correctly, it's a side effect of such packed arguments not being allowed in function definitions. (i.e. def instead of lambda) Can you please refer me to the original discussion in which it was decided to remove this grammar in Python 3? I'd like to understand the arguments for it. Thanks, Ram.

On Fri, Jan 24, 2014 at 10:50 AM, Ram Rachum <ram@rachum.com> wrote:
I don't like how in Python 3.x, you can't do this:
lambda (x, y): whatever
It's quite useful in Python 2
if I understand correctly, it's a side effect of such packed arguments not being allowed in function definitions. (i.e. def instead of lambda)
Can you please refer me to the original discussion in which it was decided to remove this grammar in Python 3? I'd like to understand the arguments for it.

Brett Cannon wrote:
On Fri, Jan 24, 2014 at 10:50 AM, Ram Rachum <ram@rachum.com <mailto:ram@rachum.com>> wrote:
lambda (x, y): whatever
Part of the rationale in that PEP is that argument unpacking can always be replaced by an explicitly named argument and an unpacking assignment. No mention is made of the fact that you can't do this in a lambda, giving the impression that lambdas are deemed second-class citizens that are not worth consideration. The author was clearly aware of the issue, since a strategy is suggested for translation of lambdas by 2to3: lambda (x, y): x + y --> lambda x_y: x_y[0] + x_y[1] That's a bit on the ugly side for human use, though. An alternative would be lambda xy: (lambda x, y: x + y)(*xy) Whether that's any better is a matter of opinion. -- Greg

On 25 January 2014 15:41, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Brett Cannon wrote:
On Fri, Jan 24, 2014 at 10:50 AM, Ram Rachum <ram@rachum.com <mailto:ram@rachum.com>> wrote:
lambda (x, y): whatever
Part of the rationale in that PEP is that argument unpacking can always be replaced by an explicitly named argument and an unpacking assignment. No mention is made of the fact that you can't do this in a lambda, giving the impression that lambdas are deemed second-class citizens that are not worth consideration.
Given that lambdas only just escaped being removed entirely from the language in Python 3, that impression isn't wrong. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

25.01.14 07:41, Greg Ewing написав(ла):
Brett Cannon wrote:
On Fri, Jan 24, 2014 at 10:50 AM, Ram Rachum <ram@rachum.com <mailto:ram@rachum.com>> wrote:
lambda (x, y): whatever
Part of the rationale in that PEP is that argument unpacking can always be replaced by an explicitly named argument and an unpacking assignment. No mention is made of the fact that you can't do this in a lambda, giving the impression that lambdas are deemed second-class citizens that are not worth consideration.
The author was clearly aware of the issue, since a strategy is suggested for translation of lambdas by 2to3:
lambda (x, y): x + y --> lambda x_y: x_y[0] + x_y[1]
That's a bit on the ugly side for human use, though. An alternative would be
lambda xy: (lambda x, y: x + y)(*xy)
Whether that's any better is a matter of opinion.
There is open issue for this: http://bugs.python.org/issue16094

On Sat, Jan 25, 2014 at 12:41 AM, Greg Ewing <greg.ewing@canterbury.ac.nz>wrote:
Brett Cannon wrote:
On Fri, Jan 24, 2014 at 10:50 AM, Ram Rachum <ram@rachum.com <mailto: ram@rachum.com>> wrote:
lambda (x, y): whatever
Part of the rationale in that PEP is that argument unpacking can always be replaced by an explicitly named argument and an unpacking assignment. No mention is made of the fact that you can't do this in a lambda, giving the impression that lambdas are deemed second-class citizens that are not worth consideration.
The author was clearly aware of the issue, since a strategy is suggested for translation of lambdas by 2to3:
lambda (x, y): x + y --> lambda x_y: x_y[0] + x_y[1]
That's a bit on the ugly side for human use, though. An alternative would be
lambda xy: (lambda x, y: x + y)(*xy)
Whether that's any better is a matter of opinion.
As the author of the PEP and I can say that `lambda (x, y): x + y` can just as easily be expressed as `lambda x, y: x + y` and then be called by using *args in the argument list. Anything that gets much fancier typically calls for a defined function instead of a lambda.

On Jan 25, 2014, at 4:01 PM, Brett Cannon <brett@python.org> wrote:
As the author of the PEP and I can say that `lambda (x, y): x + y` can just as easily be expressed as `lambda x, y: x + y` and then be called by using *args in the argument list. Anything that gets much fancier typically calls for a defined function instead of a lambda.
I think that is an over-simplification. The argument unpacking was handy in a number of situations where *args wouldn't suffice: lambda (px, py), (qx, qy): ((px - qx) ** 2 + (py - qy) ** 2) ** 0.5 IIRC, the original reason for the change was that it simplified the compiler a bit, not that it was broken or not useful. Taking-out tuple unpacking might have been a good idea for the reasons listed in the PEP, but we shouldn't pretend that it didn't cripple some of the use cases for lambda where some of the arguments came in as tuples (host/port pairs, x-y coordinates, hue-saturation-luminosity, month-day-year, etc). Raymond

On 01/26/2014 03:42 AM, Raymond Hettinger wrote:
I think that is an over-simplification. The argument unpacking was handy in a number of situations where *args wouldn't suffice:
lambda (px, py), (qx, qy): ((px - qx) ** 2 + (py - qy) ** 2) ** 0.5
IIRC, the original reason for the change was that it simplified the compiler a bit, not that it was broken or not useful.
I'm not sure if that's applicable or other issues arise with: def fn(*p): px,py,qx,qy = p; return ((px - qx) ** 2 + (py - qy) ** 2) ** 0.5 Thanks in advance! Francis

On 01/26/2014 09:59 AM, francis wrote:
On 01/26/2014 03:42 AM, Raymond Hettinger wrote:
I think that is an over-simplification. The argument unpacking was handy in a number of situations where *args wouldn't suffice:
lambda (px, py), (qx, qy): ((px - qx) ** 2 + (py - qy) ** 2) ** 0.5
IIRC, the original reason for the change was that it simplified the compiler a bit, not that it was broken or not useful.
I'm not sure if that's applicable or other issues arise with:
def fn(*p): px,py,qx,qy = p; return ((px - qx) ** 2 + (py - qy) ** 2) ** 0.5
[Dropping some whitespace to get things to all fit on one line] The goal is to call fn as: fn((1, 1), (2, 2)) So, in 2.7:
def fn((px, py), (qx, qy)): ... return ((px-qx)**2+(py-qy)**2)**0.5 ... fn((1, 1), (2, 2)) 1.4142135623730951
The nearest equivalent in 3.3 (also works in 2.7):
def fn(p, q): ... (px, py), (qx, qy) = p, q ... return ((px-qx)**2+(py-qy)**2)**0.5 ... fn((1, 1), (2, 2)) 1.4142135623730951
For a lambda in 3.3, you're out of luck because you can't do the assignment. There, the best you can do is:
fn = lambda p, q: ((p[0]-q[0])**2+(p[1]-q[1])**2)**0.5 fn((1, 1), (2, 2)) 1.4142135623730951
Which isn't quite so readable as the equivalent lambda in 2.7:
fn = lambda (px, py),(qx, qy):((px-qx)**2+(py-qy)**2)**0.5 fn((1, 1), (2, 2)) 1.4142135623730951
As someone pointed out, it's not quite the same when you do your own tuple unpacking, but it's probably close enough for most cases. Eric.

On 1/24/2014 10:50 AM, Ram Rachum wrote:
I don't like how in Python 3.x, you can't do this:
lambda (x, y): whatever
It's quite useful in Python 2
if I understand correctly, it's a side effect of such packed arguments not being allowed in function definitions. (i.e. def instead of lambda)
You can still do:
fn = lambda x, y: x+y fn(20, 22) 42
It's just tuple unpacking which doesn't work.
Can you please refer me to the original discussion in which it was decided to remove this grammar in Python 3? I'd like to understand the arguments for it.
See PEP 3113.
participants (8)
-
Brett Cannon
-
Eric V. Smith
-
francis
-
Greg Ewing
-
Nick Coghlan
-
Ram Rachum
-
Raymond Hettinger
-
Serhiy Storchaka