Hi All, I am trying to understand why %MYSUM(4) resolved to 10 - see codes and log below.
My understanding would be &N is 4, the inside %MYSUM macro resolved to 3, so the answer would be 4 + 3 = 7.
However, according to the log, it seems the macro continues to loop until the condition of &N > 1 is false.
Can anyone share some thoughts and give some advises?
Thanks.
OPTIONS MLOGIC ;
%MACRO MYSUM(N);
%IF &N >1 %THEN %EVAL(&N+ %MYSUM(%EVAL(&N-1)));
%ELSE &N;
%MEND;
%PUT %MYSUM(4);
%MACRO MYSUM(N);
26 %IF &N >1 %THEN %EVAL(&N+ %MYSUM(%EVAL(&N-1)));
27 %ELSE &N;
28 %MEND;
29
30 %PUT %MYSUM(4);
MLOGIC(MYSUM): Beginning execution.
MLOGIC(MYSUM): Parameter N has value 4
SYMBOLGEN: Macro variable N resolves to 4
MLOGIC(MYSUM): %IF condition &N >1 is TRUE
SYMBOLGEN: Macro variable N resolves to 4
MLOGIC(MYSUM): Beginning execution.
SYMBOLGEN: Macro variable N resolves to 4
MLOGIC(MYSUM): Parameter N has value 3
SYMBOLGEN: Macro variable N resolves to 3
MLOGIC(MYSUM): %IF condition &N >1 is TRUE
SYMBOLGEN: Macro variable N resolves to 3
MLOGIC(MYSUM): Beginning execution.
SYMBOLGEN: Macro variable N resolves to 3
MLOGIC(MYSUM): Parameter N has value 2
SYMBOLGEN: Macro variable N resolves to 2
MLOGIC(MYSUM): %IF condition &N >1 is TRUE
SYMBOLGEN: Macro variable N resolves to 2
MLOGIC(MYSUM): Beginning execution.
SYMBOLGEN: Macro variable N resolves to 2
MLOGIC(MYSUM): Parameter N has value 1
SYMBOLGEN: Macro variable N resolves to 1
MLOGIC(MYSUM): %IF condition &N >1 is FALSE
SYMBOLGEN: Macro variable N resolves to 1
MLOGIC(MYSUM): Ending execution.
MLOGIC(MYSUM): Ending execution.
2 The SAS System 13:02 Sunday, February 25, 2018
MLOGIC(MYSUM): Ending execution.
MLOGIC(MYSUM): Ending execution.
10
@LL5 Thank you for the amazing code and a very interesting question:
Here you go:
OPTIONS MLOGIC ;
%MACRO MYSUM(N);
%IF &N >1 %THEN %EVAL(&N+ %MYSUM(%EVAL(&N-1)));
%ELSE &N;
%MEND;
%PUT %MYSUM(4);
Execution:
%if 4>1 (true)
So (4+%mysum(%eval(4-1)))
Now execute %mysum(3)
%if 3>1 (true)
So 3+%mysum(%eval(3-1)))
à3+%mysum(2)
Now execute %mysum(2)
%if 2>1(true)
So 2+%mysum(%eval(2-1)))
2+%mysum(1)
Now execute %mysum(1)
%if 1>1 (false)
So N takes the value of 1.
Final equation %eval(4+3+2+1)=10
Basically, the code is generating the equation %EVAL(&N+ %MYSUM(%EVAL(&N-1))); with one execution of the outer parameter
Hope this helps
The bold is intended to make it distinct where i thought it is important and not to sound harsh.
4+3+2+1 = 10
@LL5 wrote:
Thanks. But why it would loop like that?
See Maxim 23.
(Just kidding)
If you want to see a really elegant application of the recursion principle to a real-world problem, see the wikipedia entry for the quicksort algorithm.
Notice how the macro calls itself internally.
The increment is not + (&N-1).
Instead it is + (%MYSUM(%EVAL(&N-1))
That's what gets you the repetition.
It's a recursive loop.
@LL5 Thank you for the amazing code and a very interesting question:
Here you go:
OPTIONS MLOGIC ;
%MACRO MYSUM(N);
%IF &N >1 %THEN %EVAL(&N+ %MYSUM(%EVAL(&N-1)));
%ELSE &N;
%MEND;
%PUT %MYSUM(4);
Execution:
%if 4>1 (true)
So (4+%mysum(%eval(4-1)))
Now execute %mysum(3)
%if 3>1 (true)
So 3+%mysum(%eval(3-1)))
à3+%mysum(2)
Now execute %mysum(2)
%if 2>1(true)
So 2+%mysum(%eval(2-1)))
2+%mysum(1)
Now execute %mysum(1)
%if 1>1 (false)
So N takes the value of 1.
Final equation %eval(4+3+2+1)=10
Basically, the code is generating the equation %EVAL(&N+ %MYSUM(%EVAL(&N-1))); with one execution of the outer parameter
Hope this helps
The bold is intended to make it distinct where i thought it is important and not to sound harsh.
Turn on the new MLOGICNEST option and the recursive nature of the function is more obvious.
Also you don't need that extra %EVAL().
%macro mysum(n);
%if &n >1 %then %eval(&n+ %mysum(&n-1));
%else &n;
%mend;
options mlogic mlogicnest;
%put %mysum(3);
options nomlogic nomlogicnest;
248 %put %mysum(3); MLOGIC(MYSUM): Beginning execution. MLOGIC(MYSUM): Parameter N has value 3 MLOGIC(MYSUM): %IF condition &n >1 is TRUE MLOGIC(MYSUM.MYSUM): Beginning execution. MLOGIC(MYSUM.MYSUM): Parameter N has value 3-1 MLOGIC(MYSUM.MYSUM): %IF condition &n >1 is TRUE MLOGIC(MYSUM.MYSUM.MYSUM): Beginning execution. MLOGIC(MYSUM.MYSUM.MYSUM): Parameter N has value 3-1-1 MLOGIC(MYSUM.MYSUM.MYSUM): %IF condition &n >1 is FALSE MLOGIC(MYSUM.MYSUM.MYSUM): Ending execution. MLOGIC(MYSUM.MYSUM): Ending execution. MLOGIC(MYSUM): Ending execution. 6
Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.
Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.