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 2005, week 4)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:   Fri, 22 Apr 2005 00:58:16 -0400
Reply-To:   Don Hendereson <donaldjhenderson@HOTMAIL.COM>
Sender:   "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:   Don Hendereson <donaldjhenderson@HOTMAIL.COM>
Subject:   Re: SCL versus Macro
In-Reply-To:   <20050422034552.THSB23292.imf23aec.mail.bellsouth.net@CHRISSY>
Content-Type:   text/plain; charset="us-ascii"

Joe,

I will respond to your point #8 only (for now). That is not to say that I cede any of your other points (I don't). It is simply that I point #8 is very clear. I post an example and if you can't replace the exact functionality, you have to cede the point. And once you cede the point, I will then turn my attention to your other comments.

What follows is a gross oversimplification of a real-world problem I recently solved with macro.

The problem: a JSP application accesses a data store maintained by collection of SAS program. These programs populate a variety of data sets that the end users of the JSP application will query and drill down thru. The user has expressed the requirement that any report displayed back to the UI needs to show a custom message with the date/time that data set was loaded. There are few wrinkles here:

- the JSP application uses JDBC to access the SAS data. Thus the above message text must be returned by a SQL query submitted via JDBC. - the user/client is not willing to assume that the process that loads the data can be counted on to update a SAS table with the appropriate message text (there are lots of valid reasons for this that are way out of scope for this discussion) - the message text, except for the date/time, must be defined in metadata - no JSP programming to parse the message text and insert the dynamic content (e.g., the date/time)

And, yes, I will agree that this is a very special case. I maintain that you can not provide a pure SCL solution to this. However, the macro solution is quite simple.

At this point I would like to digress a bit and say that the solution was motivated by the very insightful ideas that Jack Hamilton posted a while back regarding the use of macro to generate data values in queries submitted by htmSQL.

So here is the macro solution (macro code stripped down to the key elements). Define a macro which will generate the text corresponding to the date the data set was created:

%macro getDate(data=); %local dsid; %let dsid = %sysfunc(open(&data)); %sysfunc(attrn(&dsid,CRDTE),datetime.) %let dsid = %sysfunc(close(&dsid)); %mend getDate;

And let me digress here to acknowledge that I am using functions that were originally SCL functions (but are now more widely available). But without macro, I simply could not meet the requirements - thus reinforcing my point that having both sets of tools in our arsenal is a good thing.

Now, if I just call the macro in SAS code, e.g.,

%put sashelp.class created on %getDate(data=sashelp.class);

I get the following text:

sashelp.class created on 12MAY04:22:53:56

Now I create a data set, called libref.messages_data as (proc print follows):

Obs message

1 sashelp.class created on %getDate(data=sashelp.class)

Next, I create a view of this data as follows:

proc sql; create view messages as select resolve(message) as Message from libref.messages_data; quit; run;

The resolve function causes the text in the variable message to be submitted to the macro processor. The resulting generated text becomes the value of the variable (thus reinforcing another point about macro - it is simply nothing more than a text manipulation language that has a number of hooks that know about SAS, e.g., the %sysfunc macro that can call data step or scl functions).

When I run proc print on this I get:

Obs Message

1 sashelp.class created on 12MAY04:22:53:56

Note that this is the same value return to the JSP app via JDBC. The JSP application will query libref.messages and the fact that macro is involved in completely transparent to the JSP application. In fact, it is transparent to any program/process that accesses this data view.

Regards, -don h

-----Original Message----- From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of Joe Whitehurst Sent: Thursday, April 21, 2005 11:46 PM To: SAS-L@LISTSERV.UGA.EDU Subject: Re: SCL versus Macro

Don,

Glad to hear you couldn't resist anymore, and I welcome you to the discussion. I think we are all likely to learn more from a vigorous discussion among seasoned veterans like you, Ian and others. I have little difficulty agreeing with some of what you had to say. On the other hand, I am not prepared to agree with some other aspects of your commentary. I assume you have read my responses to Ian, et al, so I will not repeat those responses here although I think some of them are applicable, and I may refer to them. What I will try to do instead is respond to those parts of your commentary below with which I cannot agree at this time.

-----Original Message----- From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of Don Hendereson Sent: Thursday, April 21, 2005 7:18 PM To: SAS-L@LISTSERV.UGA.EDU Subject: Re: SCL versus Macro

Joe (et al),

I have resisted weighing in on this thread, but I can not hold back any more.

SCL is a great tool. As is macro. There is room for both. The example you presented is one that is simply not appropriate for SCL for all the reasons (and then some) that Ian stated so eloquently. *************************************************************************** ***************************************************************************

1) I think my response to Ian's critique is highly appropriate here. The example was not intended to be anything other than a refutation of the assertion that the functionality in Paul Thompson's Macro would "do things that SCL has trouble with". I think my example achieved that limited goal picayune criticisms notwithstanding.

