Go Back   Rhinocerus > Newsgroup > Newsgroup comp.soft-sys.sas

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 06-27-2006, 07:59 PM
Gregg P. Snell
Guest
 
Posts: n/a
Default SCL Joe (was RE: macro structure)

Joe,

You remind me of Baghdad Bob, a/k/a the former Iraqi Information Minister
Mohammed Saeed al-Sahaf. It was utterly amazing to watch him on TV shouting
quotes like "There are no American infidels in Baghdad. Never!" even as you
could see American soldiers in the background (lots more here
http://www.welovetheiraqiinformationminister.com/). He definitely had a
message to get out and he stuck with it! You don't happen to wear glasses
and a green beret, do you? ;-)

Gregg

-----Original Message-----
From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of Joe
Whitehurst
Sent: Tuesday, June 27, 2006 1:46 PM
To: SAS-L@LISTSERV.UGA.EDU
Subject: Re: macro structure

Jim,

You remind me of Wilhelm Reich with your wonderment about the antiquated
macro language. Wilhelm, apparently seized by some kind of "'will to
believe" was lying in a field one day and became totally convinced that he
was seeing "energy" (which he called the" Orgone") beaming down from the
blue (sure enough, if you lie on your back and look up at a clear blue sky
you can see events happening).. He immediately introduced it into his
practice which led to his dying in jail of heart failure after his quackery
was uncovered by the FDA and prosecuted by the government. Your Orgone is
your view of the topic of this thread: nested macros. Once again, I 'm
compelled to agree with Ian.

Joe

On 6/27/06, Jim Groeneveld <jim2stat@yahoo.co.uk> wrote:
>
> Hi Ian,
>
> Nested macros:
>
> Well, I just explained an example without providing concrete code. It
> boils down to conditionally generating partial (SAS) code into macro
> variables or (to be nested) macros. Finally these macro variables and
> nested macros are placed in order in a macro for execution. I could
> show you my macro CROSSTAB, but I didn't make it available yet on my
> website as it still has to be adapted quite a lot before being able to
> be used as a general macro. And I estimate it still wil take quite
> some time before I think it can. I am currently not improving the
> macro and I don't have the time to do so. But if you are interested I
> could send it to you as it is now (100 kB).
>
> Anyway, while applying nested macros I have to add that I never call
> those nested macros outside the main macro(s) in which they are
> (conditionally) defined. The main macro knows of their existence and
> contents. Outside them I do not know of them (though I indeed could
> call them knowing their name). It only makes sense to use them at the
> level where they have been defined, just like macro variable values.
> In this context I don't conceptually discriminate between a nested
> macro and a macro variable value. I only choose one of them based on the

complexity of the contents.
>
> Anyway a very brief outline:
>
> %MACRO Crosstab (.........);
> %IF (condition) %THEN %LET MacroVar = something; %ELSE %LET MacroVar =
> something else; %IF (other condition) %THEN %DO;
> %MACRO Nested (either with or without arguments);
> %* complex macro and SAS code here;
> %MEND Nested;
> %END;
> %ELSE %DO;
> %MACRO Nested (either with or without arguments);
> %* other complex macro and SAS code here;
> %MEND Nested;
> %END;
> PROC REPORT DATA=..............;
> &MacroVar /* no semicolon */
> DEFINE ...............;
> %Nested (......) /* no semicolon */ RUN; %MEND Crosstab;
>
> Conditional macro development:
>
> The very simplified code you provide indeed produces the same results.
> But you do not make use of a conditionally generated macro. That's
> fine, but that isn't the purpose of this discussion. I wanted to
> demonstrate quite briefly some simple code to generate a macro (or
> partial macro code) conditionally. My example, where I call the
> generated macro outside the scope of the generating macro:
> >%GenMacro (MetaVal=1);
> >%MacroGen (Value=1);
> >%MacroGen (Value=2);
> >%GenMacro (MetaVal=2);
> >%MacroGen (Value=1);
> >%MacroGen (Value=2);

