41

So, I am having to deal with seemingly archiac language (called PowerOn) where I have a main method, a few datatypes to define variables with, and has the ability to have sub-procedures (essentially void methods) that does not return a type nor accepts any arguements. The problem here is that EVERYTHING is global. I've read of these type of languages, but most books take the aproach "Ok, we use to use a horse and cariage, but now, here's a car so let's learn how to work on THAT!" We will NEVER relive those days". I have to admit, the mind is struggling to think outside of scope and extent.

Well here I am. I am trying to figure out how to best manage nothing but global variables across several open methods. Yep, even iterators for for loops have to be defined globaly, which I find myself recycling in different parts of my code.

My Question: for those that have this type experience, how did programmers deal with a large amount of variables in a global playing field? I have feeling it just became a mental juggling trick, but I would be interested to know if there were any known aproaches.

15
  • 71
    They prayed a lot. Commented Oct 23, 2012 at 16:21
  • 15
    I can imagine a lot of insane variable names that approxomated scope - bob_dog_fur_colour etc... to try and reduce the chance of hitting the same names.
    – Latty
    Commented Oct 23, 2012 at 16:23
  • 12
    They wrote programs that were smaller in scope, and they h a lot of bugs. Commented Oct 23, 2012 at 16:25
  • 13
    @Lattyware, actually back in the elder days you were very limited as to how descriptive you could make your variable names. Some languages only allowed 1 or 2 character variable names, others allowed you as many as 8. It sucked, but we didn't know how much it sucked back then. It did let the compiler squeeze into a limited amount of memory. Commented Oct 23, 2012 at 16:30
  • 18
    they invented better programming languages ...
    – wim
    Commented Oct 24, 2012 at 0:43

9 Answers 9

45

You'll need some kind of mental bookkeeping tricks (naming conventions, etc) in order to keep it straight. Also, document, document, document. Since all variables are globals, have a single document with all of them listed, if you can.

Try to have a small number of variables that you always use for temporaries, and remember that THEY ARE TEMPORARY. By constantly re-using the same ones, you'll get into the habit of keeping track of where they are valid or not.

Also, you want to look at the documentation and make sure you know how long variable names can be, and how many characters are actually unique. I know NOTHING about PowerOn, but if it's archaic enough to have only global scope, then it's possible that it's got a limited uniqueness length on identifiers.

I've seen things before with long identifiers, but whose identifiers were only unique in the first 8 characters. So you could have RonnyRayGun and RonnyRayBlaster and they are actually the SAME variable. In such cases I recommend keeping variable names under the 'unique' limit so that you're less likely to accidentally collide.

1
  • 5
    +1: When writing assembly I usually face some of the same problems in that if I name the registers, the names are global (I face the added problem that even if I create more names, I don't get more registers, but that's not relevant here). Having a few registers dedicated for temporary values really helps keeping down the number of variables created which makes it easier to keep everything in your head. Documenting which variables each function will use (most important is which it will modify) helps getting the global picture right.
    – Leo
    Commented Oct 24, 2012 at 7:10
53

Data dictionary.

