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

Jan Kanis jan.kanis at phil.uu.nl
Mon Oct 6 12:45:27 CEST 2008


Hmm, it's a nice new keyword doing interesting stuff, but I would
prefer solving the scoping problems (I do consider it a problem)
without introducing new keywords and such.
But the right time to do the imannentization would be as late as
possible, when the innermost scope is turned into a function by its
parent scope, like Carl proposes.


In Lisp, '(blah) can be evaluated by doing (eval '(blah)). In order to
'imannentize' the value of some variable into a quoted piece of code,
you can do two things. Since code is just lists, you can use the
standard list slice and dice functions. They als have some syntax for
this which I think goes like this:

`(blah foo ,bar baz)

This returns a list that looks like this: (blah foo <the value of bar
at the time the list was created> baz)

But I don't think we should go all the way to quasiquoting (as this is
called) unless we want to support full macros, and that isn't going to
get past Guido.

Jan


2008/10/6 Carl Johnson <carl at carlsensei.com>:
>
> 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. 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.
>
>>>> def side_effector():
> ...     r = random.randint(0, 10)
> ...     print(r)
> ...     return r
> ...
>>>> def f():
> ...     def g():
> ...         return immanentize side_effector()
> ...     return (immanentize side_effector()), g
> 5
>>>> a, b = f()
> 2
>>>> a
> 5
>>>> b()
> 2
>>>> b()
> 2
>>>> a, b = f()
> 3
>>>> a
> 5
>>>> b()
> 3
>
> In which case, for your original example, the immanentization wouldn't
> happen until f is called.
>
>>>> i = 0
>>>> def f():
> ...     global i
> ...     i += 1
> ...     return lambda: immanentize i
> ...
>>>> f()
> <function <lambda> at 0x3a57970>
>>>> g = _
>>>> f()
> <function <lambda> at 0x3a58240>
>>>> k = _
>>>> k()
> 2
>>>> g()
> 1
>
> I think that makes sense, right? :/
>
> Does anyone know how Lisp does this? I know that they write '(blah) to delay
> evaluation, but what do they do when they want to force evaluation someplace
> in the middle of a non-evaluated list?
>
> -- Carl
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>
>


More information about the Python-ideas mailing list