> of course is not the best example. It is for demonstration purposes
> only, but I think here too one would only call the generated macro
> from within the generating macro, i.e. at the same level.
>
> Like you I cannot think of a suited application of such conditionally
> generated macro code (yet). But I found it intriguing and funny to
> experiment somewhat with the macro language and discovering new horizons.
>
> Jim>Well, I know this is rather complicated, but it works anyway.
> Ian>Hence, I spent far more time trying to understand you examples
> Ian>than I did replacing them with simpler code.
> ... and isn't that quite often true on SAS-L?
>
> See you again on SAS-L, regards - Jim,
> --
> sig known
>
> On Tue, 27 Jun 2006 14:56:46 +0000, Ian Whitlock <iw1junk@COMCAST.NET>
> wrote:
>
> >Jim,
> >
> >I cannot comment on whether your CROSSTAB macro could be better
> >written without nested macro or not.
> >
> >Your MacroGen could have been hard coded as
> >
> > %MACRO MacroGen (Value=);
> > %LOCAL MacValue;
> > %IF &Value EQ 1 %THEN %LET MacValue = &MetaVal.1;
> > %ELSE %IF &Value EQ 2 %THEN %LET MacValue = &MetaVal.2;
> > %PUT MacValue = &MacValue;
> > %MEND MacroGen;
> >
> >This shows that METAVAL is a hidden unnamed parameter to MACTOGEN.
> >When I ran the code you gave below, I got the following log.
> >
> >35 <macro code not shown>
> >36 %MacroGen (Value=1);
> >MacValue = 11
> >37 %MacroGen (Value=2);
> >MacValue = 12
> >38 <different macro code not shown>
> >39 %MacroGen (Value=1);
> >MacValue = 21
> >40 %MacroGen (Value=2);
> >MacValue = 22
> >
> >METAVAL can be considered a hidden parameter since it determines how
> >MACROGEN will act. So I wrote the equivalent system.
> >
> >41 %macro macrogen(metaval=1,value=1) ;
> >42 %put macvalue = &metaval&value ;
> >43 %mend macrogen ;
> >
> >and got
> >
> >45 %MacroGen (metaval=1, Value=1);
> >macvalue = 11
> >46 %MacroGen (metaval=1, Value=2);
> >macvalue = 12
> >47 %MacroGen (metaval=2, Value=1);
> >macvalue = 21
> >48 %MacroGen (metaval=2, Value=2);
> >macvalue = 22
> >
> >The method hints at great power, since it does allow you to generate
> >some macro code. But it is far from clear whether that power is
> >useful or any better than adding sufficient parameters and using good
> >traditional techniques.
> >
> >Consider the macro code.
> >
> > %let place = there ;
> > ...
> > %goto &place ;
> >
> >It illustrates the power of one %GOTO statement to go to any named
> >place

> in
> >a macro. On the other hand, I hope everyone realizes that this power
> >has danger of making code unreadable because a variable now controls
> >the

> location
> >and in practice probably doesn't add all that much in practical power.
> >The ability, to change the meaning of a macro call by generating

> different
> >macro instructions, looks very similar to me. It can create
> >unreadable code very easily because the meaning of the same code
> >changes in various parts of the program. However, I also realize
> >that from the SAS point of view a macro generates different forms of
> >SAS code. The difference is

> that
> >it is somewhat controlled and the local instructions tell the story
> >about the generation of the local SAS code. In your case one has to
> >read the

> code
> >for GENMACRO in order to know what the second call means in the lines
> >
> > %genmacro( metaval=1 )
> > %macrogen( value=1 )
> >
> >Hence, I spent far more time trying to understand you examples than I
> >did replacing them with simpler code.
> >
> >Ian Whitlock
> >==================
> >Date: Mon, 26 Jun 2006 06:57:35 -0400
> >Reply-To: Jim Groeneveld <jim2stat@YAHOO.CO.UK>
> >Sender: "SAS(r) Discussion"
> >From: Jim Groeneveld <jim2stat@YAHOO.CO.UK>
> >Subject: Re: macro structure
> >Comments: To: Ian Whitlock <iw1junk@COMCAST.NET> Hi Ian, Thank you
> >for your elaborate explanation. Of course you are right about the
> >pros and contras of nested macros. I in general do agree with them.
> >However, it seems I have failed to explain my application of nested

> macros
> >sufficiently clear. So I will present the layout of my macro CROSSTAB
> >(under development) somewhat more concrete, but yet in general terms:
> >The macro CROSSTAB is designed to create multi-dimensional cross
> >tabulations with many options. It accepts many parameters, among
> >which

> one
> >to nine variable parameters, indications whether counts, (sub)totals
> >and various percentages are wanted, how missings per variable are to
> >be treated, whether one variable should be an across variable, the
> >width and decimals per column and many more bells and whistles. It
> >builds PROC REPORT SAS code with many conditional parts: variables
> >named on the

> COLUMN
> >statement, the DEFINE statements and its options, COMPUTE blocks,
> >BREAKs and many more.
> >Now before actually starting the PROC REPORT I already prepare
> >conditionally building parts of its code into macro variables or
> >NESTED MACROS (there you have them). I want to build all parts
> >belonging to a specific dimension (and a specific layout: an across
> >variable or not) together in one %IF %THEN %DO %END block, which is
> >quite logical and readable. E.g. a nested macro %CompBloc is being
> >built conditionally, but most of such SAS code parts are small and
> >contained in separate macro variables instead of nested macros.
> >In the PROC REPORT code the various macro variables and nested macros
> >are parsed and cause the desired PROC REPORT to be built and run,
> >while its basic code with all the macro variables and nested macros
> >is quite short and readable. I think this is a very appropriate
> >application of nested macros, though it of course can be done without
> >it. My "{many statements};" part is very complex and large and by
> >building and calling it in pieces, in modules it remains surveyable.
> >And of course you may keep disagreeing with me even on this
> >application

> of
> >nested macros. I presume you have your good reasons, of which the
> >main

