Any functional programming bunny will tell you that “reducing the amount of state” in a program is something which fpl’s are good at. When you’ve got first-class functions at your disposal, you don’t need loop counters any more, When you’ve got discriminated unions (variants in ocaml, very different from variants in VB!) you tend not to need so many ‘flag’ variables in your programs. Removing all these variables from your code makes it easier to read.
Back in the C++ world, I’m a big fan of limiting the scope of variables as much as possible. If you introduce a temporary variable which only gets used in the very next line, then surround the whole thing with braces so the variable immediately goes out of scope.
{
int tmp;
sscanf(buffer, "%d", &tmp);
counter += tmp;
}
This makes it clear that ‘tmp’ is introduce, used, and disposed of in these three lines. There’s no chance it’ll be used later. Of course, it’s possible this is a sign that you should factor out a smaller function, but not always.
Now let’s move from the function level up to the class level. Some object data members are definitely part of the object’s state. You would expect a BankAccount object to have a ‘balance’ data member. Some object data members are there for efficiency. For example, an object might maintain a single StringBuffer for use by it’s methods, rather than have methods repeatedly construct/destruct one each time they needed it. Finally, some object data members are used as communication between different member functions. They might only be set in method foo() and only read in method bar(), but your only option is to make them visible to all the class methods.
So, to bring this rambling to a point; If you need a bit of data to have scope bigger than the local function, your next step up is object scope. While that’s a whole lot better than making it a global variable, I wonder if there’s useful extra scoping levels which you could add with language support.
For example, “this data member is only visible to methods foo() and bar()”. However, maybe this is just a sign that foo(), bar() and the data member should be a subobject.
Another example: “this data member is only relevant between calls to Start() and Stop()”. Well, a Maybe<> type gets you part way there by communicating “this values isn’t always present” but there’s no way to communicate /when/ it’s going to be valid to someone reading the code, short of a comment. This isn’t something you could check for statically, obviously.
Actually, a better example would be “this data member is only relevant after someone has called Initialize()”. If you could express that in the language, then you’d probably save an awful lot of manual “if we’re uninitialized, print an error” checking.
This is at best a half-baked idea. I know there are reasonable ways of doing this all in code just now. I’m interested to see if there’s better ways of doing this. Ways which communicate intent better than hand-coded checks.