[Python-Dev] PEP 572: Assignment Expressions -- intention to accept, near-final draft
Guido van Rossum
guido at python.org
Tue Jul 10 00:15:37 EDT 2018
On Mon, Jul 9, 2018 at 8:24 PM, Rob Cliffe via Python-Dev <
python-dev at python.org> wrote:
> I apologise for not replying in the form of a Pull Request - I don't know
> how to make one.
>
>
> On 10/07/2018 02:00, Guido van Rossum wrote:
>
>> Rationale
>> =========
>>
>> Naming the result of an expression is an important part of programming,
>> allowing a descriptive name to be used in place of a longer expression,
>> and permitting reuse. Currently, this feature is available only in
>> statement form, making it unavailable in list comprehensions and other
>> expression contexts.
>>
>
> I think the wording of the last sentence gives too much importance to list
> comprehensions (IMO influenced by the amount of discussion of the PEP that
> was related to list comprehensions, understandably since that was the case
> where the semantics were most debatable). I would suggest
> "... making it unavailable in expression contexts."
> or maybe
> "... making it unavailable in expression contexts (including list
> comprehension)."
>
Hm, I don't think it's worth tweaking the text here. The PEP has some
choice things to say about comprehensions, and I don't mind calling them
out especially here. Also, when you need a temporary variable outside a
comprehension it's easy enough to rewrite the code a bit -- but for a
comprehension you'd have to refactor the whole comprehension away (into a
regular for-loop), which is a bit more effort.
> Another example illustrates that programmers sometimes do more work to
>> save an extra level of indentation::
>>
>> match1 = pattern1.match(data)
>> match2 = pattern2.match(data)
>> if match1:
>> return match1.group(1)
>> elif match2:
>> return match2.group(2)
>>
>> This code tries to match ``pattern2`` even if ``pattern1`` has a match
>> (in which case the match on ``pattern2`` is never used). The more
>> efficient rewrite would have been::
>>
>> match1 = pattern1.match(data)
>> if match1:
>> return match1.group(1)
>> else:
>> match2 = pattern2.match(data)
>> if match2:
>> return match2.group(2)
>>
> I suggest
> ... The more efficient rewrite would have been:
> match1 = pattern1.match(data)
> if match1:
> return match1.group(1)
> match2 = pattern2.match(data)
> if match2:
> return match2.group(2)
> (a more natural way to write it which avoids cascading indentation).
>
Hm, I think I might have simplified this a bit from the code I actually
found -- there might not have been a `return` in the original. I don't want
to break the `if...elif` pattern in the rewrite. I guess I'll rewrite it
using assignment to a variable instead of `return`.
> # Handle a matched regex
>> if (match := pattern.search(data)) is not None:
>> ...
>>
> I suggest
> # Handle a matched regex
> if (match := pattern.search(data)) is not None:
> # do something with match
> I think it is really important to make clear the benefit of the PEP here:
> that "match" is bound to a value and can be used subsequently.
>
> # A more explicit alternative to the 2-arg form of iter() invocation
>> while (value := read_next_item()) is not None:
>> ...
>>
> As the 2-arg form of iter() is not that well known, I suggest that the
> iter version is spelled out for contrast. (Sorry, I can't quite work it
> what it would be.)
>
Hm, you have a point there. I was referring to
for value in iter(read_next_item, None):
...
The example would be more convincing if there was an additional argument to
read_next_value(), since then the 2-arg iter() version would have required
a lambda. Maybe I shouldn't mention 2-arg iter here at all.
> # Share a subexpression between a comprehension filter clause and its
>> output
>> filtered_data = [y for x in data if (y := f(x)) is not None]
>>
> That's fine, but what about also having an example that illustrates,
> simply, the "permitting reuse" in an expression part of the Rationale, e.g.
> powers = [ (y := x+1), y**2, y**3, y**4 ]
> (I appreciate that this sort of overlaps with the section "Simplifying
> list comprehensions", but it seems to me to be such an important part of
> the Rationale that it should be illustrated here.)
>
I could add this (before the filtered_data example):
# Reuse a value that's expensive to compute
[y := f(x), y**2, y**3]
> Relative precedence of ``:=``
>> -----------------------------
>>
>> The ``:=`` operator groups more tightly than a comma in all syntactic
>> positions where it is legal, but less tightly than all operators,
>> including ``or``, ``and`` and ``not``.
>>
> and presumably including "if" and "else", as in
> x := y if y else -1
> Might it be worth adding "if" and "else" to the list?
>
Good call, I'll add conditional expressions to the list.
> - Single assignment targets other than than a single ``NAME`` are
>> not supported::
>>
>> # No equivalent
>> a[i] = x
>> self.rest = []
>>
>> [snip]
>>
>> - Iterable packing and unpacking (both regular or extended forms) are
>> not supported::
>>
>> # Equivalent needs extra parentheses
>> loc = x, y # Use (loc := (x, y))
>> info = name, phone, *rest # Use (info := (name, phone, *rest))
>>
>> # No equivalent
>> px, py, pz = position
>> name, phone, email, *other_info = contact
>>
>> [snip]
>> total += tax # Equivalent: (total := total + tax)
>>
> Is it conceivable that some of these restrictions might be removed in a
> future version of Python? If so, the PEP might include a note to this
> effect.
>
I wouldn't hold my breath.
> Oh, and what I think are typos:
>
> (Note that ``with EXPR as VAR`` does *not* simply assing the value
> of ``EXPR`` to ``VAR`` -- it calls ``EXPR.__enter__()`` and assigns
> the result of *that* to ``VAR``.)
>
> assing -> assign
>
Fixed already.
(eg where the condition is ``f(x) < 0``
>
> eg -> e.g.
>
Thanks, will fix.
> members of the core-mentorship mailing list
>
> core-mentorship -> core mentorship
>
Why? The list is named core-mentorship at python.org.
> is a vast improvment over the briefer::
>
> improvment -> improvement
>
Will fix.
> Best wishes
> Rob Cliffe
>
https://github.com/python/peps/pull/719
--
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20180709/c9ab5a21/attachment-0001.html>
More information about the Python-Dev
mailing list