DATA Step, Macro, Functions and more

Macro variable in array declaration.

Posts: 0

Macro variable in array declaration.

Why do I have to use %eval() in the array declaration, although the do loop runs without %eval()?

%let mvar=2010;
data inconsistency;
array x(%eval(&mvar-2000));
do i=1 to &mvar-2000;
Frequent Contributor
Posts: 106

Re: Macro variable in array declaration.

Look up the statement descriptions in the language reference manual. The keyword to look for is 'expression'. While you can use an expression (like the text string to which "&mvar-2000" resolves) in a 'do i=.. to ..' statement, you can't use an expression in the definition of an array. So it's not a matter of the macro language but a matter of the statement generated after macro variable/function resolution. %eval resolves the expression at macro resolution/execution time (which is before data step compile time), so only the result is being seen by the data step compiler.
As Cynthia put it these days: macro is like a typewriter (or a code writing slave as I like to call it myself): it writes SAS statements according to my instructions.

Hope this makes it somewhat clearer
Regular Contributor
Posts: 241

Re: Macro variable in array declaration.

> As Cynthia put it these days: macro is like a
> typewriter (or a code writing slave as I like to call
> it myself): it writes SAS statements according to my
> instructions.
Although the typewriter or code-writer metaphors may be easier for macro newbies, it is inaccurate and possibly misleading, because a macro *can* get somethings done without generating non-macro code. It also gives a false impression that it is OK (or even good) to write a wall-paper like repetitive code even when there are better alternatives.

In the same context, I don't think it is a sound advice to write sas code first in order to write a macro -- this will only end up encouraging users to write pieces of very inefficient sas code *and* very strange macro code, of the latter we see an example here.

Instead of relying on inaccurate and stale metaphors, I would show cleaner way of coding that minimizes the interaction (thus lessens the chances of conceptual blur) between macro language constructs and the sas code, something like below:
%let mvar = 2010;
%let dim = %eval(&mvar - 2000);

data one;
array x(&dim);
do i = 1 to &dim;
x(i) = 1;

Message was edited by:
Posts: 32

Re: Macro variable in array declaration.

Excuse me while I call chang on my rotary dial land line Smiley Happy
Posts: 8,740

Re: Macro variable in array declaration.


Interesting perspective.

Personally, I do not think the iPad's "text substitution" routine is a good metaphor for what the macro facility does. I do not find any "touch screen" examples that accurately illustrate the capabilities of the macro facility. Nor do I think, offhand, of any "voice recognition" software example that is a good metaphor for what the macro facility does.

The closest computer based metaphor that I can some up with is programmable keyboard shortcuts -- so I might, in my word processor, set up F1 to always insert "supercalifragilisticexpealidocious" wherever my cursor was placed in a word processing document or if I had a SEARCH and REPLACE routine set up in search for ~XXX~ and replace that string with the some other string.

The fundamental idea of "text substitution" is the first hurdle for "macro newbies" and I think that this section from the documentation explains the basics:

from the documentation:

This entire section is a direct quote from the macro documentation. The highlights were added by me.

When you use a macro facility name in a SAS program or from a command prompt, the macro facility generates SAS statements and commands as needed. The rest of SAS receives those statements and uses them in the same way it uses the ones you enter in the standard manner.

The macro facility has two components:
macro processor is the portion of SAS that does the work
macro language is the syntax that you use to communicate with the macro processor

When SAS compiles program text, two delimiters trigger macro processor activity:
&name refers to a macro variable. "Replacing Text Strings Using Macro Variables" explains how to create a macro variable. The form &name is called a macro variable reference.
%name refers to a macro. "Generating SAS Code Using Macros" explains how to create a macro. The form %name is called a macro call.

The text substitution produced by the macro processor is completed before the program text is compiled and executed. The macro facility uses statements and functions that resemble the statements and functions that you use in the DATA step. An important difference, however, is that macro language elements can enable only text substitution and are not present during program or command execution.

If people don't understand this last sentence, I find this to be a good documentation site that walks through a simple program and has pictures that show the process of text substitution:

When you move beyond text substitution with &MACVAR references and %LET, then there are other documentation sites that explain, in great detail, how macro program calls are resolved and what is generated when you call a macro program. On this documentation site

It says:
How the Macro Processor Executes a Compiled Macro
Macro execution begins with the macro processor opening the SASMACR catalog to read the appropriate macro entry. As the macro processor executes the compiled instructions in the macro entry, it performs a series of simple repetitive actions. During macro execution, the macro processor does the following:

--executes compiled macro program instructions

--places noncompiled constant text on the input stack

--waits for the word scanner to process the generated text

--resumes executing compiled macro program instructions

Again, I see no iPad, voice recognition or touch screen analogy possibilities in that explanation.

And, I find this "Summary of Macro Processing" explanation in the documentation
to be VERY clear:

Summary of Macro Processing
The previous sections illustrate the relationship between macro compilation and execution and DATA step compilation and execution. The relationship contains a pattern of simple repetitive actions. These actions begin when text is submitted to the input stack and the word scanner begins tokenization. At times the word scanner waits for the macro processor to perform an activity, such as searching the symbol tables or compiling a macro definition. If the macro processor generates text during its activity, then it pauses while the word scanner tokenizes the text and sends the tokens to the appropriate target. These tokens might trigger other actions in parts of SAS, such as the DATA step compiler, the command processor, or a SAS procedure. If any of these actions occur, the macro processor waits for these actions to be completed before resuming its activity. When the macro processor stops, the word scanner resumes tokenization. This process continues until the entire program has been processed.

...whose sweaters do NOT smell like the stuffy basement of an old house ;-)
Posts: 7,356

Re: Macro variable in array declaration.


Please don't take Chang's comments personally. Yes, when experienced SAS users come to the Forum, a number of us will question anything said that doesn't conform to our understanding of how SAS works .. especially if we see such places as forums for teaching others how to use or program in SAS.

In the present case, nothing in the documentation refers to a typewriter, or an Ipad or any other mechanism. It simply refers to text substitution within a given set of rules.

Posts: 8,740

Re: Macro variable in array declaration.

I didn't take it personally (hence the smiley face with the wink). I put the documentation links in my post so that folks who felt the typewriter example was inappropriate could go straight to the documentation.

Ask a Question
Discussion stats
  • 6 replies
  • 6 in conversation