Re: Confusing error message: lambda walruses

2021-10-03 Thread Peter J. Holzer
On 2021-10-03 10:39:38 +1100, Chris Angelico wrote:
> Using assignment expressions in lambda functions sometimes works, but
> sometimes doesn't.

> ... return lambda x: (x, x := 2, x)
syntax ok

> return lambda: n := 1
syntax error

> ... return lambda: (n := 1)
syntax ok

> return (lambda: n := 1)
syntax error

> ... return (lambda: (n := 1)), (lambda: n)
syntax ok, but doesn't assign

...
> What's going on here?

I think it's the parentheses:

The right side of the lambda is defined as an «expression», not an an
«assignment_expression», and there is no direct derivation from one to
the other in the grammar. So you can't put an «assignment_expression» there
directly. But if you put it in parentheses, it becomes a «starred_item»
which is a «starred_expression» which is then part of the «parenth_form»
which is an «enclosure» which is an «atom» which is (through several
more steps) an «expression» which can be used on the right side of a
lambda.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | [email protected] |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Confusing error message: lambda walruses

2021-10-03 Thread Peter J. Holzer
On 2021-10-03 10:39:38 +1100, Chris Angelico wrote:
> # Oh, and it doesn't actually assign anything.
> >>> def f(n):
> ... return (lambda: (n := 1)), (lambda: n)
> ...
> >>> g, h = f(5)
> >>> h()
> 5
> >>> g()
> 1
> >>> h()
> 5

I thought about that one a bit more and I think that the lambda is
creating a new scope, just like a regular function would, so it is
assigning to its own private «n», not the «n» in «f(n)».

https://docs.python.org/3/reference/expressions.html#grammar-token-lambda-expr
doesn't mention scope explicitely, but

|The unnamed object behaves like a function object defined with:
|
|def (parameters):
|return expression

implies to me that it should create a new scope because a nested function
defined with «def» would do that, too.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | [email protected] |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list