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 (April 2007, week 4)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
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)
Comments: cc: Chang Chung <chang_y_chung@HOTMAIL.COM>,
          Hsiwei Yu <hsiwei.yu@SPCORP.COM>

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


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