[Python-ideas] Inline assignment expression

Nick Coghlan ncoghlan at gmail.com
Sun Mar 15 05:39:05 CET 2009


Jervis Whitley wrote:
>>> if (something as x) == other:
>>>    # can now use x.
>> Interesting. I'd definitely prefer that to the C-style inline assignment
>> syntax: I think it reads better, and there's less chance of the Accidental
>> Assignment Instead Of Comparison trap that has plagued other languages.
> 
> However, allowing this "something as x" syntax for assignment would cause
> confusion with the "with contextmanager as x" scenario. "as" was chosen in their
> case because the expr contextmanager is not assigned to x.
> While I do like the "as" syntax too, I have not endorsed it for the
> above reason.

If you look at the current uses for 'as' it is never for direct assignment:

import x as y:
  'x' is not a normal expression here, it's a reference into the module
namespace. The value assigned to 'y' has nothing to do with what you
would get if you evaluated the expression 'x' in the current namespace.

with x as y:
  'y' is assigned the value of x.__enter__(), not x

except x as y:
  'y' is assigned the value of a raised exception that meets the
criteria "isinstance(y, x)".

In all three cases, while the value eventually assigned to 'y' is
*related* to the value of 'x' in some way, it isn't necessarily 'x'
itself that is assigned (although the with statement version can
sometimes give that impression, since many __enter__() methods finish
with "return self").

Proposals for implicit assignment tend to founder on one of two objections:

A. The proposal uses existing assignment syntax ('x = y') and runs afoul
of the C embedded assignment ambiguity problem (i.e. did the programmer
intentionally write "if x = y:" or did they actually mean to write "if x
== y:"?)

B. The proposal uses different assignment syntax ('x -> y', 'y <- x', 'x
as y') and runs afoul of the question of why are there two forms of
assignment statement? (Since any expression can be a statement, the new
embedded assignment syntax would either work as a statement as well, or
else a special rule would have to added to the compiler to say "cannot
use embedded assignment expression as statement - use an assignment
statement instead").

There are also a couple of more general points of confusion related to
nested namespaces as far as embedded assignments go:

1. Assignments inside lambda expressions, list/dict/set comprehensions
and generator expressions (all of which create their own local
namespace) won't affect the current scope, but assignment in any other
expression *will* affect the current scope. Just to make things even
more confusing, assignments in the outermost iterator of a comprehension
or genexp actually *will* affect the current scope.

2. Since global and nonlocal declarations only affect the current
namespace, they're subject to the same kind of confusion as happens with
local assignments: they won't affect assignments embedded inside lambda
expressions, comprehensions and genexps (except for the outermost
iterator for the latter two expression groups).

With the way nested namespaces are set up, allowing embedded assignments
would just be a recipe for long term confusion even if it did
occasionally make some algorithms fractionally easier to write down.

Cheers,
Nick.

Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------



More information about the Python-ideas mailing list