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 concision. 
* 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.

Style:
* 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 too:
(expression
 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...@gmail.com> wrote:
On 8 May 2018 at 04:19, Brett Cannon <br...@python.org> 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...@gmail.com   |   Brisbane, Australia

_______________________________________________
Python-ideas mailing list
Python...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/




--
--Guido van Rossum (python.org/~guido)