Home > Programming > Programming an estimation command in Stata: Global macros versus local macros

Programming an estimation command in Stata: Global macros versus local macros

I discuss a pair of examples that illustrate the differences between global macros and local macros. You can view this post as a technical appendix to the previous post in the #StataProgramming series, which introduced global macros and local macros.

In every command I write, I use local macros to store stuff in a workspace that will not alter a user’s data and to make my code easier to read. A good understanding of the differences between global macros and local macros helps me to write better code. The essential differences between global macros and local macros can be summarized in two points.

  1. There is only one global macro with a specific name in Stata, and its contents can be accessed or changed by a Stata command executed at any Stata level.
  2. In contrast, each Stata level can have a local macro of a specific name, and each one’s contents cannot be accessed or changed by commands executed at other Stata levels.

If you are already comfortable with 1 and 2, skip the remainder of this post.

This is the third post in the series Programming an estimation command in Stata. I recommend that you start at the beginning. See Programming an estimation command in Stata: A map to posted entries for a map to all the posts in this series.

Global macros are global

The do-files globala.do and globalb.do in code blocks globala and globalb illustrate what it means to be global.

Code block 1: globala.do

*-------------------------------Begin globala.do ---------------
*! globala.do
*  In this do-file we define the global macro vlist, but we
*  do not use it
global vlist var1 var2 var3

do globalb
*-------------------------------End globala.do ---------------

Code block 2: globalb.do

*-------------------------------Begin globalb.do ---------------
*! globalb.do
*  In this do-file, we use the global macro vlist, defined in globala.do

display "The global macro vlist contains $vlist"
*-------------------------------End globalb.do ---------------

The easiest way to see what this code does is to execute it; the output is in example 1.

Example 1: Output from do globala

. do globala

. *-------------------------------Begin globala.do ---------------
. *! globala.do
. *  In this do-file we define the global macro vlist, but we
. *  do not use it
. global vlist var1 var2 var3

. 
. do globalb

. *-------------------------------Begin globalb.do ---------------
. *! globalb.do
. *  In this do-file, we use the global macro vlist, defined in globala.do
. 
. display "The global macro vlist contains $vlist"
The global macro vlist contains var1 var2 var3

. *-------------------------------End globalb.do ---------------
. 
end of do-file

. *-------------------------------End globala.do ---------------
. 
end of do-file

Line 5 of globalb.do can access the contents of vlist created on line 5 of globala.do because vlist is a global macro.

Figure 1 makes this same point graphically: the global macro vlist is in global memory, and a command executed anywhere can access or change the contents of vlist.

Figure 1: A global macro in global memory
graph1

Local macros are local

The do-files locala.do and localb.do in code blocks 3 and 4 illustrate what it means to be local.

Code block 3: locala.do

*-------------------------------Begin locala.do ---------------
*! locala.do
local mylist "a b c"
display "mylist contains `mylist'"

do localb

display "mylist contains `mylist'"
*-------------------------------End locala.do ---------------

Code block 4: localb.do

*-------------------------------Begin localb.do ---------------
*! localb.do
local mylist "x y z"
display "mylist contains `mylist'"
*-------------------------------End localb.do ---------------

The easiest way to see what this code does is to execute it; the output is in example 2.

Example 2: Output from do locala

. do locala

. *-------------------------------Begin locala.do ---------------
. *! locala.do
. local mylist "a b c"

. display "mylist contains `mylist'"
mylist contains a b c

. 
. do localb

. *-------------------------------Begin localb.do ---------------
. *! localb.do
. local mylist "x y z"

. display "mylist contains `mylist'"
mylist contains x y z

. *-------------------------------End localb.do ---------------
. 
end of do-file

. 
. display "mylist contains `mylist'"
mylist contains a b c

. *-------------------------------End locala.do ---------------
. 
end of do-file

The code in blocks 3 and 4 and the output in example 2 illustrate that a command executed at the level of localb.do cannot change the local macro mylist that is local to locala.do. Line 8 of locala.do displays the contents of the mylist local to locala.do. The contents are still a b c after localb.do finishes because the local macro mylist created on line 3 of locala.do is local to locala.do and it is unaffected by the mylist created on line 3 of localb.do.

Figure 2 makes this point graphically. The contents of the local macro mylist that is local to locala.do can be accessed and changed by commands run in locala.do, but not by commands run in localb.do. Analogously, the contents of the local macro mylist that is local to localb.do can be accessed and changed by commands run in localb.do, but not by commands run in locala.do.

Figure 2: Local macros are local to do-files
graph1

Done and Undone

I essentially provided you with a technical appendix to the previous #StataProgramming post. I illustrated that global macros are global and that local macros are local. I use the concepts developed thus far to present an ado-command in the next post.

  • Stas Kolenikov

    I used globals in two of my estimation commands: -denormix- (univariate normal mixtures; superseded by Partha Deb’s -fmm- by now which itself may be considered dated these days, although I am sure it still runs) and -confa- (confirmatory factor analysis; superseded by the official -sem- by now). In both cases, I did not know how many ML equations I was going to have, so I had to accumulate them in globals at the syntax parsing stage, and pass them to my evaluators. Generally, I consider globals to be a programming “smell”, especially when used in do-files and interactive analysis: rarely one is going to have something that will stay the same for all data sets, for all data management and analysis commands, etc. Am I wrong?

  • Alfonso Sánchez-Peñalver

    The way I have always thought about it is that globals are only useful if you are going to need to access them from different subprocedures. They become useful when all subprocedures need to access the same information. For example I have many estimation commands subprocedures for a general command, and I want to access what the user actually wrote in my subprocedures. I store it in a global macro and then access it from the subprocedures.

    Now since I don’t want the macro to be accessible once my command actually does its estimation I use -macro drop- at the end.