Why does a macro parameter inside %EVAL continue to loop

Accepted Solution Solved
Reply
Contributor LL5
Contributor
Posts: 55
Accepted Solution

Why does a macro parameter inside %EVAL continue to loop

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

 


Accepted Solutions
Solution
‎02-25-2018 06:54 PM
PROC Star
Posts: 1,097

Re: Why does a macro parameter inside %EVAL continue to loop

[ Edited ]

@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)))

  • (4+%mysum(3))

 

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. 

View solution in original post


All Replies
SAS Super FREQ
Posts: 496

Re: Why does a macro parameter inside %EVAL continue to loop

4+3+2+1 = 10

Contributor LL5
Contributor
Posts: 55

Re: Why does a macro parameter inside %EVAL continue to loop

Thanks. But why it would loop like that?
Super User
Posts: 9,350

Re: Why does a macro parameter inside %EVAL continue to loop


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.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
How to convert datasets to data steps
How to post code
Super User
Posts: 6,396

Re: Why does a macro parameter inside %EVAL continue to loop

[ Edited ]

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.

Super User
Posts: 22,575

Re: Why does a macro parameter inside %EVAL continue to loop

Posted in reply to Astounding

It's a recursive loop. 

Solution
‎02-25-2018 06:54 PM
PROC Star
Posts: 1,097

Re: Why does a macro parameter inside %EVAL continue to loop

[ Edited ]

@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)))

  • (4+%mysum(3))

 

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. 

Contributor LL5
Contributor
Posts: 55

Re: Why does a macro parameter inside %EVAL continue to loop

Thanks novinosrin for this step by step illustration! Now I understand the equation is about &n + %mysum(n), so the inside macro continues to loop until the condition is false. This’s really helpful.
Super User
Super User
Posts: 7,762

Re: Why does a macro parameter inside %EVAL continue to loop

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
Contributor LL5
Contributor
Posts: 55

Re: Why does a macro parameter inside %EVAL continue to loop

Interesting. So I would think the if then else condition is kind of nested into the inner %mysum macro. So probably the concept is like below:

%MACRO MYSUM(4);

%IF &N >1 %THEN %EVAL(4 + %MYSUM(4-1=3)

%IF &N >1 %THEN %EVAL(3 + %MYSUM(3-1=2)

%IF &N >1 %EVAL(2 + %MYSUM(%EVAL(2-1=1)

%IF &N >1 %EVAL(1 + %MYSUM(1-1=0)

);

%ELSE &N));

%ELSE &N;

%MEND;

%PUT %MYSUM(4);
☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 9 replies
  • 232 views
  • 5 likes
  • 7 in conversation