Script builder library (Part 1)

A macro is a reporter that reports a chunk of code (this is why your work is interesting) which is then evaluated in the caller in place of the macro call. This doesn't matter if the code just computes some function. Macros are needed when you want to change the flow of control of the caller, or declare script variables in the caller.

So, for example, Snap! ordinarily initializes new variables with the value 0. Let's say I want to make a bunch of local variables and initialize them all to empty lists. I write this block:


(using blocks from the Create Variables library). My idea is to call it from other blocks, like this:

But it doesn't work! Why not? Because a, b, and c are declared as script variables of the block SCRIPT LIST VARIABLES, not of the block FOO.

So instead I have to make SCRIPT LIST VARIABLES a macro (we don't have a notation for that yet) that does this:


(I've made this a reporter because all macros are reporters, but really I want the hat block to say that it's a command macro, because what it reports is a script, rather than an expression.) Now, when FOO calls SCRIPT LIST VARIABLES, the script in the gray ring will be evaluated inside FOO, right where the macro call is. In effect the macro call is replaced by whatever the macro reports. So now the script variables are declared inside FOO, not inside SCRIPT LIST VARIABLES.

Does that make sense? If not, try to ask a question that helps me see where you're lost.

EDIT: Oh, whoops, if you're lost it's my fault, because I neglected to mention that the variable VARS is local to SCRIPT LIST VARIABLES, so it's not obvious why I can use it in the code that the macro reports, which will be evaluated in a different procedure that doesn't have a variable VARS. The answer is that the gray ring doesn't just encapsulate the code; it also remembers the environment in which it's made, in this case the environment of SCRIPT LIST VARIABLES, which includes its input variable VARS.

1 Like