On Thu, 26 Apr 2018 10:20:40 +1000 Chris Angelico firstname.lastname@example.org wrote:
On Thu, Apr 26, 2018 at 10:11 AM, Yury Selivanov
Just yesterday this snippet was used on python-dev to show how great the new syntax is:
my_func(arg, buffer=(buf := [None]*get_size()), size=len(buf))
To my eye this is an anti-pattern. One line of code was saved, but the other line becomes less readable. The fact that 'buf' can be used after that line means that it will be harder for a reader to trace the origin of the variable, as a top-level "buf = " statement would be more visible.
Making 'buf' more visible is ONLY a virtue if it's going to be used elsewhere. Otherwise, the name 'buf' is an implementation detail of the fact that this function wants both a buffer and a size. Should you want to expand this out over more lines, you could do this:
template = [None] buf = template*get_size() length = len(buf) my_func(arg, buffer=buf, size=length)
What are the names 'template' and 'length' achieving? Why should they claim your attention?
What is the name 'buf' in the binding expression achieving? Why should it claim my attention? It's not any different: it's just something that's used in a statement then unnecessary. Yet it will persist until the end of the enclosing scope, being retained for no reason. Perhaps we need C-like nested scopes, if such is the concern about names that live for too long?
(of course, the fact that
my_func needs you to pass its argument's
length as a separate argument, while it could compute it by itself, is
a bit silly)
As a side note, personally, I'm usually much more concerned about the lifetime of values than the lifetime of names. The latter are cheap, the former can represent expensive resources.
They are useless relics of a done-and-dusted calculation, being retained for no reason. They do not deserve top-level placement.
The form as given above is starting to get a bit noisy, but I strongly disagree that 'buf' deserves to be a stand-alone name. It is as valueless as 'template' is.