PyMyth: Global variables are evil... WRONG!

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Nov 15 03:19:01 EST 2013


On Thu, 14 Nov 2013 09:26:18 -0800, Rick Johnson wrote:

> On Wednesday, November 13, 2013 11:50:40 PM UTC-6, Steven D'Aprano
> wrote:
[...]
>> of course, but that in general *its too damn hard* for human
>> programmers to write good, reliable, maintainable, correct (i.e.
>> bug-free) code using process-wide global variables.
> 
> Complete FUD. Maybe for you. Not for me.

I wasn't taking about genius programmers like you Rick, that would be 
silly. I'm talking about mere mortals like the rest of us.


>> Global variables are the spaghetti code of namespacing -- everything is
>> mixed up together in one big tangled mess.
> 
> It's a tangled mess if you design it to be a tangled mess.

Nobody sets out to *design* a tangled mess. What normally happens is that 
a tangled mess is the result of *lack of design*.


>> The more global variables you have, the worse the tangle.
> 
> Complete illogic.
> 
> What if all the globals are only accessed and never mutated? 

Then they aren't global VARIABLES. You'll note that I was very careful to 
refer to "variables".

Read-only global constants don't increase coupling to anywhere near the 
same degree as writable global variables. As such, they're far less 
harmful.

Of course, there is still some degree of coupling -- suppose one chunk of 
code wants a global constant X=23 and another chunk of code wants a 
global constant X=42? But such issues are generally easy to spot and easy 
to fix.


>> One or two is not too bad. With good conventions for encapsulation to
>> limit the amount of tangled, coupled code (e.g. naming conventions, or
>> limiting globals to a single module at a time by default) the amount of
>> harm can be reduced to manageable levels.
> 
>> SO now your agreeing that globals are not evil again.

In this thread, I have never called global variables "evil". I have 
called them *harmful*, and tried to make it clear that harm is not a 
dichotomy "zero harm" versus "infinite harm", but a matter of degree. I 
stand by that.


>> Global variables increases coupling between distant parts of the code.
>> I remember a nasty little bug in Windows where removing IE stopped
>> copy-and- paste from working everywhere. That's a sign of excess
>> coupling between code -- there's no logical reason why removing a web
>> browser should cause copying text in Notepad to fail.
> 
> Do you have link describing this bug? I am not aware of such bug ,but
> uh, i would not at all be surprised that windows could break from
> removing that gawd awful IE.
> 
> Come to think of it, i'll bet it's not even a bug at all, but a feature
> to prevent "wise users" from removing IE, thereby maintaining IE's
> footprint in the wild.

Heh. 

Sorry, I can't find the link. It was well over five years ago, probably 
more like ten. But whether deliberate or accidental, that's the sort of 
thing I mean when I talk about excessive coupling. Note that coupling in 
and of itself is not harmful -- for example, you want the brake pedal of 
your car to be coupled to the brakes. Excess and inappropriate coupling 
is harmful: pressing the brake pedal shouldn't turn off the headlights, 
nor should a blown brake light stop the brakes from working. Hence we try 
to minimize coupling to only those areas that actually need them.

With physical devices, that's often -- not always -- trivial. The 
constraints of physical matter makes it natural to keep things loosely 
coupled. When you're building a car, the hard part is getting the 
coupling that you actually do want, not avoiding coupling you don't. 
Physical devices are, as a general rule, inherently and naturally 
encapsulated: the brake pedal is physically uncoupled from the brakes 
unless you literally connect them with steel cables and wires. Your 
fridge isn't connected to anything except the power supply, so it 
physically can't flush the toilet. Since the toilet and fridge are made 
in different factories and installed by different people, there's no 
motivation to couple them. Even if some bright spark decided that since 
opening the fridge door turns on the fridge light, and pressing the 
toilet button opens the cistern value, the two operations are related and 
therefore "Don't Repeat Yourself" applies and there should be a single 
mechanism to do both, it is impractical to build such a system. (And 
thank goodness. But just wait until we have internet-enabled fridges and 
toilets...)

But with software, coupling is *easy*. By default, code in a single 
process is completely coupled. Think of a chunk of machine code running 
in a single piece of memory. We have to build in our own conventions for 
decoupling code: subroutines, local variables, objects, modular code, and 
so forth. Physical objects are inherently decoupled. Code is inherently 
coupled, and we need conventions to decouple it. One of those conventions 
is to prefer local variables to global variables, and another is to limit 
the scope of global variables to per module rather than process-wide.



-- 
Steven



More information about the Python-list mailing list