Date: Sat, 14 Jan 2006 20:07:04 +0000
Reply-To: iw1junk@COMCAST.NET
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Ian Whitlock <iw1junk@COMCAST.NET>
Subject: Re: Why not use macros ?
Alan,
I took a look at the CodeSmith site, since you suggested it. It looks like
a system to create a series of code templates to be modified. I spend the
time thinking about my program when I type the equivalent of a template.
If I had to search for the appropriate template instead, I think I would
lose this valuable thinking time and the quality of my programs would
rapidly degenerate. A look at the example on your site only convinced me
more that I should avoid it. Moreover, I do not see my programs as a
series of templates. When I studied LISP, I read that a good LISP program
contains no pattern because the language has the ability to remove
redundancy. I tend to think SAS and macro provide the same sort of power.
However, I can see how this tool might be good for some programmers, so it
is worth each person's consideration.
In a message to Harry you mentioned C# is free so I searched for a free copy
but didn't find it. Did you mean that you pay Microsoft enough for other things
that C# is free? Or can you point to where it is offered free? You also
mentioned the advantage that C# supports OOP. It would be interesting to
see examples where OOP pays off in code generation.
Now let's turn to a closer look at your example of DATA step that presumes
to imitate macro, and its companion in C#. You start with a 7 lines of
pseudo SAS code which if it were real code could be run in SAS to produce a
result. You then introduce 10 lines of pseudo C# code. I assume that the
C# code has to be compiled, then one has to execute the executable, locate
the code generated SAS code, and finally SAS execute it. As written you
either forgot to generate the INCLUDE in the C# program, or intended still
another step to find the written-written SAS code to be executed. This
does not look like an improved structure for developing SAS code to me. I
also note that the call in MAIN to BuildDataStep(10) seems somewhat
disconnected from the following function, BuildLibraries(int x).
Let's look at the finer details as related to imitating SAS macro. In the
pseudo SAS code you have a simple DO-loop writing the code.
do i=1 to 10 ;
put "some sas code" ;
end ;
Even if we consider this pseudo, it is highly misleading. I have almost
never used a macro to generate simply copied constant text and certainly
not programs that could be written in a simple DO-LOOP. Perhaps you also
forgot an ARRAY statement,
array code (10) _temporary_
( "first line;" ... ) ;
and the apparatus for making substitutions in each of the lines. With
these corrections we have arrived at the beginning step of learning macro,
i.e. learning to write parameterized units of SAS code. However, this is
still very far from the way a mature SAS programmer would write most
macros.
I think there is a place for using DATA steps to write SAS code, but I do
not think it is to replace macros. I wrote a lot of such steps from 1981
to 1984 when the macro language was introduced, so I think I have a good
idea of how the technique can accomplish what macros do. However, I
usually found the programs much harder to develop and later to read using
that technique, so I find it better left to special purposes. I do use
CALL EXECUTE a lot, but usually to invoke a sequence of macros rather than
to directly generate a lot of code.
Let's assume you have fixed up the C# code to be a little more realistic,
so we can look at the practical side of SAS programming. Of course, there
is some mistake in the code, so the code must be modified and run again.
Now consider going back to that C# code, locating the error in the mass of
required by realism. You mean I have to compile that again, run it again,
find the generated SAS code and SAS execute it again? And repeat that for
every mistake?
I think those of us who chose to use SAS as our main programming language,
chose it, in part, for the rapid turn around of some response to running
and then fixing the code. You seem to have found a method of destroying
one of the most important features of SAS. Or perhaps I have
misinterpreted what you meant to show becasue of your omitted details or my
lack of knowledge about using C#.
The example is still highly misleading because in many macro/SAS programs
the code generated depends on the results of earlier code. So in fact, a
realistic example would require multiple C# programs and extra SAS code to
make the intermediate SAS results available to the next C# program for
generating the next SAS step.
Perhaps we write very different kinds of SAS programs to solve very
different kinds of problems, or perhaps you are a former C programmer who
likes to develop systems for others to use, which happen to involve some
SAS code. Do you work in an environment where the result produced by your
generated SAS code must be in by the end of the day, or is your job to
produce the mechanism by which someone else will later use to generate and
then run the SAS code? When I realize that you have seriously suggested to
a relatively new to SAS, social scientist that he needs to learn C# in
order to upgrade his SAS abilities, I wonder in amazement at the variety of
advice that can be found on SAS-L. Perhaps it would be better to explain
your background and job requirements, and then give examples to show how C#
has enhanced your ability to work under those requirements rather than try
to explain how C# allows you to avoid macro.
I agree that code generation can be done by a number of different
languages, however SAS macro has two distinct advantages which alternatives
must overcome:
1) it keeps the action in one system, SAS
2) macro instructions are embedded in the text manipulated, while most
programming languages, including SAS, require some form of quoting
to distinguish the text data, i.e. generated SAS code, from the
generating language.
I note that special purpose text manipulation languages such as HTML,
XML, and LaTex, which work to display text, all use the same principle that
the instructions are distinguished by special marks rather than the text
data. I suspect that in each case the language would be very much harder
to use had it been developed the other way around. Consequently, I find
macro a pretty good text manipulation language for manipulating bits of SAS
code.
True, SAS macro has been very much abused, but I tend to think this is a
statement about the programmers and their ability to write macro, rather
than about the language itself. Consequently, I concentrate on writing good
macro code rather than avoiding macro. Yes, I have missed some better
programs by writing a macro, but I suspect I would have missed very much
more by following a policy of extreme macro avoidance. Yes, I have written
some tortured macro code, but I have also seen a lot of tortured SAS code
because of a lack of knowledge about macro.
I do think macro solutions appear too often on SAS-L, but usually because
the macros are poorly written and illustrate too many bad design habits, or
because they are aimed at someone who clearly does not have the ability to
understand or maintain the solution. When they are inherently wrong
because they do not do the job, or because macro is the wrong tool, they
are usually corrected with better code or suggestions.
Ian Whitlock
===================
Date: Fri, 13 Jan 2006 16:26:00 -0700
Reply-To: Alan Churchill <SASL001@SAVIAN.NET>
Sender: "SAS(r) Discussion"
From: Alan Churchill <SASL001@SAVIAN.NET>
Subject: Re: Why not use macros ?
Comments: To: Arthur Tabachneck <art297@NETSCAPE.NET>
In-Reply-To: <200601132245.k0DMdMIF013783@mailgw.cc.uga.edu>
Content-Type: text/plain; charset="iso-8859-1"
Arthur,
On snippets, take a look at the video I made showing how they work:
http://www.savian.net/snippets/snippets.html
On the macro side, show me something you can do in macros that you can't do
in datastep.
Data Step Macro Simulation
==========================
data _null_ ;
file somewhere ;
do i=1 to 10 ;
put "some sas code" ;
end ;
run;
%include somewhere ;
C# Macro Simulation (1 possible way of handling)
================================================
public void Main()
{
BuildDataStep(10) ;
}
public void BuildLibraries(int x)
{
Console.WriteLine("data _null_ ;") ;
Console.WriteLine("file somewhere ;") ;
Console.WriteLine("do ;") ;
for(int i=0;i<x;i++)
{
Console.WriteLine("put \"some sas code\" ;") ;
}
Console.WriteLine("end ;") ;
Console.WriteLine("run ;") ;}
}
I use macros but very sparingly. I haven't used them heavily in 10 years
because they were difficult to debug. Things have improved but I can still
debug data step code a lot faster.
Alan
Alan Churchill
Savian "Bridging SAS and Microsoft Technologies"
www.savian.net
-----Original Message-----
From: SAS(r) Discussion [mailto:SAS-L] On Behalf Of Arthur
Tabachneck
Sent: Friday, January 13, 2006 3:46 PM
To: SAS-L
Subject: Re: Why not use macros ?
Alan,
I disagree with your comment about macros not being necessary, but that
isn't why I'm responding. While they may not conform specifically with
code VS2005 "snippets", don't SAS Abbreviations come very close?
For those not familiar with SAS Abbreviations see:
http://support.sas.com/sassamples/papers/0303_saseditor.pdf
Art
----------
On Fri, 13 Jan 2006 15:31:26 -0700, Alan Churchill <SASL001@SAVIAN.NET>
wrote:
>Macros are merely code generators and they aren't necessary. They are
useful
>in the toolbag but you can do the same thing using data step or SCL or a
>host of other technologies.
>
>Awhile back for the Denver SUG, I wrote a paper on using C# to generate
SAS
>as well as using a commercial tool such as CodeSmith to generate SAS.
These
>have drawbacks vis-à-vis macros but they also have some great strengths
that
>macros lack. The whole goal, imo, is to have a number of tricks and apply
>as the situation demands.
>
>I think the most interesting area that people can look at is CodeSmith. It
>can save boatloads of time for repetitive coding. That is until SAS
includes
>'snippets' in the editor similar to what VS2005 has.
>
>Alan