Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ProceduralMacros

Macros for Macaulay2, written in Macaulay2: code that writes code before it runs. Inspired by Rust’s procedural macros, and still very much an experiment.

needsPackage "ProceduralMacros"

runSource ///
$defineRecord PackageRelease(makePackageRelease; releaseName, releaseVersion) $
///

turns into

PackageRelease = new Type of BasicList
makePackageRelease = (releaseName, releaseVersion) -> new PackageRelease from {releaseName, releaseVersion}
releaseName = value -> value#0
releaseVersion = value -> value#1

expandSource shows the expansion without running it. Two macros come built in: defineRecord and inferReturns (which adds return types it can work out).

Your own

Declarative, a pattern and a template:

declMacro("double", "'e", "2 * ('e)")

'x is a metavariable, 'x:Number a typed one, '{…}+ repeats.

Or procedural, a function from the parsed input (a token tree from M2’s own parse) to new tokens:

installMacro("myMacro", ts -> ...)

For bigger things there are typed syntax-tree views with visitors and folds, and visualizeTree when you’re lost.

Install

installPackage "ProceduralMacros"

Needs M2 1.26.05+ (the first one with parse).

Watch out

  • load / needs don’t expand macros, so use value openIn "file.m2"
  • templates don’t add parentheses for you
  • the API will change

Prefer Rust? m2-syn does macros with a typed tree and quote-style templates.

Repository