LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (July 2008, week 1)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:   Sat, 5 Jul 2008 00:33:53 +0000
Reply-To:   iw1junk@COMCAST.NET
Sender:   "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:   Ian Whitlock <iw1junk@COMCAST.NET>
Subject:   Re: Macro behavior in IML and DATA step
Comments:   cc: Paul Thompson <paul@WUBIOS.WUSTL.EDU>

Sumary: Theory can be wrong, but sometimes appear to explain. #iw-value=1

Paul,

You wrote, "The macro system behaves a little differently in IML than it does in other parts of SAS."

You have things the wrong way around. It is the procedure or language that behaves differently, not macro. It is sort like having a theory that the cart pushes the horse rather than the horse pulls the cart.

Given the appropriate environment, a macro variable is always available immediately following EXECUTION of the statement that assigns the variable. Since in some languages of the SAS family statements do not execute until a whole step is compiled, we find some languages where a variable created by a statement S is not available to the compiler by a statement following S because S does not EXECUTE until the step has finished compiling, i.e. long after the compiler needs the new value of the macro variable. And we find some languages where the variable is available in a subsequent statement to the compiler because each statement is executed immediately upon compilation.

Let's look at a modified form of your first example.

291 %let _i=1; 292 data _null_; 293 call symput("_i",'2'); 294 call execute ('%put "&_i";') ; 295 run;

"2" NOTE: DATA statement used (Total process time): real time 0.07 seconds cpu time 0.01 seconds

NOTE: CALL EXECUTE routine executed successfully, but no SAS statements were generated.

What is the difference between your example and mine? Mine does not ask the compiler to know the value of _I, yours does.

The more accurate statement is that some compiled languages behave differently during compilation, not that the macro facility behaves differently. So why is it important? With your statement one might look to the macro documentation to find out what is happening, while with mine one would look in the language or procedure documentation to understand what is happening. Moreover, one would be on the lookout for different compile/execute behavior in other procedure with my phrasing, but not yours. Your statement also leads one to believe that he has to learn different macro languages rather than different procedure behavior. In short it may work for you, but it is misleading to one who wants to understand in general what to expect.

Now let's look at another language where each statement executes after it is compiled, as opposed to when the procedure is finished.

296 data w ; 297 x = 1 ; 298 run ;

NOTE: The data set WORK.W has 1 observations and 1 variables. NOTE: DATA statement used (Total process time): real time 0.06 seconds cpu time 0.01 seconds

299 300 %let works = 1 ; 301 proc sql ; 302 select "hello world" into :works from w ; 303 %put &works ; hello world 304 quit ; NOTE: PROCEDURE SQL used (Total process time): real time 0.20 seconds cpu time 0.02 seconds

If you know that in both IML and SQL that statements execute immediately upon compilation then my second example is no surprise. But if you think that macro behaves differently in IML then you will have to learn the same thing all over about SQL as part of the price paid for hanging on to a wrong theory.

Ian Whitlock ==============

Date: Fri, 4 Jul 2008 14:14:32 -0500 Reply-To: paul@WUBIOS.WUSTL.EDU Sender: "SAS(r) Discussion" From: Paul Thompson <paul@WUBIOS.WUSTL.EDU> Subject: Macro behavior in IML and DATA step Content-Type: text/plain; charset=ISO-8859-1; DelSp="Yes"; format="flowed"

The macro system behaves a little differently in IML than it does in other parts of SAS. In IML, each statement is executed immediately, rather than waiting until all code is assembled. This is a bit odd for those who use macros outside of IML.

Here is a simple example. First, we see the normal behavior in the datastep, where the call symput does not affect the value of _i until after the run:

75 options mprint; 76 77 %let _i=1; 78 data _null_; 79 call symput("_i",'2'); 80 put "&_i"; 81 run;

1 NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.00 seconds

82 %put _i[&_i]; _i[2]

This is all quite what SAS users expect.

In IML, things behave a little differently. Here is a comparable example, with the output brought in from the OUTPUT window shown below.

83 84 %let _i=1; 85 proc iml; NOTE: IML Ready 86 call symput("_i",'2'); 87 print "Current value of _i: &_i"; 88 quit; NOTE: Exiting IML. NOTE: PROCEDURE IML used (Total process time): real time 0.03 seconds cpu time 0.01 seconds

89 %put _i[&_i]; _i[2]

From the OUTPUT window: The SAS System 13:58 Friday, July 4, 2008 6

Current value of _i: 2

I encourage those who have not tried this to do so.

IML is an interesting part of SAS. Its immediate execution component is very useful. It gives the ability of macro code to more tightly self-modify.

This issue was raised by a post or two earlier today. I thought it interesting, so present this small tutorial.


Back to: Top of message | Previous page | Main SAS-L page