
I would definitely love that kind of subscoping syntax, but as you say, that would be a much larger change. :) The use of this for things like '2+2' would be, as you say, syntactic sugar; the compiler could even be clever and strip it out of the bytecode entirely. Its only purpose in that context would be to clarify place of use, and to allow simplification of multi-element 'with' assignments like in the last example I gave in the original email. The principal purpose of this change, however, would be to enable things like optional value returns, in which in at least one fork of a conditional the 'with' statement would remain nontrivial. On Sat, May 18, 2019 at 7:02 PM Chris Angelico <rosuav@gmail.com> wrote:
On Sun, May 19, 2019 at 11:46 AM David Mertz <mertz@gnosis.cx> wrote:
I think you probably mean something other than what you actually
write. It doesn't really make sense for "any expression" as far as I can tell. What would it possibly mean to write:
with (2+2) as foo: print(foo)
I have occasionally thought it would be nice to do something like this (and I could, but I haven't, so I guess I don't think it that strongly):
@contextmanager ... def bind(val): ... yield val ... with bind(2+2) as four: ... print(four) ... 4
Thing is, this is slightly deceptive. People will assume/expect that the name binding 'four' ends at the end of the 'with' block. In actual fact, something like this has an entrance but no exit - there is absolutely no meaning to the unindent. Functionality would be identical to "with bind(2+2) as four: pass" followed by the same code.
Python's 'with' block guards a section of code. At the end of that code, something has to get undone - a file gets closed, a database transaction gets committed/rolled back, a suppressed exception returns to normal state, etc. You can't have the __exit__ method do "del four", so with current code, there's no code-significant meaning to this block.
So there are two broad options:
1) Keep it having no functional meaning, just a semantic declaration "hey, this is the only place I'm using this". Not hugely valuable, but maybe people would like it. Probably best to have the three-line bind() function.
2) Redefine the 'with' block or create a new syntactic form such that the variable actually creates a subscope. That way, at the end of the block, the name would revert to its former meaning.
x = 1 with local 2 as x: print(x) # 2 print(x) # 1
This would have definite value, but would be a much larger change to the language. And variants of it have been proposed and rejected before.
ChrisA _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/