[Python-ideas] If branch merging
Steven D'Aprano
steve at pearwood.info
Mon Jun 8 14:12:28 CEST 2015
On Mon, Jun 08, 2015 at 04:24:33AM -0700, Andrew Barnert via Python-ideas wrote:
[...]
> > For if/elif clauses and while loops, the leaking would be a desired
> > feature in order to make the subexpression available for use inside
> > the following suite body.
>
> Except it would also make the subexpression available for use _after_
> the suite body. And it would give you a way to accidentally replace
> rather than shadow a variable from earlier in the function. So it
> really is just as bad as any other assignment or other mutation inside
> a condition.
I don't know why you think this will be a bad thing. Or rather, even if
it is a bad thing, it's the Python Way. Apart from classes and functions
themselves, indented blocks are *not* new scopes as they may be in some
other languages. They are part of the existing scope, and the issues you
raise above are already true today:
x = 1
if some_condition():
x = 2 # replaces, rather than shadow, the earlier x
y = 3 # y may be available for use after the suite body
So I don't see the following as any more of a problem:
x = 1
if (some_condition() as x) or (another_condition() as y):
...
# x is replaced, and y is available
The solution to replacing a variable is, use another name. And if you
really care about y escaping from the if-block, just use del y at the
end of the block. (I can't imagine why anyone would bother.)
[...]
> > The other possibility that comes to mind is to ask the question: "What
> > happens when a named subexpression appears as part of an argument list
> > to a function call, or as part of a subscript operation, or as part of
> > a container display?", as in:
> >
> > x = func(b if (a.b as b) else a.c)
> > x = y[b if (a.b as b) else a.c]
> > x = (b if (a.b as b) else a.c),
> > x = [b if (a.b as b) else a.c]
> > x = {b if (a.b as b) else a.c}
> > x = {'k': b if (a.b as b) else a.c}
> >
> > Having *those* subexpressions leak seems highly questionable,
I agree with that in regard to the function call. It just feels wrong
and icky for a binding to occur inside a function call like that. But
I don't think I agree with respect to the rest. To answer Andrew's later
question:
> What does "x[(a.b as b)] = b" mean
surely it simply means the same as:
b = a.b
x[b] = b
Now we could apply the same logic to a function call:
# func(a.b as b)
b = a.b
func(b)
but I think the reason this feels wrong for function calls is that it
looks like the "as b" binding should be inside the function's scope
rather than in the caller's scope. (At least that's what it looks like
to me.) But that doesn't apply to the others. (At least for me.)
But frankly, I think I would prefer to have b escape from the function
call than to have to deal with a bunch of obscure, complicated and
unintuitive "as" scoping rules. Simplicity and predictability counts for
a lot.
--
Steve
More information about the Python-ideas
mailing list