Why learn to use structures?

Why use structures in GAUSS?

Some GAUSS users think that learning to use structures may be difficult and wonder if it is worth the effort. Using structures to hold arguments to procedures, outputs and control variables has many advantages over the use of global variables and is universally considered a best practice. Fortunately, the hurdle to learning structures is smaller than many people think. This document will explain how you will benefit from using them.

Keep similar items together

A structure is just a container that can hold different variables. A simple analogy is a grocery bag. If you only purchase an orange or two, it is easy to keep track of them. However, as you add more and more items, it becomes a burden to carry them all separately.

To combat this simple problem, you place the items in a grocery bag. Once the items are in the bag, you have only one thing to keep track of—the grocery bag. All of the individual items are still available any time you would like to access them. However when they are not needed, you have the luxury of not thinking about them. Similarly, structures provide a convenient package for holding and transporting GAUSS variables.

Code that is easier to understand

Replacing global variable inputs with structures leads to programs that are easier to follow and less prone to certain accidental errors.

When a structure is passed into a procedure, all its members are local to that procedure and thus cannot be changed outside of the procedure. Global variables, however, can be changed by any other code. This can lead to certain variables being set unexpectedly by another part of the program or the order in which different programs are run. These changes to global variables by other code can lead your program to intermittently run differently than you expect.

Relying on global variables also creates a dependency for your program since the variables need to be set before running it. If others use the code you have written or you move it to a new machine, neglecting to set these global variables will produce “undefined symbol” errors. These errors are often frustrating and can be difficult to resolve.

Although adding a structure will also create a dependency for your program, it is much easier for users to see if they are missing a structure definition or a function to set its default values. A global control variable may only appear once or twice in a program and when it does, it may be deep inside the program’s inner workings, making it easy to overlook.

Code that is easier to change

Structures make it simpler to make changes to your code. For example, if you wanted to add a control variable to a procedure that inputs all variables as individual matrices, strings, etc, you would either have to change the prototype for the procedure, such as from:

proc (1) = myProc( a, b, c );

to

proc (1) = myProc(a, b, c, d);

or create a global variable, introducing all the problems we discussed previously. While changing the prototype in the procedure definition as above is not difficult, it also requires you to make this change to every instance where you are calling this procedure. As the number of arguments grows, this will also incrementally increase the difficulty of using the procedure. For example, a call to the GAUSS ols procedure looks might look like this:

{ vnam, m, b, stb, vc,
  stderr, sigma, cx,
  rsq, resid, dwstat } = ols(dataset, depvar, indvars);

The large number of outputs to this function can be burdensome. When using structures to contain the outputs, however, you only need to add another entry to the structure definition. For example if we have an olsmtOut structure named “out”, the function call looks much simpler:

out = olsmt(oc0, dataset, depvar, indvars);

And accessing the individual outputs is just as easy. To print the Durbin-Watson statistic after the call to ols would look like this:

print dwstat;

To access the same statistic from the structure, you apply the dot operator to the structure instance. In this example, "out" is the structure instance. To print the Durbin-Watson statistic you would enter:

print out.dwstat;

Summary

  1. Using structures to contain variables for a procedure or large numbers of similar outputs is universally considered a best practice.
  2. Structures keep similar items together in one convenient location.
  3. Structures make code easier to understand.
  4. Structures make code easier to change.