[Python-ideas] For-loop variable scope: simultaneous possession and ingestion of cake

Terry Reedy tjreedy at udel.edu
Mon Oct 6 19:07:47 CEST 2008

Carl Johnson wrote:
> On 2008/10/05, at 9:08 pm, Bruce Leban wrote:
>> Consider this:
>> i = 0
>> def f():
>>     global i
>>     i += 1
>>     return lambda: immanentize 1
>> when does immanentize get evaluated? when f is defined or when the 
>> lambda is evaluated? From what you wrote, it sounds like you think 
>> it's evaluated when f is defined. OK, so how do I get the equivalent of:
>> def f():
>>     global i
>>     i += 1
>>     lambda i=i: i
>> using immanentize?
> OK, now I see what you're getting at. That makes more sense. The 
> question is how do we deal with nested scopes with an immanentize in the 
> innermost scope. Off the top of my head, I think the most sensible way 
> to do it is that the immanentization happens when the innermost scope 
> it's in is turned into a real function by the next scope out. But I may 
> need to do some more thinking about what would happen here:
> def f():
>     xs = []
>     for i in range(10):
>         xs.append(lambda: immanentize i)
>     return xs
> Clearly, we want this immanentize to be held off on until f is finally 
> called.

Actually, until the lambda is executed.  What you are saying is that you
want immanetized expressions to be evaluated as the same time the
default arg expressions are, which is when the def/lambda is executed to
create a function object.  The only difference between them and default
args is that they could not be replaced by the function call, which is
precise the problem with default pseudoargs. Call them constants defined
at definition time rather than as compilation time.

Do you want the constants to be names or anonymous  -- which is to say,
would there values appear in locals()?  If named, their expressions
could/should appear in the header with a syntax similar to but somehow
different from default args.  A possibility:
    ...lambda $i=i: i

To implement this, the constants would have to be stored in the function
object and not in the compiled code object that is shared by all
functions generated by repeated execution of the definition.

> The more I think about it, the more I realize that an 
> immanentize always needs to be inside of some kind of function 
> declaration, whether it's a def or a lambda or (maybe) a class (but I 
> haven't thought about the details of that yet…), and evaluated just one 
> level "up" from that.

Immanetize would have be a no-op at top-level, as is global.  Whether it
should be illegal at top-level or not is a different questions.  Global
is legal even though it is redundant.

If the constants are named and their definitions are in the function
header, there would be no question of top-level appearance.

Terry Jan Reedy

More information about the Python-ideas mailing list