In a central repository (usually the lead programmer's office), there was a looseleaf binder, that contained one page for each and every global variable. The page gave the name, its definition, its purpose, and which routines set or used it.

Early embedded systems with microscopic RAM had a similar problem, and a similar solution. The lead programmer maintained the master RAM map, down to the individual bytes, showing what RAM was used by which modules for which purposes. Programmers who needed a dedicated RAM allocation went to the lead programmer, who, after discussing the matter, made the appropriate notebook entry and gave the guy his RAM. (You did not want to be in the shoes of the programmer who took a RAM byte without clearing it with the lead programmer. Trust me on this.)

This problem also showed up when programmers had to build large systems in early versions of BASIC. It showed up for me personally while using a very primitive "database" manager called Info (product of Henco, Inc. of New Jersey - HOPEFULLY now long gone!). Both of those languages had a very limited variable name vocabulary.

3
  • I'm in a very similar situaion with it being more of a "database" manager where the language directly interfaces with database, along some programming like functionality. This is very helpful Commented Oct 23, 2012 at 16:57
  • 1
    That reminds me of back when I was learning BASIC and variables couldn't have names longer than two characters, and keeping track of them in a sizable program... Commented Oct 23, 2012 at 18:56
  • @KevinRubin, don't remind me. Ah feel yore pain, as Bill Clinton used to say... Commented Aug 20, 2013 at 21:14
8

The rise of programming languages with block scope coincided with the advent of faster, larger machines, and that is no coincidence. Early computers had RAM measured in MB, kB or even in bytes; there was simply no opportunity to even have so many variables that they would be confused when the program got large, because programs never got that large. Advances in programming languages were usually made when people recognized that their old programming habits didn't scale up when the arena got much larger; block scope was invented as a mechanism of defense for programmers against their own limited memory.

Computing was also a much more rarefied and exotic activity when comoputers were fantastically expensive, and it may well be that only particularly mathematically inclined and ingenious individuals became programmers in the first place (although such comparisons are impractical to test, and certainly politically incendiary). In the early days, software was usually shipped for free with a computer in order to convince people to buy it in the first place; the thought that institutional users would even attempt to write their own programs was unknown at first.

4
  • How far back are you talking about. I have personally seen a couple minicomputers from the early 80's that had a 'datapool' (ie a global variable listing) containing in excess of 60K labels. Commented Oct 24, 2012 at 0:18
  • -1: In the early days you not only paid a monthly rental to have access to a computer, you paid for CPU cycles and memory used by you program. Software was far from free, and running the software even less so.
    – mattnz
    Commented Oct 24, 2012 at 2:36
  • 1
    @mattnz: Back some time ago, software was often bundled, which is somewhat different from free. Typically, an enterprise that needed a computer would buy or rent one, and not pay for running the machine, although individual users would often be charged for that. I'm also puzzled by the OP's claim that people weren't expected to write their own software, because that certainly wasn't my experience. If you could afford a computer, you could afford a development staff, and there really wasn't much canned software out there. Commented Oct 24, 2012 at 16:51
  • The problems with single-scope programming were recognized quite early, long before computers had multiple megabytes of memory. ALGOL, the first language with lexical scope, appeared in 1958. Commented Oct 25, 2012 at 16:31
4

My gosh, that is many years ago (bubbling memories :)).

I don't know the language you refer to, but in general we adapted to what we had. It wasn't really a huge issue. You needed to pay more attention to var names which often contained (in short form, in those days number of bytes was precious) reference to sub or function, like mIORead1 if you had a handler to read data from a file 1, or you had various counter vars like i, j, k etc. which by your own system you knew what they were for, if they could be reused and so forth. It was more hardcore (no helmets or gloves back then) :-)

3

This is pretty similar to PLC programming, though modern PLCs now allow you to have "tags" (aka variables) that are local to a program. Still, a lot of people just program using all global tags.

I've found, if you're going to do that, you need to use a structured naming convention. For instance: Motor1_DriveContactor_Run. If your language happens to support structures (sometimes known as user-defined types) then you can also use those to create a structured data hierarchy, such as: Motor[1].DriveContactor.Run.

That keeps everything organized, and usually the intellisense is decent enough to help you along.

2

I actually learned to program in a language called Authorware, where everything was global. Luckily, it did have Arrays and after a certain point something called Lists, which were similar to generic objects.

An Authorware program actually had a physical structure (Authorware was based on a flow-chart metaphor), and its scripting language was based on old-style Pascal. What we did was to relate the physical structure to the indices in an Array, and often the Array indices would contain Lists that we'd treat as a local object for the physical piece we were using.

