WHAT? Yes that’s what I thought too when I came up with that idea. How am I supposed to implement a service code, like a memory database that holds objects to be fetched by other program parts? Yes at first glance it seems weird, but it can be done.
Think about it: Everywhere we hear the mantra “don’t create functions with side effects!” – And what better side effect is there than a function that modifies a global variable which in turn is used in a lot of other locations? Besides, if you want to use Unit Tests, how do you test this scenario?
So I agree completely with this axiom, that side effects are bad. And the availability of global variables invites the programmer to use them. “Oh just this once, since it’s easier than to redesign this code”. Yes and once more and again and again and before you know it, it’s a common practice.
My solution to this problem is NO GLOBAL VARIABLES PERIOD!
By eliminating them, the language will enforce clean coding by leaving the designer no choice but to have clearly defined Module interfaces.
Variables can only be declared inside a module and are available only inside the module in which they were declared. The can then be passed as actual parameters in a module call and thus be made available to a module, but they don’t outlive the lifetime of the module itself, or in other words, they exist only for as long as the module is running.
This makes Unit Testing a breeze. There are no global variables, there are no C++ objects with state variables, the Module is COMPLETELY defined by it’s actual parameters, NO SIDE EFFECTS AT ALL.
Imagine there is a huge hierarchy of modules which solve a complex problem. There will certainly be the need for something like “permanent variables” for instance a file could be permanently open as a log output. The file handle will then have to be created on the top level of the hierarchy and passed to the lower modules through the parameter interface.
Will this make the interface larger? No doubt. There are ways to keep interfaces neat and clean for instance by creating a data type that combines this handle with other commonly needed data in a record so that the parameter count can be minimized, but these are stylistic questions. I have heard some people argue that a function should never have more than one or two parameters. Obviously that will not be the case here, especially not at higher levels. Lower level Modules will tend to have fewer parameters than higher level ones, but there is nothing wrong with that. It’s just the way things are. If data are needed, they have to be brought to the location where they are needed somehow. Either through the parameter interface or through global variables or object state variables. And since we eliminate the latter two, there is only the Module interface.
I believe this will eliminate a lot of common problems and causes for hard to find bugs.