Date: Fri, 27 Apr 2007 20:44:04 +0000
Reply-To: iw1junk@COMCAST.NET
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Ian Whitlock <iw1junk@COMCAST.NET>
Subject: Re: Checking if macro exists? (Was Re: Macro Quoting)
Summary: Some macro thoughts.
#iw-value=1
Chang,
Yes it is a dangerous idea to think that starting with a %-sign means a
macro. Consider
%include fref ;
or
%str(x) = 5 ;
Both of these are SAS statements. In both cases a macro does not exist.
now consider
x = = 3 , ;
Is this a SAS statement? If you don't care that this is not an executable
SAS statement, why should you care what happens when you execute %MAC? In
both cases the code is either executable or not, and it is not easy to know
which.
In a prior message you say, "It is an interesting idea to pass a piece of
SAS code or a macro call as a parameter to another macro, although I am
having difficulty thinking of practical uses or benefits of this particular
design."
It should strike you as an interesting idea. What is a macro? It is
probably best to think of it as a package of SAS code. What is its
importance? You can write the package in one place and reference it in
many. For example,
%macro loop (n) ;
%local i ;
%do i = 1 %to &n ;
%mac *<<<not shown here;
%end ;
%mend ;
Now suppose I want this to be more flexible, i.e. I not only do not want to
know what MAC does, I do not even want to be committed to the name MAC.
Then I could write.
%macro loop (n,m=mac) ;
%local i ;
%do i = 1 %to &n ;
%unquote(&m) *<<<not shown here;
%end ;
%mend ;
I am thinking of M as providing a macro call, but do I care. Suppose I
write
%loop(3,m=%nrstr(data w&i ; x = 4 ; run ;))
A language like Ruby makes essential use of this idea, that it is useful to
attach a block of code to function at call time as opposed to function
writing time. It is harder to make use of this in SAS because the language
isn't designed to support it, but it is still a tool worth putting in your
tool box. Programmers have worked around language deficiencies as long as
there have been language to program with.
In my SGF coder's corner paper I discuss, in part, a macro %REPLACE with a
parameter CODE which expects a block (chunk, bit) of SAS code which
generalizes the above idea in a list context. The paper does not mention
that this block could refer to a quoted macro call. You might see how well
it works with a macro instead. What would
%REPLACE(l=a b c, code=%nrstr(%#))
mean? (I am not sure whether the papers are generally available or not.)
Before worrying about %SYMMACROEXIST, here are some questions to help me
understand what you mean by existence.
I have a program that writes a macro. Does that macro exist before I run
the program? What if the program is sitting in the display manager? I
have a file JUNK.MAC; in it is some code for a macro AMAC. Does AMAC
exist? I have a file JUNK.SAS that is in a directory that is in the list
of autocall libraries. Does the macro JUNK exist? What if that file is
empty? What if there is code to define a macro named, JUNK, in the file,
but it is not compilable? What if that code compiles but is not
executable?
Now having thought about existence, how will that help you decide what to
do when the answer is yes? I note that even the SAS system does not
particularly care about existence.
103 %put "%x" ;
WARNING: Apparent invocation of macro X not resolved.
"%x"
On the other hand, the message is fairly clear - it's not my problem.
In this case it was kind enough to print my message anyway. Will you
provide the same sort of trust when you have a %SYMMACROEXIST function?
Ian Whitlock
==============
Date: Fri, 27 Apr 2007 13:11:57 -0400
Reply-To: Chang Chung <chang_y_chung@HOTMAIL.COM>
Sender: "SAS(r) Discussion"
From: Chang Chung <chang_y_chung@HOTMAIL.COM>
Subject: Re: Checking if macro exists? (Was Re: Macro Quoting)
Comments: To: Hsiwei Yu <hsiwei.yu@SPCORP.COM>
On Fri, 27 Apr 2007 12:41:03 -0400, Yu, Hsiwei <hsiwei.yu@SPCORP.COM>
wrote:
>Yes, can find out if a macro variable's value starts with '%', like: ...
>%chkPct1stChar( in= %nrstr(%%)xyz ); > >Though no automatic way to detect
if a macro exists or defined or >compiled, sashelp.vcatalg can help. >title
'See a list of compiled macro'; >proc print data= sashelp.vcatalg; >where
objtype='MACRO'; >run; > >Guess it would be hard work to figure out auto
call members, i.e. what >is in sasautos >%let a= %sysfunc( getoption(
sasautos )); >%put &a..;
Hi, Hsiwei,
Thanks for your thoughtful answer. I would say "exactly!" I don't really
like checking the first character like %chkPct1stChar macro does because
the fact that the parameter starts with "%" does not mean that there is
such a macro. For example, even after it is checked OK by the macro, you
can encounter an error or something that you did not expect when the macro
does not exists. IMHO, you should check the existence when you want to
check the existence. If it is possible to check, that is. So, that is why I
asked the question in the first place.
Yes, you are correct in that we can query the sashelp.vcatalg to find out
if a macro is compiled previously in the same session. But as you mention,
the macros don't have to be compiled in the same session to be available
for calling. For example, we don't have to compile any of the autocall
macros in the same session, but they are available for calling.
So the question remains open is it really possible for even si to implement
something like %symMacroExist?! I think it should be possible, but I may be
wrong...
Cheers, Chang
Date: Fri, 27 Apr 2007 11:31:50 -0400
Reply-To: Chang Chung <chang_y_chung@HOTMAIL.COM>
Sender: "SAS(r) Discussion"
From: Chang Chung <chang_y_chung@HOTMAIL.COM>
Subject: Checking if macro exists? (Was Re: Macro Quoting)
Comments: To: Ian Whitlock <iw1junk@COMCAST.NET>
>From: Unnat Patel <unnatppatel@YAHOO.COM> >Reply-To: unnatppatel@YAHOO.COM
>To: SAS-L >Subject: %qsubstr OR %qscan >Date: Thu, 26 Apr 2007 05:54:44
-0700 > >Hi All, > > I have macro variable which can have macro name OR
valid SAS >statments. (macro variable gets generated from variable) I would
like >to write condition to check whether parameter contains macro name OR
>SAS statments. (e.g. if first character is "%" then it is macro name >
otherwise not) I tried %qsubstr and %qscan but "Scenario II" is not >
working. (please see SAS code for both scenarios as below) ...
Hi,
It is an interesting idea to pass a piece of sas code or a macro call as a
parameter to another macro, although I am having difficulty thinking of
practical uses or benefits of this particular design. In any way, this line
of thought lead me to a question of whether there is a way for us to check
if certain macro is available to be called, once we are give the macro
name.
In the case of macro variable, we can check if it exists with %symexist()
or symexist function, but do we have something similar for macro's, like
%symMacroExist() or something? Or am I asking something impossible?
Cheers, Chang