This is not a duplicate of Assignment inside lambda expression in Python, i.e., I'm not asking how to trick Python into assigning in a lambda
expression.
I have some λ-calculus background. Considering the following code, it
looks like Python is quite willing to perform side-effects in lambda
expressions:
#!/usr/bin/python
def applyTo42(f):
return f(42)
def double(x):
return x * 2
class ContainsVal:
def __init__(self, v):
self.v = v
def store(self, v):
self.v = v
def main():
print('== functional, no side effects')
print('-- print the double of 42')
print(applyTo42(double))
print('-- print 1000 more than 42')
print(applyTo42(lambda x: x + 1000))
print('-- print c\'s value instead of 42')
c = ContainsVal(23)
print(applyTo42(lambda x: c.v))
print('== not functional, side effects')
print('-- perform IO on 42')
applyTo42(lambda x: print(x))
print('-- set c\'s value to 42')
print(c.v)
applyTo42(lambda x: c.store(x))
print(c.v)
#print('== illegal, but why?')
#print(applyTo42(lambda x: c.v = 99))
if __name__ == '__main__':
main()
But if I uncomment the lines
print('== illegal, but why?')
print(applyTo42(lambda x: c.v = 99))
I'll get
SyntaxError: lambda cannot contain assignment
Why not? What is the deeper reason behind this?
As the code demonstrates, it cannot be about “purity” in a functional sense.
The only explanation I can imagine is that assignemts do not return anything, not even
None
. But that sounds lame and would be easy to fix (one way: make lambda expressions returnNone
if body is a statement).
Not an answer:
Because it's defined that way (I want to know why it's defined that way).
Because it's in the grammar (see above).
Use
def
if you need statements (I did not ask for how to get statements into a function).
“This would change syntax / the language / semantics” would be ok as an answer if you can come up with an example of such a change, and why it would be bad.
lambdas
are limited to only expressions on purpose. If you want all the rest, just use a full function definition. Here is the spec: docs.python.org/3/reference/expressions.html#lambda – Squamousif x = 3:
(instead ofif x == 3:
) becomes a syntax error rather than a subtle runtime semantic error. – Sweatylambda x: setattr(c, 'v', 99)
. – Sweatydef
statement, and in fact are a convenience that was almost eliminated from the language altogether during the design of Python 3. – Sweaty