[Python-Dev] just trying to catch up with the semantic

Jeremy Hylton jeremy@alum.mit.edu
Thu, 1 Mar 2001 11:10:28 -0500 (EST)


I'm not convinced there is a natural meaning for this, nor am I
certain that was is now implemented is the least unnatural meaning.

    from __future__ import nested_scopes
    x=7
    def f():
        x=1
        def g():
            global x
            def i():
                def h():
                    return x
                return h()
            return i()
        return g()
    
    print f()
    print x

prints:
    7
    7

I think the chief question is what 'global x' means without any other
reference to x in the same code block.  The other issue is whether a
global statement is a name binding operation of sorts.

If we had
        def g():
	    x = 2            # instead of global
            def i():
                def h():
                    return x
                return h()
            return i()

It is clear that x in h uses the binding introduced in g.

        def g():
            global x
	    x = 2
            def i():
                def h():
                    return x
                return h()
            return i()

Now that x is declared global, should the binding for x in g be
visible in h?  I think it should, because the alternative would be
more confusing.

    def f():
        x = 3
        def g():
            global x
	    x = 2
            def i():
                def h():
                    return x
                return h()
            return i()

If global x meant that the binding for x wasn't visible in nested
scopes, then h would use the binding for x introduced in f.  This is
confusing, because visual inspection shows that the nearest block with
an assignment to x is g.  (You might overlook the global x statement.)

The rule currently implemented is to use the binding introduced in the
nearest enclosing scope.  If the binding happens to be between the
name and the global namespace, that is the binding that is used.

Samuele noted that he thinks the most natural semantics would be for
global to extend into nested scopes.  I think this would be confusing
-- or at least I'm confused <wink>.  

        def g():
            global x
	    x = 2
            def i():
                def h():
                    x = 10
                    return x
                return h()
            return i()

In this case, he suggests that the assignment in h should affect the
global x.  I think this is incorrect because enclosing scopes should
only have an effect when variables are free.  By the normal Python
rules, x is not free in h because there is an assignment to x; x is
just a local.

Jeremy