An Idea Exchange for SAS software and services

by PROC Star
on ‎05-21-2013 10:12 PM

I really like the suggestions for MACROCREATE and %INTERNAL scope.  I guess between the two, MACROCREATE seems like a "nice to have" that would help me catch cases where I accidentally forget to define the scope of a macro var.  But %INTERNAL would be even more useful.  It would mean that I could safely call any macro from within my macro, without worrying that the called macro will clobber my macro's macro vars.  If %INTERNAL existed, I would probably use it 95% of the time.    I'm having trouble coming up with a situation where %STATIC would be useful, but perhaps I'm just not imaginative enough.

by Contributor Peter_L
on ‎05-23-2013 04:24 AM

Thanks for the support. I have updated the idea to explain the advantages of %STATIC scope. It's defensive programming - it seems unimportant until you try to fix a problem with tangled global variables, when you wish you'd had it. Global variables and macro languages are well-known for causing problems. It's no accident that Java did not inherit the macro pre-processor from C.

I also realised that declare-before-use must take account of lists of variables generated by PROC SQL.

by Super User
on ‎05-23-2013 09:24 PM

I am not sure this is feasible, or adds that much value, for such a dynamic interpreted "language" as SAS macro.

You might be better off looking into the new DS2 language that SAS is developing.  That should be closer to the type of compiled languages were it is possible to enforce such rules.

by Contributor Peter_L
on ‎05-24-2013 09:50 AM

So far as I can see, the new DS2 language is to replace the data step. It has a different role from the macro language. It is precisely the dynamic interpreted nature of the SAS macro language that leads to problems when programs get big. Even a small amount of extra support for scope limitation and reduced side effects would be very helpful. I think at least parts of this suggestion would not be too difficult to implement.

by Regular Contributor
on ‎05-26-2015 04:10 PM

Ron Cody asked a question which your %static statement would solve.

iirc: How do I pass the value of macro variable data from one global macro to another?

%macro one(data=sashelp.class);

*... etc;

%mend one;

%macro two(two_data=&data)

*... etc;

%mend two;

The kludges suggested on SAS-L were

1. global data

2. a data set to contain a set of macro variables and values

This 2nd suggestion would be easy to implement with sql from dictionary.macros

proc sql; create table saved_macro_variables as

select * from dictionary.macros where scope eq 'LOCAL';


in macro two, 'fluffing' --- or rehabilitating --- can be done with call execute

data _null_;

set saved_macro_variables;

call execute(catx(' ','%let',name,'=',value,';'));


Ron Fehd  macro maven

by Trusted Advisor
on ‎05-28-2015 02:54 PM

I believe the request for %STATIC, i.e. a definable constant-value macro variable is already delivered.

(in 9.4)


It is the same for %LOCAL, as well.

by PROC Star
on ‎05-28-2015 03:26 PM

I don't think  /READONLY accomplishes what was proposing.    (I had hoped it might!)  As I understand it, /READONLY means what it says, the value of the macro variable can only been written to once.  I think the proposed %INTERNAL and %STATIC would allow the value of a macro variable to be updated as needed when the updates are made within the macro that created the macro variables.  But they would prevent the value from being updated from outside of the current macro (nested macro scopes).  So they would avoid the problem where a helper macro fails to declare its macro variables as %local, and then when it execute its macro variable assignments collide with an outer scope.

Currently, when you call a macro, there is no way to protect yourself from that macro contaminating your current macro symbol table(s).  You need to trust that the macro developer has been careful to declare everything to be %local.

by Trusted Advisor
on ‎05-28-2015 05:26 PM

Peter Lancashire wrote:

[...] values would persist between macro calls [...] The %STATIC statement would have to allow the setting of a default constant value.

The way I read this is that %STATIC is a CONSTANT, at the global scope...  and as such, already exists.

%INTERNAL would equate to a 'private' variable at the most local scope, this is different as the values are not constant (aka static...) but provides a level of protection to the variable from outside influences.

I would expect, without modifying current syntax too dramatically a better way to look at %INTERNAL would be like:

%LOCAL / PRIVATE variable_name <= default_value>;

As thoughtfully pointed out on a different Idea, there may well be many people out there already with macros called '%INTERNAL', and it is important to be mindful of such.

by Contributor Peter_L
on ‎05-29-2015 06:52 AM

Thanks for the interest in this suggestion.

No, %STATIC declared in a macro is not visible at all in global scope, it is private to the macro and persistent. It could have the same name as a global variable and not interfere with it.

If SAS has chosen to add /OPTION as a standard syntax to extend or modify the meaning of macro statements, then your suggestion of %LOCAL /PRIVATE seems good to me: it is clear what it should mean. Similarly, one could have %LOCAL /STATIC, or if it seems clearer, %LOCAL /PERSISTENT. The important thing is clarity and consistency with other usage in SAS if possible, if not already in SAS then with other well-known languages. The last thing we need is another term or syntax to learn. (SAS: note your function names!)

by Frequent Contributor
on ‎05-29-2015 10:45 AM

I think PROC LUA will be a better long-term solution.  It's a structured language in a way that the current macro language is not.  For old-time MVSers, it's like the difference between CLIST and Rexx.

LUA can't currently create macros, but I hear it's a future goal. It might happen as quickly as a change to the macro language could be approved.

Idea Statuses
Top Liked Authors