[Python-ideas] Inline assignments using "given" clauses

Neil Girdhar mistersheik at gmail.com
Sat May 12 11:16:07 EDT 2018

I love given compared with := mainly because

Simpler is better than complex:
* given breaks a complex statement into two simpler ones, which is putting 
people off in the simple examples shown here (some people are annoyed by 
the extra characters).  However, when given is used in a list comprehension 
to prevent having to re-express it as a for loop, then two simple 
statements are easier to understand than one complex statement.   This is a 
common difference between code written at programming contests versus code 
written by those same software engineers years later at big companies.  
Code that you write for yourself can be compact because you already 
understand it, but code you write professionally is read many many more 
times than it is written.  Accessibility is much more important than 
* Python has a reputation for being working pseudocode, and given reads 
like pseudocode.  := needs to be deciphered by comparison especially in the 
complicated cases where multiple := operators are used on one line.
* there are no difficult mental questions about evaluation order, e.g., in 
a bracketed expression having multiple assignments.  Similarly, instead of 
(a.b(a) given a = c.d())  do I write (a.b(a := c.d())) or ((a := 
c.d()).b(a)) ?
* it avoids the question of what happens when := is used in a switch:  (a 
if (b := c) else d)   Sometimes you want the assignment to happen 
unconditionally (a if (b:=c) else d) + b; sometimes you don't.  How do you 
force one case or the other?  given makes it obvious by separating 
assignment from the usage of its assignment target.

* it avoids the big style question of when to use and when not to use :=.  
(Even if you ask people not to, people are going to write the 
expression-statement a := b as a synonym for the statement a = b.)
* it looks a lot like the existing Python "for" and "if" clauses, which 
also do in-expression assignments.  This makes formatting the code obvious 
 given a = b)

compared with

expresion (
    a := b
) rest of expression

which quickly gets ugly.

Best, Neil

On Thursday, May 10, 2018 at 9:46:01 AM UTC-4, Guido van Rossum wrote:
> I'm sorry, but unless there's a sudden landslide of support for 'given' in 
> favor of ':=', I'm really not going to consider it.
> I'd pronounce "if (x := y) > 0" as either "if y (assigned to x) is greater 
> than zero" or "if x (assigned from y) is greater than zero".
> On Thu, May 10, 2018 at 6:39 AM, Nick Coghlan <ncog... at gmail.com 
> <javascript:>> wrote:
>> On 8 May 2018 at 04:19, Brett Cannon <br... at python.org <javascript:>> 
>> wrote:
>>> My brain wants to drop the variable name in front of 'given':
>>> if given m = pattern.search(data):
>>> while given m = pattern.search(remaining_data):
>>> Maybe it's because the examples use such a short variable name?
>> Does that change if the condition isn't just "bool(name)"? For example:
>>     if y > 0 given y = f(x):
>>         ...
>> That's the situation where I strongly prefer the postfix operator 
>> spelling, since it's pretty clear how I should pronounce it (i.e. "if y is 
>> greater than zero, given y is set to f-of-x, then ..."). By contrast, while 
>> a variety of  plausible suggestions have been made, I still don't really 
>> know how to pronounce "if (y := f(x)) > 0:)" in a way that's going to be 
>> clear to an English-speaking listener (aside from pronouncing it the same 
>> way as I'd pronounce the version using "given", but that then raises the 
>> question of "Why isn't it written the way it is pronounced?").
>> I do agree with Tim that the name repetition would strongly encourage the 
>> use of short names rather than long ones (since you're always typing them 
>> at least twice), such that we'd probably see code like:
>>     while not probable_prime(n) given (n =
>>                             highbit | randrange(1, highbit, 2)):
>>         pass
>> Rather than the more explicit:
>>     while not probable_prime(candidate) given (candidate =
>>                             highbit | randrange(1, highbit, 2)):
>>         pass
>> However, I'd still consider both of those easier to follow than:
>>     while not probable_prime(candidate := highbit | randrange(1, highbit, 
>> 2)):
>>         pass
>> since it's really unclear to me that "candidate" in the latter form is a 
>> positional argument being bound to a name in the local environment, and 
>> *not* a keyword argument being passed to "probable_prime".
>> I've also been pondering what the given variant might look like as a 
>> generally available postfix operator, rather than being restricted to 
>> if/elif/while clauses, and I think that would have interesting implications 
>> for the flexibility of its usage in comprehensions, since there would now 
>> be *three* places where "given" could appear (as is already the case for 
>> the inline binding operator spelling):
>> - in the result expression
>> - in the iterable expression
>> - in the filter expression
>> That is:
>>     [(x, y, x - y) given y = f(x) for x in data]
>>     [(x, data) for x in data given data = get_data()]
>>     [(x, y, x/y) for x in data if y given y = f(x)]
>> Rather than:
>>     [(x, y := f(x), x - y) for x in data]
>>     [(x, data) for x in data := get_data()]
>>     [(x, y, x/y) for x in data if y := f(x)]
>> Opening it up that way would allow for some odd usages that might need to 
>> be discouraged in PEP 8 (like explicitly preferring "probable_prime(n) 
>> given n = highbit | randrange(1, highbit, 2)" to "probable_prime(n given n 
>> = highbit | randrange(1, highbit, 2))"), but it would probably still be 
>> simpler overall than attempting to restrict the construct purely to 
>> if/elif/while.
>> Even as a generally available postfix keyword, "given" should still be 
>> amenable to the treatment where it could be allowed as a variable name in a 
>> non-operator context (since we don't allow two adjacent expressions to 
>> imply a function call, it's only prefix keywords that have to be disallowed 
>> as names to avoid ambiguity in the parser).
>> Cheers,
>> Nick.
>> -- 
>> Nick Coghlan   |   ncog... at gmail.com <javascript:>   |   Brisbane, 
>> Australia
>> _______________________________________________
>> Python-ideas mailing list
>> Python... at python.org <javascript:>
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
> -- 
> --Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180512/24690a66/attachment-0001.html>

More information about the Python-ideas mailing list