Search code examples
sassas-macro

(SAS) Passing a function as an argument to a function (or macro)


In a modern language (e.g.python), you could do something like

def do_a_thing(foo,bar):
    thing = (... do a thing to foo(bar) ...)
    return thing

How does one do this (or something similar enough) in SAS? In my concrete application I have defined a bunch of functions, and need to do the same thing to all of them, so I thought it would be nice to have a function that takes a function as an argument and then does the thing to that function, and then apply it where needed. The "obvious" solution doesn't work, e.g. in a proc fcmp doing this:

function do_a_thing(foo,bar);
    thing = (... do a thing to foo(bar) ...)
return(thing);
endsub;

This fails because SAS doesn't know about any function called foo, and throws an error.

I expect the answer involves some macro trickery, but I find the macro system somewhat opaque and can't quite figure it out. What's the best way to do this?


Solution

  • You haven't really shown an example where this might be required (or even useful).

    But in general in SAS you would use code generation to implement that type of mis-direction. For example your second "function" could be a statement style macro. That is macro that only emits part of a statement to be included into the actual SAS program you want to create.

    %macro do_a_thing(function,arglist);
      &function(&arglist)
    %mend;
    

    Then you might use it in a program

    data want ;
      set have ;
      mean = %do_a_thing(mean,of _numeric_);
      std = %do_a_thing(std,of _numeric_);
    run;
    

    For more complex things you will have more trouble. The new-ish DOSUBL() function might help in that they can allow you to run multiple steps in a separate execution space. But for most things the performance cost might be too high to make it worth while.