BookmarkSubscribeRSS Feed
Priyanka_sas7
Calcite | Level 5

%macro mysum(n);
%put mysum called: n=&n;
%if &n > 1 %then %eval(&n + %mysum(%eval(&n-1)));
%else &n;
%mend;
%put %mysum(4);

 

Result : 10. 

2 REPLIES 2
Tom
Super User Tom
Super User

That is called RECURSION.

 

When the value of N is larger than one it calls itself with a value of N-1. 

 

Macro calls work well for recursion because each instance of the executing macro creates a whole new symbol space to store the values of the local macro variable, in this case the parameter value N.

 

You can see it in action if you turn on MLOGIC and MLOGICNEST options. 

544  options mlogic mlogicnest;
545  %put %mysum(4);
MLOGIC(MYSUM):  Beginning execution.
MLOGIC(MYSUM):  Parameter N has value 4
MLOGIC(MYSUM):  %PUT mysum called: n=&n
mysum called: n=4
MLOGIC(MYSUM):  %IF condition &n > 1 is TRUE
MLOGIC(MYSUM.MYSUM):  Beginning execution.
MLOGIC(MYSUM.MYSUM):  Parameter N has value 3
MLOGIC(MYSUM.MYSUM):  %PUT mysum called: n=&n
mysum called: n=3
MLOGIC(MYSUM.MYSUM):  %IF condition &n > 1 is TRUE
MLOGIC(MYSUM.MYSUM.MYSUM):  Beginning execution.
MLOGIC(MYSUM.MYSUM.MYSUM):  Parameter N has value 2
MLOGIC(MYSUM.MYSUM.MYSUM):  %PUT mysum called: n=&n
mysum called: n=2
MLOGIC(MYSUM.MYSUM.MYSUM):  %IF condition &n > 1 is TRUE
MLOGIC(MYSUM.MYSUM.MYSUM.MYSUM):  Beginning execution.
MLOGIC(MYSUM.MYSUM.MYSUM.MYSUM):  Parameter N has value 1
MLOGIC(MYSUM.MYSUM.MYSUM.MYSUM):  %PUT mysum called: n=&n
mysum called: n=1
MLOGIC(MYSUM.MYSUM.MYSUM.MYSUM):  %IF condition &n > 1 is FALSE
MLOGIC(MYSUM.MYSUM.MYSUM.MYSUM):  Ending execution.
MLOGIC(MYSUM.MYSUM.MYSUM):  Ending execution.
MLOGIC(MYSUM.MYSUM):  Ending execution.
MLOGIC(MYSUM):  Ending execution.
10

 

ballardw
Super User

Recursion is a powerful tool.

 

It can also be very slippery and should very carefully document exactly what the inputs are expected to be.

For example this particular macro will generate an error if called with a decimal value such as

%put %mysum(2.1);

You may find if you test that option that you have an unstable system as well because of the way that SAS treats macro code.

Calling the macro this way:

%put %mysum(2);
%put %mysum(2.1);
%put %mysum(2);

Generates this log:

6    %put %mysum(2);
mysum called: n=2
mysum called: n=1
3
7    %put %mysum(2.1);
mysum called: n=2.1
ERROR: A character operand was found in the %EVAL function or %IF
       condition where a numeric operand is required. The condition was:
       2.1-1
ERROR: The macro MYSUM will stop executing.
ERROR: A character operand was found in the %EVAL function or %IF
       condition where a numeric operand is required. The condition was:
       2.1 +
ERROR: The macro MYSUM will stop executing.
8    %put %mysum(2);
ERROR: Open code statement recursion detected.

Moral of the story: If you pursue this then SAVE YOUR CODE frequently as it easy to place SAS into an unstable session. That open code recursion error usually means time to stop and restart SAS.

 

Another concern with recursion is setting a stopping rule. It is very easy to create an infinite loop if your stop condition is poorly designed.

 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

What is ANOVA?

ANOVA, or Analysis Of Variance, is used to compare the averages or means of two or more populations to better understand how they differ. Watch this tutorial for more.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 2 replies
  • 543 views
  • 5 likes
  • 3 in conversation