Create a gist now

Instantly share code, notes, and snippets.

More thoughts on macros

So, jnthn++ and I were discussing macros, deciding where to start implementing them. The discussion derailed into a general discussion of how macros and quasis work underneath, though. Here's what we arrived at:

  • A quasi is parsed into something like a call to a lambda expression, with the {{{$a}}}-style variables being passed into it.

  • The macro arguments are constrained by what you can express as an AST clade. In other words, they have to be valid expressions. You can't do this:

    mymacro(+); # WRONG

  • Things like class declarations among the macro arguments, which cause BEGIN- time "events" to occur (such as registering the class in the package) will happen normally, even if the eventual result of the macro doesn't contain the original class declaration.

  • On the other hand, any routine or type declaration inside a quasi is registered at parse-time as an event in the quasi, but nothing more than that. When the quasi is spliced into the mainline code, the stored events are replayed, which causes grammar actions to be called and symbol tables to be updated.

  • If a different slang is in effect when the quasi is reified as opposed to when it was parsed, note that the actions run are those that were in effect when the quasi was parsed. This means that slang authors will have to be a bit mindful about action composability.

  • We're thinking it's better to have an opaque Perl6::AST object rather than a tree of Perl6::AST::Node objects. The Perl6::AST object is a facade to the implementation's AST, and exposes a lean, standardized interface that doesn't commit to too much.

  • make quasi { [...] } is nice for people writing slang action methods. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment