This seems more suitable for a style guide. Enforcing such restrictions in the grammar would actually be complicated, due to nesting -- but even if it wasn't, I wouldn't want to, as I don't want to limit future generations to only the benefits of the new construct that we can now come up with. Orthogonality is a good thing in my mind, else we might never have had nested functions or conditional imports.
As to why you might want to use := in a function call, I could imagine writing if validate(name := re.search(pattern, line).group(1)): return name The benefit of combining the assignment with the if would be more apparent if there was an if-elif...elif-else pattern, like here: https://github.com/python/peps/pull/695/files#diff-09a4f112ea673a2339f0bec6014ff47fR409 (click off the comments to see it better). On Sat, Jul 7, 2018 at 6:12 AM Giampaolo Rodola' <g.rod...@gmail.com> wrote: > Sorry in advance for opening yet another topic about PEP-572. With PEP-572 > being officially accepted I know debating its inclusion in the language is > a useless exercise at this point, but since it's still in "draft" status I > would like to express my opinion as I think this is a feature which can > potentially be abused fairly easily. FWIW I initially found myself > disliking the idea as a whole but > https://github.com/python/cpython/pull/8122 made me (and others) > reconsider it quite a bit (see: > https://twitter.com/grodola/status/1015251302350245888). PR-8122 clearly > shows an improvement in expressiveness and compactness (many folks argue > this is too much) but PEP-572 as it currently stands is too permissive > IMHO. My concern about "easily abusable ugly cases" still remains, and I > think they should be banned instead of just discouraged in the PEP or in > the doc. Since we spend way more time *reading* code rather than writing > it, as a "reader" I would expect a more prudent approach to the problem. > > Proposal > ======== > > 1) allow only one := assignment per line in "if" statements: > >>> if x := val1 and y := val2: # SyntaxError or SyntaxWarning > >>> if x == val1 and y := val2: # SyntaxError or SyntaxWarning > >>> if x := val1 and y == val2: # SyntaxError or SyntaxWarning > >>> if x := val1: # OK > >>> if (x := val1): # OK > > 2) allow := in "while" statements, "if" statements and comprehensions only: > >>> foo(x := 0) # SyntaxError > >>> yield x := 3 # SyntaxError > >>> assert y := 3 # SyntaxError > > 3) (debatable) disallow := if the variable is already defined: > >>> x = 5 > >>> if (x := val): # SyntaxError or SyntaxWarning > > 4) ban "a = (b := c)", "x = a := (b := (c := d))" and similar (they're > just too ugly IMHO) > > Rationale 1 > =========== > > In visual terms assignments in Python have always occurred at the > BEGINNING of the line and always on the most LEFT side: > > >>> foo = fun1() > >>> bar = fun2() > >>> baz = fun3() > > That is where I naturally expect an assignment to be when reading code. My > main concern with PEP-572 is that an assignments can now occur at *any > point* in the line: > > >>> foo = fun1() > >>> bar = fun2() > >>> if foo == val1 and bar == val2 and baz := fun3(): > ... ... > > That forces me to visually scan the whole line horizontally from left to > right 'till its end, looking for possible variables being set. I'm > concerned that I will miss := occurrences because visually they are very > similar to == unless parentheses are made mandatory: > > >>> if foo == val1 and bar == val2 and (baz := fun3()): > ... ... > > Also, in case of multi-line conditionals I have to visually scan the > construct both horizontally AND vertically: > > >>> if (foo == val1 and \ > ... bar == val2 and \ > ... baz := val3): > ... ... > > Again, that is not a place where I would expect to find or look for a > variable assignment. I know I wouldn't like to read or review a code which > does that and I suspect linters will likely end up wanting to emit a > warning in that case (see: https://github.com/PyCQA/pylint/issues/2246). > https://github.com/python/cpython/pull/8116/files avoids using multiple > := per line and that's why the result appears readable enough IMO. > > Rationale 2 > =========== > > PEP-572 states: > > > The := operator may be used directly in a positional function call > argument > > That means allowing: > > >>> foo(x := 0) > > I honestly don't see why anyone would want to call a function AND assign a > variable value at the same time (except in comprehensions). With this in > place I not only have to guard against "if" statements assigning values at > any point in the code, but also function calls, both horizontally and > vertically e.g.: > > >>> foo(some_long_var_name, another_one, x := bar(), > y := fun()) > > To me this looks like the perfect example of where this functionality can > be abused. Also, I'm not clear what PEP-572 intend to do about "all other > places". E.g. should these cases be allowed? (IMO no) > > >>> yield x := 3 > >>> assert y := 3 > > -- > Giampaolo - http://grodola.blogspot.com > > _______________________________________________ > Python-Dev mailing list > Python-Dev@python.org > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > https://mail.python.org/mailman/options/python-dev/guido%40python.org > -- --Guido van Rossum (python.org/~guido)
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com