*************************************************************************** *************************************************************************** Permit me to offer just one simple critique of your response. Ian's point about clarity of the arguments is well stated. And let me use that to motivate my point. If I call macro overrun and forget about the underscores in the parameter names, or I provide a parameter name that is not a valid macro parameter, I get a syntax error - as I should.

In your example, if I specify:

%let bs = .....

Instead of:

%let _bs = .....

I would presume that the process runs with the default parameter values. So I might get something that gave me no indication whatsoever that I called your SCL program incorrectly. **************************************************************************** ****************************************************************************

2) This particular picayune criticism would be easily handled in any real world use of SAS Component Language by testing the values of the parameters being passed and writing an appropriate message to the log, stopping the program, or any other action a programmer might wish to take.

**************************************************************************** **************************************************************************** Next, you talk about the use of lists - very nice things indeed. But if you add up all the various bits and pieces of things that you need to hook together and assume in order to do things with SCL, you have a far more complicated and dangerous environment than one that uses simple macro. *************************************************************************** ***************************************************************************

3) The real quarry I am after is not a simple macro, but one that has constructions like: &&&&&&&zebra.&&&&&warpraptor&&&&&&&&&&&metope&&bullsht for an extreme example. *************************************************************************** ***************************************************************************

Permit me to illustrate with another example. Consider wanting to call two different modules one right after the other:

%one(data=a,vars=b)

Followed by:

%two(vars=c)

Where, for example for macro two, I want the default value for data. In your example with %let statements (a macro language construct I might add), you would have to know and remember to blank out the value before the second call. The use of macro variables to pass parameters also means that the user has to know all the parameters for every routine/module they call. **************************************************************************** ****************************************************************************

4) Point 2 applies here, and I'm aware that %LET is a Macro Language construct, and I have stopped using them in all but trivial cases.

**************************************************************************** **************************************************************************** And yes, you can come back and tell me that LISTS and conventions (e.g., a SCL entry gets its parameter values from a LIST with a name uniquely determined by the SCL entry name) can solve all that - but that is not the point. **************************************************************************** ****************************************************************************

5) I would say at least that and much more given a real world example, and that is a great part of the point I wish to make.

**************************************************************************** ****************************************************************************

The point is that some problems are better suited to macro and some to SCL. The version 6 HTML formatting tools are a prime example. They are mostly written in SCL - but the user/programmer interface is a macro call - for many of the reasons Ian highlighted. **************************************************************************** ****************************************************************************

6) It is just as likely that the reason that the user/programmer interface is a Macro call is that is what the programmer charged with the responsibility knew how to do. In my experience, it is a rare event in world history when any system building decisions are actually based on rational considerations.

**************************************************************************** ****************************************************************************

It should be very simple. Both SCL and macro are great tools to have in our toolkit as SAS developers/users. But to make the claim that SCL is better than macro or that macro is better than SCL simply can not be supported. **************************************************************************** ****************************************************************************

7) I can certainly "claim" that SAS Component Language is better for organizing and controlling batch SAS programs than the SAS Macro Language is, but what I intend to do instead is illustrate why with a series of examples starting with the data mining simulation macro offered by Michael Murff of Brigham Young University. In fact, what I would like to do is put this dead horse aside so I can focus on that project

**************************************************************************** **************************************************************************** I am pretty sure either of us could provide any number of examples that simply can not be done in macro, but can be in SCL. And I am almost positive that I can provide macro examples that simply can't be done in SCL. **************************************************************************** ****************************************************************************

8) Even though I am not from Missouri, I will have to be shown a Macro Language example whose functionality cannot be replicated with SAS Component Language. I simply don't believe it is possible.

**************************************************************************** **************************************************************************** Why can't we leave the matter at the statement that both are great tools that each have their place. **************************************************************************** ****************************************************************************

9) Now, that wouldn't be any fun would it? And members of this forum would be deprived of the learning opportunities afforded when experts disagree Publicly.

Kind Regards,

Joe

*************************************************************************** **************************************************************************** Regards, -don h

-----Original Message----- From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of Joe Whitehurst Sent: Thursday, April 21, 2005 2:30 PM To: SAS-L@LISTSERV.UGA.EDU Subject: Re: SCL versus Macro

Ian,

Like Richard, you have made some interesting comments which point out further unwarranted assumptions I made in presenting what I meant to be just a quick example to refute Frank's assertion, "OK, here's a good example of a situation where macros do things that SCL has trouble with". I think my example even with all its warts did do this. I did not intend anything more than this for this example, and I certainly did not attempt to put "one... in a position to make a reasonable judgment on the superiority of SCL code to macro code in all cases" on the basis of this simple example. Nevertheless, because you have been thoughtful enough to critique the example, I will try to respond to your suggestions.