> one
> >is, that it all can be done without nested macros. And yes, that is
> >true, but as with many other solutions, the choice for a specific
> >design may be to improve readability and quality. So I don't rule out
> >nesting macros in all cases, though I generally also would recommend
> >to avoid them if (and as far as) possible. If we do disagree at all,
> >I think we don't disagree much, we mainly agree and may disagree on this

specific exceptional case.
> >Now something else:
> >The nested macros that I discussed above generate SAS code
> >conditionally and (thus) also contain their own macro statements,
> >along with their definitions. So the nested macro code itself is
> >fixed, while the SAS code to generate is variable / conditional. And
> >you said "you cannot generate part of a macro with a macro" or rather
> >one can not generate (partial) conditional macro code for another, nested

macro code.
> >Well, I have been thinking about that and came to the conclusion that
> >it is actually possible to have a macro, not even a meta-macro
> >language, generate conditional pieces of macro code for a nested
> >macro to define. I did not think of a suited application yet, but the
> >following code demonstrates the possibility. In there the main macro
> >is GenMacro that conditionally generates the macro MacroGen. The
> >MacroGen code initially

> is
> >generated and stored as inactive (quoted) code in a macro variable,
> >in

> one
> >example as a complete macro and in another example as various pieces
> >of inactive macro code. Later in the main macro the GenMacro code is
> >being parsed, whether as a whole or as a collection of pieces.
> >Dependent on the MetaVal value of GenMacro, either 1 or 2, the macro
> >MacroGen is built as

> a
> >whole or from pieces and also produces slightly different results.

> Running
> >the nested macro at the upper level shows the different result values.
> >%MACRO GenMacro (MetaVal=);
> > %LOCAL Variable MacStart MacEnd;
> > %IF (&MetaVal EQ 1) %THEN %LET Variable = %NRSTR(
> > %MACRO MacroGen %(Value=%);
> > %LOCAL MacValue;
> > %IF &Value EQ 1 %THEN %LET MacValue = 11;
> > %ELSE %IF &Value EQ 2 %THEN %LET MacValue = 12;
> > %PUT MacValue = &MacValue;
> > %MEND MacroGen;
> > );
> > %ELSE %IF (&MetaVal EQ 2) %THEN %DO;
> > %LET MacStart = %NRSTR( %MACRO MacroGen %(Value=%); );
> > %LET Variable = %NRSTR(
> > %LOCAL MacValue;
> > %IF &Value EQ 1 %THEN %LET MacValue = 21;
> > %ELSE %IF &Value EQ 2 %THEN %LET MacValue = 22;
> > %PUT MacValue = &MacValue;
> > );
> > %LET MacEnd = %NRSTR( %MEND MacroGen; );
> > %END;
> > %IF (&MetaVal EQ 2) %THEN %PUT MacStart = &MacStart;
> > %PUT Variable = &Variable;
> > %IF (&MetaVal EQ 2) %THEN %PUT MacEnd = &MacEnd;
> > %IF (&MetaVal EQ 1) %THEN %DO;
> > %UNQUOTE(&Variable) /* no semicolon */
> > %END;
> > %ELSE %IF (&MetaVal EQ 2) %THEN %DO;
> > %UNQUOTE(&MacStart &Variable &MacEnd) /* no semicolon, see
> >comment below */
> > %END;
> >%MEND GenMacro;
> >%GenMacro (MetaVal=1);
> >%MacroGen (Value=1);
> >%MacroGen (Value=2);
> >%GenMacro (MetaVal=2);
> >%MacroGen (Value=1);
> >%MacroGen (Value=2);
> >This is the "comment below":
> >Here one can not state:
> > %UNQUOTE(&MacStart)
> > %UNQUOTE(&Variable)
> > %UNQUOTE(&MacEnd)
> >because once the first piece of code is parsed the other pieces can
> >not

> be
> >parsed any more at that point, but are being parsed at runtime of the
> >nested macro. This causes ERRORs and unment program flow, as the
> >nested macro initially does not even have an %MEND statement.
> >Well, I know this is rather complicated, but it works anyway.
> >Regards - Jim.
> >--
> >Jim Groeneveld, Netherlands
> >Statistician, SAS consultant
> >home.hccnet.nl/jim.groeneveld

>

Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Macro Quoting Question Kevin Morgan Newsgroup comp.soft-sys.sas 1 07-06-2007 02:47 AM
Re: Macro Quoting Puzzle!!! Ian Whitlock Newsgroup comp.soft-sys.sas 0 05-28-2007 03:41 PM
Re: macro structure Fehd, Ronald J. Newsgroup comp.soft-sys.sas 0 06-29-2006 08:03 PM
Re: Understanding How Macro Processor Works Terjeson, Mark Newsgroup comp.soft-sys.sas 0 03-24-2006 11:00 PM
Re: MAcro Design was (Re: Macro quoting essentials) Ian Whitlock Newsgroup comp.soft-sys.sas 3 12-11-2005 11:18 PM



All times are GMT. The time now is 07:32 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.