I’ve been thinking about how to cleanly implement some form of hygienic macros for OCaml. Specifically, I’m thinking about how to implement something like Rust’s macro_rules
. The problem there, is that the objects the macros manipulate are “token-trees” – streams of tokens, structured into trees at “()”, “”, “{}”. Now, it would make sense to stick to syntax that fits with OCaml’s PPX, so one would want there to be some form of PPX extension, that specified that the payload was a token-tree stream. Today, the payloads can be: structures, signatures, patterns, types. Strings/expressions enter as structures.
None of these work for hygienic macros implemented in the style of Rust: they require that the result of macro-expansion be re-parsed, and it can easily be the case that the syntactic category of a token-tree argument to a macro (is “a * b” a type, or an expression?) cannot be inferred until that final parse. So it would seem that one would need a new kind of payload for PPX extensions – a token-tree. Viz.
[%foo! (a, b,c)]
where the “!” indicates that the payload is a token-tree stream bounded by that closing “]”.
One might ask “why not use a string payload” as in
{%foo|(a,b,c)|} (which is shorthand, if I’m remembering the syntax right, for [%foo {|(a,b,c)|}]
and the answer is that in nested macro-invocations, we would want to rename any hygienically-created identifiers, but that will be difficult if they are embedded in string payloads. It would involve repeated parsing/renaming/stringification. A big mess, and hard to keep location information consistent (for debugging).
In Camlp5, I can sidestep all of this, b/c I can extend the syntax in arbitrary ways, but obviously if hygienic macros are going to be useful, they’ll need to be implemented with the current PPX infrastructure; hence my question to you all.
I’d welcome any feedback.