Just as Frank's Macro Language code presents a clear set of parameters which are readily apparent to you, including which had default values and which did not, an expert with the SAS Macro Language, I assert that the SAS Component Language functionally equivalent code also presents a clear set of parameters which are readily apparent to an expert with SAS Component Language, including which had default values and which did not. I might say that your construct subsystem for construing SAS Component Language code is not nearly as elaborated as your construct subsystem for construing SAS Macro Language code. Or, I could just say, you have vastly more experience construing SAS Macro Language code than you do construing SAS Component Language code. Or, even, you have developed cognitive structures for assimilating Macro Language code while you still have to accommodate Component Language code. From the standpoint of an expert with SAS Component language: %let _bs=1; %let _es=2;

libname x "/users/x";

%let _vrun=a; dm 'af=x._overrun.scl';

%let _vrun=b; dm 'af=x._overrun.scl';

with knowledge of the details of the code in _overrun.scl is just as informative as the corresponding Macro Language code details would be to an expert with the SAS Macro Language.

As regards the user/tool communication problem for batch programs, the SAS System comes with an editor/viewer for SAS Component Language stored Lists (CatalogEntryType=SLIST) which obviates the need for any macro variables at all. I considered it beyond the scope of this little example, but I will include complete instructions on how to create, review, and revise SLISTs to facilitate parameter passing to batch programs when I present the SAS Component Language functional equivalent to the data mining simulation Macro. To whet the appetites of any readers of this thread let me just ask if you could use a data structure which can store items (32k max length) of mixed data types including other lists and which can have item names of any length (32k max) using any printable character and which allows these items to be retrieved by name or position or index to control your batch processing?

Joe Whitehurst

-----Original Message----- From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of Ian Whitlock Sent: Thursday, April 21, 2005 12:44 PM To: SAS-L@LISTSERV.UGA.EDU Subject: SCL versus Macro

In response to Frank Ivis' macro example (proposed under the subject line "Re: The advantage and disadvanatge of using SAS Macros"),

fi> %macro _overrun(_bs=1,_es=2,_vrun=); fi> %if (&_bs <= 1 & 1 <= &_es) %then %do; fi> libname x "/users/x"; fi> proc format;value af 1='a' 2='b';run; fi> %end; fi> %if (&_bs <= 2 & 2 <= &_es) %then %do; fi> proc means data=x.file;var &_vrun; fi> run; fi> %end; fi> %mend _overrun;

and usage code

fi> %_overrun(_vrun=a); fi> %_overrun(_vrun=b);

Joe Whitehurst posted an alternative using SCL. (I put the SCL first, to parallel the macro code and to distinguish the tool form the use of the tool.)

jw> init: jw> _vrun=symget("_vrun"); jw> _bs=symget("_bs"); jw> _es=symget("_es"); jw> jw> if _bs<=1 & 1<=_es then do; jw> submit continue; jw> proc format;value af 1='a' 2='b';run; jw> endsubmit; jw> end; jw> jw> if _bs<=2 & 2<=_es then do; jw> submit continue; jw> proc means data=x.file;var &_vrun;run; jw> endsubmit; jw> end; jw> return;

Here is Joe's usage code.

jw> %let _bs=1; jw> %let _es=2; jw> jw> libname x "/users/x"; jw> jw> %let _vrun=a; jw> dm 'af=x._overrun.scl'; jw> jw> %let _vrun=b; jw> dm 'af=x._overrun.scl';

One thing I find immediately apparent is the loss of a clear set of parameters. When I read

libname x "/users/x"; %_overrun(_vrun=a);

I know that default parameter values are being used for all parameters except _VRUN. When I read

%macro _overrun(_bs=1,_es=2,_vrun=);

I know exactly what the parameters are and how the default values have been set.

When I read Joe's code I know none of this. In fact, I do not even find an awareness that the example made use of default parameters. For me the clarity of parameterization is essential! Hence I think, Joe, should rewrite the code to show these features and include the equivalent of the calls

%_overrun(_bs=0,_vrun=) %_overrun(_es=3,_vrun=)

before one is in a position to make a reasonable judgment on the superiority of SCL code to macro code in all cases.

I think this point is very important because my current understanding of SAS/AF is that it was designed to interact with a user providing information from a GUI-form. While I see an important feature of macro as it's ability to organize a batch SAS program in a structured manner.

Are global macro variables essential to fitting SAS/AF into macro shoes? Joe suggested:

jw> If one wanted to avoid even Macro variables the key word jw> parameters could be passed in a stored SCL list, text file, jw> SAS dataset or almost any other file structure accessible jw> to the SAS System. You could also eschew both of the PROCs jw> in favor of SAS Component Language functions. Thanks for jw> the example.

Since the point is important for program clarity, I think in the example code, Joe should show exactly what is entailed adopting each of these possibilities, particularly in a batch environment. At present, I find it disturbing that for his first cut at this example he chose global macro variables to solve the user/tool communication problem.

Ian Whitlock

PS. Normally I would not want to change the subject line, but I think it particularly important here to have a more meaningful subject line, since these messages are not a simple answer to a specific problem.


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