[Tim]
Then `c` is 12, but `a` is still 1 and `b` is still 2. Same thing in the end:
c = local(a=3, b=4, a*b)
[Nikolaus Rath
I think this can be done already with slighly different syntax:
c = (lambda a=3, b=4: a*b)()
The trailing () is a little ugly, but the semantics are much more obvious.
[Tim]
But also broken, in a way that can't be sanely fixed. Covered before in other messages. Short course:
a = 10 b = 20 (lambda a=3, b=a+1: (a, b))() (3, 11)
This context really demands (3, 4) instead. In Scheme terms, Python's lambda default arguments do "let" binding ("all at once"), but "let*" binding is what's needed ("one at a time, left to right, with bindings already done visible to later bindings").
[Chris Angelico
So maybe the effective semantics should be:
(lambda a=3: (lambda b=a+1: (a, b))())() (3, 4)
Almost, but by that point the idea that this is already "easily spelled" via lambdas has become ludicrously difficult to argue with a straight face ;-) By "almost", I mean there are other cases where even nesting Python lambdas doesn't capture the intent. In these cases, not only does the expression defining b refer to a, but _also_ the expression defining a refers to b. You can play, if you like, with trying to define the `iseven` lambda here in one line by nesting lambdas to define `even` and `odd` as default arguments: even = (lambda n: n == 0 or odd(n-1)) odd = (lambda n: False if n == 0 else even(n-1)) iseven = lambda n: even(n) Scheme supplies `letrec` for when "mutually recursive" bindings are needed. In Python that distinction isn't nearly as evidently needed, because Python's idea of closures doesn't capture all the bindings currently in effect,. For example, when `odd` above is defined, Python has no idea at all what the then-current binding for `even` is - it doesn't even look for "even" until the lambda is _executed_. But, to be fair, I'm not sure: iseven =- local( even = (lambda n: n == 0 or odd(n-1)), odd = (lambda n: False if n == 0 else even(n-1)). lambda n: even(n)) would have worked either. At the moment I'm certain it wouldn't. Last night I was pretty sure it would ;-)