[Python-ideas] PEP 572: Assignment Expressions (post #4)

Kirill Balunov kirillbalunov at gmail.com
Thu Apr 12 05:21:40 EDT 2018


2018-04-12 1:43 GMT+03:00 Chris Angelico <rosuav at gmail.com>:

> On Thu, Apr 12, 2018 at 5:24 AM, Kirill Balunov <kirillbalunov at gmail.com>
> wrote:
> > I find that I wrote very vague, so I'll try in response to my answer to
> add
> > some specifics. In general, I find this idea missed in the language and
> > thank you for trying to fix this! In my opinion it has only a meaning in
> > certain constructions such as `while`, `if`, `elif` and maybe
> > comprehensions\generators. As a general form "anywhere" it can be
> _useful_,
> > but makes the code unreadable and difficult to perceive while giving not
> so
> > much benefit. What I find nice to have:
> >
> > Extend while statement syntax:
> >
> >  while (input("> ") as command) != "quit":
> >      print("You entered:", command)
>
> What you're writing there is not truly an extension of the while
> statement, but a special feature of an expression *within* the while
> header.


All right! You caught me :) For lack of a thoughtful alternative version in
my head, let it be an expression but such that it can only be used
(evaluated) in boolean context: `while` and `if`s statements (let's skip
comprehensions and generators for some time, except their `if` clause). I
agree that it contradicts with the way that in 'with' or 'import'
statements it is a part of their own syntax. But nonetheless they have the
same syntax but, strictly speaking, different semantics! And this is
normal, because they are different statements.


> Syntactically, this "expr as name" notation must be able to be
> combined with other operators (as in what you've written here), so it
> isn't like the way the 'with' or 'import' statement specifically makes
> a feature available as its own syntax.
>

Ability to combine `expr as name` with other operators - is actually a
matter of operator precedence. In my mind it should have the highest
precedence:
while input("> ") as command != "quit":
is equivalent to
while (input("> ") as command) != "quit":

Suppose that some function can return `empty tuple` and `None` (which are
both False in boolean context), for this case you can write:
while func(something) as value is not None:
which is equivalent to
while (func(something) as value) is not None:
and can be also written as:
while (func(something) as value) or (value is not None):
In the last snippet parenthesis were used only for readability.


Another example:
while f1(x) + f2(x) as value:
will be parsed as:
while f1(x) + (f2(x) as value):


> > Extend ternary expression syntax:
> >
> > data = y/x if (f(x) as y) > 0 else 0
>
> Again, this is doing further operations after the capturing, so it's
> not like you can incorporate it in the syntax. You can't write:
>
> expr2 if expr1 as NAME else expr3
> and explain its semantics that way, because then you can't put the ">
> 0" part in anywhere.
>

Do not quite understand why I can not? :) (the parenthesis was used only
for readability)


> So if, syntactically, this is a modification to expressions in
> general, why restrict them to certain contexts? Why can't I lift the
> condition out of the 'while' and give it a name?
>
> while (input("> ") as command) != "quit":
> # becomes #
> cond = (input("> ") as command) != "quit"
> print(cond)
> while cond:
>
> But I can't if this is magic in the 'while' statement. What do you
> gain by forbidding it?
>

I gain readability! I don't see any reason to use it in other
contexts... Because
it makes the code unreadable and difficult to perceive while giving not so
much benefit.  I may be wrong, but so far I have not seen a single example
that at least slightly changed my mind. Concerning your example, I did not
understand it..`cond` is evaluated only once...why you need a while loop in
this case?



> > I think that is all. And it seems to me that it covers 99% of all the
> > use-cases of this feature. In my own world I would like them to make a
> local
> > _statement_ binding (but this is certainly a very controversial point). I
> > even like that this syntax matches the `with` an `except` statements
> syntax,
> > although it has a different semantic. But I do not think that anyone will
> > have problems with perception of this.
>
> Statement-local names, controversial? You don't say!
>
> I actually think the parallel with 'with' and 'except' works *against*
> that version of the proposal, precisely because of the different
> semantics (as you mention). The difference between:
>
> except Exception as e:
> except (Exception as e):
>
>
It **will not be allowed** in `except` since there is no boolean
context... There
is no parallels, only the same syntax, it seems to me that no one will have
problems understanding what that means in different contexts. In addition,
at the moment all are coping with the differences between `import`, `with`
and `except`.



> is significant and fairly easy to spot; as soon as you try to use 'e',
> you'll figure out that it's the Exception class, not the instance that
> got thrown. But in a 'with' statement?
>
> with open(fn) as f:
> with (open(fn) as f):
>
> These will do the same thing, because Python's file objects return
> self from __enter__. So do a lot of context managers. You can go a
> VERY long way down this rabbit-hole, doing things like:
>
> with (open(infile) as read and
>         open(outfile, "w") as write):
>     write.write(read.read())
>
> In CPython, you likely won't notice anything wrong here. And hey, it's
> backslash-free multi-line context management! In fact, you might even
> be able to use this in *Jython* without noticing a problem. Until you
> have two output files, and then stuff breaks badly. Thus I sought to
> outright forbid 'as' in the expressions used in a 'with' or 'except'
> statement.


The same goes for `with` statements, I see no reason to use both `:=` and
`expr as name` in with statements. How this feature can be used here,
especially in the context you mentioned above?


> The problem doesn't exist with ':=', because it's clear
> that the different semantics go with different syntax:
>
> with open(fn) as f:
> with f := open(fn):
>
> And since there's no reason to restrict it, it's open to all contexts
> where an expression s needed.
>

 As for me this example just shows that `:=` should not be used in `with`
statements at all.

I ask you to understand me correctly, but what surprised me most, was that
different versions of PEP (3 and 4) speaks about absolutely different
things.  I think it would be great to have two competing proposals:
1. This PEP in the form that is now (with general assignment expression)
2. Another PEP which discusses only the changes in if and while statements.
I understand that it is much easier to advise than to do! I also understand
how much time it takes for all this. I myself still can not find the time
(English is given to me with great difficulty :)) to write about PEP about
partial assignment statement ...
But still, as I see these two PEPs will allow to simultaneously look at the
two approaches, and also allow to separately work through the problems
arising in each of them. I do not want to repeat it again, but I have not
yet seen any reasonable example where this current `:=` feature can be
useful, except `while` and `if`. So I do not understand why everything
needs to be complicated and not concentrate on what can actually be useful.

With kind regards,
-gdg
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180412/458d5a7a/attachment-0001.html>


More information about the Python-ideas mailing list