Authorware was designed for eLearning, so one of the icons we had was a Page. Pages would be attached to a Framework. So, for Page 1, we'd look in some Array at index 1 (Authorware was 1-indexed) and pull out the data for that page, which would be stored a List that would act as a pseudo-object. The Page would then have logic that would pull out the "properties" of the object by name. If you don't have anything like Objects, but you have Arrays, you can simply have a convention of what data goes where.

It's not really that different from what we do when we retrieve data from a database and perform dependency injection, except that everything's really global, and you're simply choosing to put everything into little boxes and only look at the one(s) you're concerned with right now.

Depending on what you're trying to do and what your language supports, this might help you at least break things down into more manageable chunks.

2
  • I also worked with Macromedia Authorware, @amy-blankenship. I don't remember what version it was when I last worked with it, maybe 3. Was it replaced by Flash/Showckwave or does it still exist ? Commented Oct 24, 2012 at 0:52
  • They were different things. Macromedia caused a lot of confusion in version 5 (of both) by calling everything Shockwave, including Director, when packaged for the web. Authorware was discontinued by Adobe after the acquisition, Flash is sort of still going. Commented Oct 25, 2012 at 1:49
1

When I was at university we were taught at length about "The Global Variable Problem" - a collection of bugs and code maintainence problems caused by lots of global variables.

Some variables are more dangerous than others.

Safe: Variables which do not affect the flow-of-control e.g. LastName

Dangerous: Any variable which affects the flow-of-control of the program e.g. DeliveryStatus

Most dangerous first:

  • Compound status (mode and sub-mode)
  • Compound values (total, sub-total)
  • Single status (mode)
  • Single values (count)

To avoid the "global variable problem" you need to

  • Document each variable and function.
  • Keep related variables close together (with code which uses them) in the same section of the source code.
  • Hide the "dangerous" variables, so other programmers do not know of their existance. Avoid using them directly, especially in other sections of the code.
  • Provide functions which read/write dangerous variables (so other programmers do not need to).

To structure your code, when no structure is available in the language, use comments and naming conventions:

/* --------------------------- Program mode ------------------------ */

var Mode_Standard = 1;      // Normal operation (SubMode unused)
var Mode_Backup   = 2;      // Backup mode      (SubMode is backup device)

var BackupMode_Disk = 1;    // SubMode: Backup to disk
var BackupMode_Tape = 2;    // SubMode: Backup to tape

var MainMode = Mode_Standard;
var SubMode = 0;

function Mode_SetBackup(backupMode)
{
    MainMode = Mode_Backup;
    SubMode = backupMode;
}

function Mode_SetStandardMode()
{
    MainMode = Mode_Standard;
    SubMode  = 0;
}

function Mode_GetBackupMode()
{
    if (MainMode != Mode_Backup)
        return 0;

    return SubMode;
}

/* --------------------------- Stock Control ------------------------ */

var Stock_Total =  123;      // Total stock       (including RingFenced)
var Stock_RingFenced = 22;   // Ring-fenced stock (always less than total)

// Adds further ring-fenced stock 
function Stock_AddRingFenced(quantity)
{
    Stock_Total      += quantity;
    Stock_RingFenced += quantity;
}

/* ------------------------- Customers ----------------------- */

var Customer_FirstName = "Tony";
var Customer_LastName  = "Stark";
0

Don't know how they did.

But I think that modern OOP languages had a very similar problem regarding the naming collision.

The solution is adopting namespace. It is an abstract concept, but widely adopted by several implementation (Java packages, .NET namespace, Python modules).

If the language you are using has not too narrow limitation about naming lenght, then you can apply the namespace to a good variable naming.

So the variable name also represents the variable scope.

Try to define a naming pattern like this: order_detail_product_code, order_detail_product_unit_price. Or for the temporary counters or swaps: tmp_i, tmp_swap.

0

In languages were all variables are global (I have used a couple) we used to use a variable naming convention. For example: if I actually wanted to use a variable as global I might use "m_" or "_" prefix. Of course this still relies on the developers to have this discipline

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.