Macro

This entry is mainly focused on programmatic macros as seen in Clojure. There are also textual macros which I am ignoring.

A macro is a part of code which is converted to new code before execution. It may be used to extend the syntax of a language. Most imperative languages have some form of loop, but creating a new type of loop in a language like Javascript would require runtime execution of code inside of functions. Imagine that the for loop never existed in Javascript. We could create one as a function, but its use would be verbose.

// for loop
for (var c = 0; c < list.length; c++) {
	// do something
}

// as function
var c = 0
for(() => c < list.length, () => c++,
	() => {
		// do something
	})

We are forced to constantly wrap all of our expressions in arrow functions so that their execution may be controlled and their results collected. The for function also has no control over the context of variables. We were still not able to fit our c declaration statement into the function call, as any variable declared in an arrow function would not be accessible to the other arrow functions.

A macro solves all of these problems by running a function (the macro) at compile time. The macro is given any nested expressions as trees of syntax, and may return a new tree of syntax which will replace the macro reference in the code before the final step of compilation. If our for loop was a macro, we could leave the the conditional and incremental statements as lone expressions, which the macro would place in the proper position to be executed repeatedly at runtime. The macro could even be given the declaration expression, which it could position such that the scope matched with the other expressions.

#software