Replacement for keyword 'global' good idea? (e.g. 'modulescope'or 'module' better?)

Bengt Richter bokr at oz.net
Sun Aug 7 23:46:32 CEST 2005


On Sat, 6 Aug 2005 19:28:13 -0400, "Terry Reedy" <tjreedy at udel.edu> wrote:

>
>"Paolino" <paolo_veronelli at tiscali.it> wrote in message 
>news:42F4F2D3.80804 at tiscali.it...
>> seberino at spawar.navy.mil wrote:
>> I don't think the global keyword is useful actually.
>> What's so special in a module nemespace to be priviledged like that.
>
>The specialness of globals and locals was part of Python's original simple 
>namespace design, and is still reflected in exec statements and eval 
>functions, as well as in nested functions.
>
Ok ;-) But that's historical, and tells us something about how we got to the status quo.
ISTM someone wants to discuss possibilities for the future (unless they are just complaining ;-)

>> The point IMO is accessing names defined somewhere in the enclosing
>> namespaces.
>
>Accessing such names is already possible, even *after* the outer function 
>returns and the rest of its execution context is deleted.
>
>> def enclosing():
>>   var=2
>>   def enclosed():
>>     outer var=4
>
>This is rebinding, rather than merely accessing.  Similar, but even more 
>problematical would be initial binding in outer from inner:
>
>def enclosing():
>    def enclosed():
>        outer var = 4
>
>> this is the base of something useful.
>
>Actually, it is the reinvention of classes:
>
>class enclosing(object):
>    def __init__(self):
>        self.var = 2
>    def enclosed(self):
>        self.var = 4
>
>There was a long discussion on the pydev list a couple of years ago re 
>adding rebinding in addition to access (of outer variables).  I think, in 
>the end, Guido concluded that there was no compelling reason, as of then, 
>to add another general mechanism for private, sharable, rebindable 
>variables.
>
>> I think there is only one or none possible solution to an outer statement
>
>There were lots of proposals for both the exact syntax and semantics of 
>outer binding/rebinding.
>
No doubt ;-)
It might be interesting to compare attribute names with bare names. For attributes
we also have a legacy from the historical evolution of current functionaly. E.g.,
classic vs new classes, descriptors, and most relevenat to the current discussion,
mro and super.

Bare names do not (yet ;-) have an explicit "nro" (name resolution order), and there
is no "super" for names (though someone recently proposed an "unshadow" operator here
on c.l.p, so the subject is alive ;-)

Nor do we have any correspondence for bare names analogous to

    setattr(obj, "name", value) <=> obj.name = value

e.g.,

    setname(<namespace_selection>, "name", value)

There is nowhere near the kind of control the programmer has over attribute namespace
use for bare-name use, even though by various means we are able to select from a limited
set of namespaces. (BTW, if <namespace_selection> were a call to a suitable builtin function
that could return objects whose attribute namespace were the desired name space, then setname
could be effected with setattr, e.g.,

    setattr(get_ns_obj(), "name", value)    # name = value (defaulting to local, same as get_ns_obj(0))
    setattr(get_ns_obj(1), "name", value)   # name = value (in lexically immediately (1) enclosing scope)
    setattr(get_ns_obj(-1), "name", value)  # name = value (in global module scope)
)  

I am thinking that there is a subliminal discussion under a layer of red herrings ;-)
I refer to the subject of unification/generalizing/orthogonalizing by removing special
legacy restrictions (or not introducing special restrictions in a new feature).

E.g., recently decorators were introduced, and part of the discussion (which became explicit ;-)
was whether to allow the expression following the '@' to be a fully general expression, or
whether to restrict it to names, dotted names, and function calls. The latter won out.

Some regard this kind of restriction as paternalistic, and protest that "we are adults here"
(even though we are not all, and we others not all the time ;-)

The BDFL has introduced many new ideas, yet has retained or introduced restrictions on fully
orthogonal functionality that might otherwise be allowed if e.g. names in certain contexts
were allowed to be full expressions. It goes the other way too. IIRC the list of bases for
a class will be allowed to be an empty "()" soon.

Bottom line, I think Python is eminently usable and very pleasant to use, but I think bare name
mechanisms could be improved.

<another HOTTOMH idea ;-)>
What about more namespace control in the definition of functions, along the lines of
"nro" for bare name lookup in the function body? This could be in the form of a sequence
of ordinary objects whose attribute name spaces should be searched before looking in globals().
Also using := rather than = to override local namespace binding with extended name space lookup,
e.g., (discuss **=<name space object sequence> syntax later ;-)

    def fun(a, b=2, *args, **kw, **=(nso, nso2, etc)):
       print x  # looks for local x, nso.x, nso2.x, etc.x, and then globals()['x']
                # i.e., not a used-before-bound error if **= spec exists
       x = 123  # binds local x in any case
       print x  # finds the local x first
       del x    # unshadow **= namespace sequence
       x := 456 # not local binding unless pre-existing, but if so rebind.
                # Also rebind if found in enclosing closure scope, BTW.
                # Otherwise find the first object nsofound with x attr in **= object attribute name space sequence,
                # and then do nsofound.x=456 -- where x could be a normal property defined by type(nsofound)

The property possibility should be interesting ;-)

</another>

Be kind, I've suggested := for find-and-rebind before, but I haven't thought very far about this combination
with extended function namespace ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list