[Python-Dev] LOAD_NAME & classes
Tim Peters
tim.one@comcast.net
Thu, 25 Apr 2002 02:06:21 -0400
[Scott Gilbert, on Icon]
> A few corrections. New variable names were local by default.
Ack! You're right! Years of stuffing in "local" decls made me forget why
they were recommended to begin with.
> The only way to get a global variable was to make a "global varname"
> statement at the global scope.
The difficulty being-- why explicit "local" was really recommended --that a
new global magically changes every *implicit* local vrbl of the same name
into a global. This bit too when an implicit local happened to have the
same name as a new function added later, because function names are
automatically global. Like:
procedure main()
f()
g()
end
procedure f()
count := 1
while count < 10 do count +:= 1
write(count)
end
procedure g()
write(len([2, 3, 4]) | "oops!")
end
procedure len(x)
return *x
end
That prints
10
3
If you just happen to change the name of the "len" function to "count"
later:
procedure g()
write(count([2, 3, 4]) | "oops!")
end
procedure count(x)
return *x
end
it suddenly prints
10
oops!
instead (the expression
count([2, 3, 4]) | "oops!"
becomes
10([2, 3, 4]) | "oops!"
because the once-local "count" in f is suddenly global, and retains its
value of 10; then 10([2, 3, 4]) fails, and the alternative "oops!" is tried
and succeeds).
In real life these could be an absolute bitch to track down, so I always
used local. Insert
local count
at the top of f and everything's fine again.
> Icon gave you a None-like value, &null, for your variables if you
> hadn't already assigned to them somewhere. So strictly speaking,
> you could read a variable before writing to it, and a declaration (first
> initialization) wasn't necessary the same way it is in Python.
I prefer Python distinguishing between None and unbound too; e.g., I'd much
rather have
x := y
blow up at once if y hasn't been bound than to silently propagate &null (or
a Python None). &null could travel *all over the place* before you finally
hit an expression where it didn't just silently fail (very few things in
Icon raise errors, as the 10([2, 3, 4]) example should have suggested to
onlookers <wink>).
> Using "local x" was strongly recommended because (a) you could use the
> -u switch of icont to warn you when you didn't declare your locals
> (usually from typos),
Unfortunately, -u doesn't complain about the "10 oops!" example above: as
far as it's concerned, all variables were declared in that example.
Fortunately, it does complain about the original way of writing it, because
"count" is undeclared then.
> and (b) in case you forgot that you used the same name as a global
> somewhere else, or more likely you "link"ed with a file that had global
> declarations you weren't aware of.
Like an implicit "import *" in Python -- we're well aware of the dangers of
*that* around here <wink>.
> So it really wasn't so error prone. (Icon's not even close to
> Perl in this regard. :-)
Not for scope rules alone, no, although Perl sticking to explicit "my"
everywhere isn't much worse than Icon sticking to explicit "local"
everywere.