[Python-Dev] let's not stretch a keyword's use unreasonably, _please_...

Alex Martelli aleaxit at yahoo.com
Wed Oct 22 12:11:37 EDT 2003


I'm traveling, but i did manage to briefly peek at python-dev -- and,
with some luck, I think i'll manage to post from here too.  It's
probably gonna be the weekend before I get mail access again, but,
in the meantime...:

I think we're trying to stretch the meaning of a keyword, "global"
(that wasn't a particularly appropriate one for Python anyway, as
opposed to ABC), "beyond reason".  Yes, the temptation is huge,
because adding a keyword is problematic.  But this is like C's
extending "static" to mean "private to this module as opposed to
visible from other modules too" and later C++ further stretching it
to mean "pertaining to the class rather than to the instance".

Seriously, I weep inside whenever I have to explain "staticmethod"
in terms of "once upon a time, there was a language (which has just
about nothing to do with Python) which stretched the meaning of a
word, which an older language had already stretched for a vaguely
related purpose, and ..." :-(

Well, nothing we can do about THAT -- that particular abuse of
"static" is widely enough engrained in too many _programmers'_
minds, so newbies will just have to put up with it.

But, "global" _isn't_ similarly engrained.  It sits oddly in
Python -- a statement that doesn't actually DO things, but rather
"flags" something for the compiler's benefit; in other words,
_a declaration_ -- the one and only (expletive deleted) declaration
we have in Python, though we call it "a statement" probably in
an attempt at decency:-).  I've seen it called "a declarative
statement" on this thread, which is something of an oxymoron to
me -- statements DO things.  All but "global", that is.

And it *rubs in* the "compile-time" vs "runtime" distinction
that Python is mostly SO good at seamlessly hiding...!

And all for what purpose?  To let that one particular case
of "assigment to bare name" actually mean setattr on some
object (the current module) "blackmagically".  I've seen it
argued on this thread that "variables in a module and
attributes in an object are different things" -- but they
*AREN'T*!  Just like, say, in a class.

Inside a class C's body ("toplevel" in it, not nested inside
a def &c) I can write
    x = 23
and it means C.x = 23 (for a normal metaclass).  Once the
class object C is created, if I want to tweak that attribute
of C I have to write e.g. C.x = 42 after getting ahold of
some reference to C (by its name, or say in a method of C by
self.__class__.x = 42, etc).

Inside a module M's body ("toplevel" in it, not nested inside
a def &c) I can write
    x = 23
and it means M.x = 23 (unconditionally).  Once the module
object M is created, if I want to tweak that attribute
of M I have to write e.g. M.x = 42 after getting ahold of
some reference to M (say by an "import M", or say in a function
of M by sys.modules[__name__].x = 42, etc).

*OR* in the second case I can alternatively use the magical
"compile-time declarative statement" ``global x'' -- a weird
"special case" with a weird keyword going with it.  Why?
The two cases aren't all that different; bright learners catch
them on to them most easily when I draw the parallels explicitly
(before going on to explain the differences, of course).


If "assigning to bare names not in the current scope" _must_
be supported by a dedicated keyword, I think that keyword
should be 'scope'.  NOT 'global'.  Let's not do the "see how
far we can stretch 'static' and then some" gig, please...

Alternatively, assigning to an attribute of some particular
object still feels a better approach to me -- no new kwd,
no stretching of bad old ones, actually a chance to let bad
old 'global' fade slowly into the sunset.  If there's any
chance to salvage THAT approach -- if it only needs a good
neat syntax to get that "particular object" -- I'll be glad
to participate in brainstorming to find it.  But before we
spend energy on that, I'd like to know it's not sure to be
wasted, because it just 'must' be a keyword; this subdebate
is warranted only if it's _conceivable_ that attribute
assignment be again demeed acceptable for this purpose.

If it HAS to be a keyword, I think it should be 'scope' AND
it should not be a STATEMENT but rather an "operator".
E.g., a "bare name" COULD be "x scope foo" or "(x in
module scope)" or some such construct (I think it could
syntactically resemble attribute assignment and that would
be USEFUL, e.g. scope(foo).x, even if scope was not a
function but a keyword).  But _this_ subdebate, I think, is
warranted only if it's _conceivable_ that a keyword could
be added for this (be it 'scope' or something even better
that I haven't thought of).

If both conditions fail -- it MUST be a keyword, and that
keyword MUST be 'global' no matter how horrid that is,
then once that is etched in stone I don't think there is
much worth debating, because I don't think the result can
be decent -- it seems an overconstrained system.  So, in
just the spirit of "print>>bah, x", I would suggest:

    global>>outer, x

There!  What could be better?-)


Alex




More information about the Python-Dev mailing list