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

Nick Coghlan ncoghlan at gmail.com
Thu May 10 06:39:47 EDT 2018


On 8 May 2018 at 04:19, Brett Cannon <brett at 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   |   ncoghlan at gmail.com   |   Brisbane, Australia
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180510/8612b3b2/attachment-0001.html>


More information about the Python-ideas mailing list