[Python-ideas] A real life example of "given"

Steven D'Aprano steve at pearwood.info
Thu May 31 08:53:15 EDT 2018


On Thu, May 31, 2018 at 02:22:21PM +0200, Peter O'Connor wrote:

> There seems to be a lot of controversy about updating variables defined
> outside a comprehension within a comprehension.  Seems like it could lead
> to a lot of bugs and unintended consequences, and that it's safer to not
> allow side-effects of comprehensions.

Gosh, you mean that a feature intended to have side-effects might have 
side-effects? Who would have predicted that! *wink*

I have to keep pointing this out, because critics keep refusing to 
acknowledge this point: one of the major motivating use-cases of 
assignment expressions specifically relies on the ability to update a 
local variable from inside a comprehension. If not for that use-case, we 
probably wouldn't be having this discussion at all.

I think it ought to take more than "controversy" to eliminate that 
use-case from consideration. It ought to take a good demonstration that 
this is a real, not just theoretical, problem, that it *encourages* bugs 
not just allows them. *Any* use of variables can "lead to a lot of bugs 
and unintended consequences" (just ask functional programmers). Yes, it 
can, but it usually doesn't.

Bottom line is, if you think it is okay that the following assignment to 
x affects the local scope:

    results = []
    for a in seq:
        # using "given" to avoid arguments about :=
        y = (x given x = a)+1  
        results.append(y)
    assert "x" in locals()

but then worry that changing the loop to a comprehension:

    results = [(x given x = a)+1 for a in seq]
    assert "x" in locals()

will be a problem, then I think you are applying an unreasonably strict 
standard of functional purity towards comprehensions, one which is not 
justified by Python's consenting adults approach to side-effects or the 
fact that comprehensions can already have side-effects.

(Sorry Nick!)

[Aside: yes, I realise the assertions will fail if seq is empty. It's 
just an illustration, not production code.]



-- 
Steve


More information about the Python-ideas mailing list