%length is a very special macro function, it can take ant numbe of
comma (,) without any problem. Thus,
%let x = a, b;
will run fine. The result is 3.
Ian Whitlock wrote:
> Subject: Macro quoting essentials
> Summary: Short lesson on practical macro quoting
> Respondent: Ian Whitlock email@example.com
> After reading the discussion under the subject "%upcase", I think it is
> time to look at macro quoting from the practical point of view.
> There are two timing issues with macro quoting. Sometimes a symbol must
> be hidden at macro compile time and some times at macro execution time.
> Hence there are two important classes of functions.
> 1) compile time quoting - %STR and %NSTR
> 2) execution time quoting - %SUPERQ and all other quoting functions
> Symbols hidden at compile time stay hidden at execution time unless
> explicitly or implicitly unquoted, so %STR and %NSTR solve most quoting
> problems. At compile time the usual problem is hiding a semi-colon,
> %macro q () ; /* version 9.1.2 + */
> %local boundary ;
> %let boundary = %str(run ;) ; %* need semi-colon in the value
> but %let must not set it at
> compile time;
> %put &boundary more ;
> %mend q ;
> If one is writing messages that involve %-signs and ampersands then %NRSTR
> is needed. (NR stands for no-re scan, i.e. evaluation of macro triggers.)
> Actually, in a macro there is no need to hide these symbols at compile time
> since no resolution or macro execution takes place at compile time. But it
> is more convenient to hide these symbols at compile time, and let them stay
> hidden at execution time.
> The use of the compile time functions is indicated whenever one is typing a
> symbol that must be hidden at some time. This covers the vast majority of
> Since there is no need to hide most symbols at compile time, it can happen
> that a variable's value must be hidden at execution time. The chief reason
> is that %EVAL (implicitly called by %IF and in any place where a number is
> expected by the system) assumes meaning for arithmetic, logical, and
> comparison symbols that may be unwanted in some situation. Such cases can
> usually be covered by the use of %SUPERQ, which hides everything and takes
> the variable name as its argument instead of the variables value. For
> example, %SUPERQ(X), is the quoted value of &X, while %SUPERQ(&X) is the
> quoted value of the variable named by &X.
> At execution time there may also be a need to hide commas. For example,
> %let x = a,b ;
> causes no problem, but
> will cause a problem at execution time because the %LENGTH function cannot
> have two arguments.
> %let x = %str(a,b) ;
> provides the simple compile time solution, and
> provides an execution time solution.
> There is still one more important case. Sometimes one wants to hide a
> quote mark so that a macro expression can be evaluated inside single
> quotes. Since the symbol is known, as opposed to being in the value of a
> variable, one would like to use a compile time function; but %STR and
> %NRSTR do not hide quote marks. In this case, the %-sign acts as an escape
> character; hence %STR(%') is a hidden quote mark.
> It is important to note that quoting is implicitly removed in the return
> value of macro functions that do not begin with a Q. The ones that begin
> with a Q apply quoting to the returned value. To prove that Q-functions
> apply quoting rather than not removing it, you could execute
> %put %length(%qupcase(a,b)) ;
> and see that it works. To prove that previously applied quoting is removed
> by Q-functions you can take advantage that 10 is maximum depth of quoting
> and study the execution of
> %macro q ( n ) ;
> %local i w ;
> %let w = %str(a,b) ;
> %do i = 1 %to 20 ;
> %let w = %qupcase (&w) ;
> %end ;
> %put >>>>&w<<< after 20 qupcases ;
> %do i = 1 %to &n ;
> %let w = %superq (w) ;
> %end ;
> %put >>>>&w<<< after &n bquotes ;
> %mend q ;
> When macro time quoting is applied, it may be necessary to explicitly
> remove that quoting at execution time with %UNQUOTE. The most common
> example is when single quote marks are needed around the value of a macro
> %let x = something ;
> %put %eval(%unquote(%str(%')&x%str(%'))='something') ;
> The old proverb, "If it looks good but doesn't work apply %UNQUOTE" is
> still worth while because there are times when the macro facility leaves
> a token in pieces and %UNQUOTE can glue those pieces back together.
> I think that the above covers all the important practical facts of macro
> quoting. The "other execution time functions %QUOTE, %NRQUOTE, %BQUOTE,
> and %NRBQUOTE can be left to those more interested in macro quoting than
> writing practical programs. In fact I would suggest that a required use of
> these tools is probably an indication that the design is bad or that macro
> is the wrong tool for the application.
> I am interested in evidence to the contrary.