[Python-ideas] If branch merging

Nick Coghlan ncoghlan at gmail.com
Thu Jun 11 02:54:46 CEST 2015

On 10 June 2015 at 10:20, Andrew Barnert <abarnert at yahoo.com> wrote:
> On Jun 9, 2015, at 16:46, Nick Coghlan <ncoghlan at gmail.com> wrote:
>> However if name bindings *didn't* leak out of their containing expression by default, and while/if/elif code generation instead gained machinery to retrieve the name bindings for any named subexpressions in the condition, that would eliminate most of the potentially bizarre edge cases.
> I don't think here's any consistent way to define "containing expression" that makes any sense for while/if statements.

Sure there is. The gist of the basic "no leak" behaviour could be
something like:

1. Any expression containing a named subexpression would automatically
be converted to a lambda expression that is defined and called inline
(expressions that already implicitly define their own scope,
specifically comprehensions and generation expressions, would
terminate the search for the "containing expression" node and allow
this step to be skipped).
2. Any name references from within the expression that are not
references to named subexpressions or comprehension iteration
variables would be converted to parameter names for the implicitly
defined lambda expression, and thus resolved in the containing scope
rather than the nested scope.

In that basic mode, the only thing made available from the implicitly
created scope would be the result of the lambda expression. Something

    x = (250 as a)*a + b

would be equivalent to:

    x= (lambda b: ((250 as a)*a + b))(b)

if/elif/while clauses would define the behaviour of their conditional
expressions slightly differently: for those, the values of any named
subexpressions would also be passed back out, allowing them to be
bound appropriately in the outer scope (requiring compatibility with
class and module namespaces means it wouldn't be possible to use cell
references here).

Whether there should be a separate "bindlocal" statement for lifting
named subexpressions out of an expression and binding them all locally
would be an interesting question - I can't think of a good *use case*
for that, but it would be a good hook for explaining the difference
between the default behaviour of named subexpressions and the variant
used in if/elif/while conditional expressions.

> But "containing _statement_", that's easy.

No, it's not, because statements already contain name binding
operations that persist beyond the scope of the statement. In addition
to actual assignment statements, there are also for loops, with
statements, class definitions and function definitions.

Having the presence of a named subexpression magically change the
scope of the statement level name binding operations wouldn't be
acceptable, and having some name bindings propagate but not others
gets very tricky in the general case. (PEP's 403 and 3150 go into some
of the complexities)


Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-ideas mailing list