
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@gmail.com | Brisbane, Australia ---------------------------------------------------------------