closures and dynamic binding

Terry Reedy tjreedy at udel.edu
Mon Sep 29 05:56:02 CEST 2008


Aaron "Castironpi" Brady wrote:
> On Sep 28, 4:47 pm, Terry Reedy <tjre... at udel.edu> wrote:
>> Aaron "Castironpi" Brady wrote:

>>>>>> inner = lambda: n
>> when inner is actually compiled outside of outer, it is no longer a
>> closure over outer's 'n' and 'n' will be looked for in globals instead.
>>
>>>>>> outer = lambda n: inner
>>>>>> outer(0)
>>> <function <lambda> at 0x00A01170>
>>>>>> a=outer(0)
>>>>>> b=outer(1)
>>>>>> a()
>>> Traceback (most recent call last):
>>>   File "<stdin>", line 1, in <module>
>>>   File "<stdin>", line 1, in <lambda>
>>> NameError: global name 'n' is not defined
>>> Why doesn't 'inner' know it's been used in two different scopes, and
>>> look up 'n' based on the one it's in?
>> That would be dynamic rather than lexical scoping.
> 
> I couldn't find how those apply on the wikipedia website.  It says:
> "dynamic scoping can be dangerous and almost no modern languages use
> it", but it sounded like that was what closures use.  Or maybe it was
> what 'inner' in Steven's example would use.  I'm confused.

As I understand it, partly from postings here years ago...

Lexical: The namespace scope of 'n' in inner is determined by where 
inner is located in the code -- where is is compiled.  This is Python 
(and nearly all modern languages).  Even without closures, the global 
scope of a function is the module it is defined in.

Dynamic: The namespace scope of 'n' in inner, how it is looked up, is 
determined by where inner is called from. This is what you seemed to be 
suggesting -- look up 'n' based on the scope it is *used* in.

Even without closures, dynamic scoping would be if the global scope of a 
function for each call were the module it is called in.

tjr




More information about the Python-list mailing list