[Python-Dev] PEP 572: Assignment Expressions (original) (raw)
Paul Moore p.f.moore at gmail.com
Fri Apr 20 04:32:34 EDT 2018
- Previous message (by thread): [Python-Dev] PEP 572: Assignment Expressions
- Next message (by thread): [Python-Dev] PEP 572: Assignment Expressions
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 20 April 2018 at 07:46, Chris Angelico <rosuav at gmail.com> wrote:
On Fri, Apr 20, 2018 at 1:30 PM, Stephen J. Turnbull <turnbull.stephen.fw at u.tsukuba.ac.jp> wrote:
Christoph Groth writes:
> Wouldn't it be a pity not to liberate assignments from their boring > statement existence? Maybe not. While it would be nice to solve the loop-and-a-half "problem" and the loop variable initialization "problem" (not everyone agrees these are even problems, especially now that we have comprehensions and generator expressions), as a matter of taste I like the fact that this particular class of side effects is given weighty statement syntax rather than more lightweight expression syntax. That is, I find statement syntax more readable. If you've read the PEP, you'll see that it encourages the use of assignment statements whereever possible. If statement syntax is generally more readable, by all means, use it. That doesn't mean there aren't situations where the expression syntax is FAR more readable. Tell me, is this "more readable" than a loop with an actual condition in it? def sqrt(n): guess, nextguess = 1, n while True: if math.isclose(guess, nextguess): return guess guess = nextguess nextguess = n / guess Readable doesn't mean "corresponds closely to its disassembly", despite the way many people throw the word around. It also doesn't mean "code I like", as opposed to "code I don't like". The words for those concepts are "strongly typed" and "dynamically typed", as have been demonstrated through MANY online discussions. (But I digress.) Readable code is code which expresses an algorithm, expresses the programmer's intent. It adequately demonstrates something at a higher abstraction level. Does the algorithm demonstrated here include an infinite loop? No? Then it shouldn't have "while True:" in it.
Thanks Chris - this is a very good explanation of how we can (somewhat) objectively look at "readability", and not one I'd really considered before. It's also an extremely good argument (IMO) that the loop-and-a-half construct would benefit from improvement.
In my opinion, it's only partially related to the assignment expression discussion, though. Yes, assignment expressions "solve" the loop-and-a-half situation. I'm unsure how much I like the look of the resulting code, but I concede that's a "code I like" vs "code I don't like" situation. But assignment expressions are much more general than that, and as a general construct, they should be evaluated based on how many problems like this they solve, and whether the downsides justify it. We've already had the comprehension use case marginalised as no longer being a key use case for the proposal, because they weren't as "obviously" improved as some people had hoped. So overall, I think assignment expressions have proved to be a bit useful in some cases, and less so in others.
Clearly any proposal can be picked to death with enough time to look for flaws. And part of the Zen is "Now is better than never". But I think in this case, "Although never is often better than right now" applies - we've had some very productive discussions, and you've done an incredible job of managing them and capturing the results, but it feels to me that the overall result is that there's likely a better solution still out there, that needs a new intuition to solve.
Now, this is a pretty obvious example. I deliberately wrote it so you could simply lift the condition straight into the while header. And I hope that everyone here agrees that this would be an improvement:
def sqrt(n): guess, nextguess = 1, n while not math.isclose(guess, nextguess): guess = nextguess nextguess = n / guess return guess But what if the condition were more complicated? def readdocument(file): doc = "" while (token := file.getnexttoken()) != "END": doc += token return doc The loop condition is "while the token is not END", or "while getnexttoken() doesn't return END", depending on your point of view. Is it "more readable" to put that condition into the while header, or to use an infinite loop and a break statement, or to duplicate a line of code before the loop and at the bottom of the loop? Which one best expresses the programmer's intention?
The version that captures the value and tests it. I agree completely here. But we do have other options:
def read_document(file): doc = "" for token in token_stream(file, terminator="END"): doc += token return doc
(This point about rewriting to use for and an iterator applies to Chris Barker's fp.readline() example as well).
Sure, token_stream might need a loop-and-a-half internally[1]. But from the user's point of view that's "low level" code, so not so important (ultimately, this is all about abstracting intent). And people maybe aren't used to writing "helper" iterators quite this freely, but that's a matter of education. So agreed - assignment expressions help with loop-and-a-half constructs. But we have other ways of dealing with them, so that's a relatively manageable situation.
It's still all about cost-benefit trade-offs, with no clear winner (in my view).
Paul
[1] Although actually not - in this case, iter(file.get_next_token, 'END') is exactly what you need. But I concede that it's possible to demonstrate examples where that isn't the case.
- Previous message (by thread): [Python-Dev] PEP 572: Assignment Expressions
- Next message (by thread): [Python-Dev] PEP 572: Assignment Expressions
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]