In reply to Peter Lancashire.

If I may, a small comment about "why not explicitly declare a macro to be a pure function (only macro code) or any collection of SAS code".

When you look at %macros, which are in their design wrappers for (any possible) SAS code, you can see that they are something far more general than just functions.

With the advent of DoSubL() function this distinction about "pure" macrocode vs. "not pure" is less and less relevant. You can embed all groups of datasteps and procedures inside a macro and still have it work as a "pure macro code". If you look at the example in my previous comment the macro presented there can be executed inside another datastep and it will behave like a "pure macro function" even tough it contains datastep code.

data _null_;
array test[%nobs(dset=SASHELP.CARS, result=NOBS)];
d = dim(test);
put d=;
run;

About "function return type" - since for the macro language everything it digest is a text (in fact the text of our code) also the result it returns is only a text (which is then compiled and eventually executed) :-)

All the best
Bart