You asked about other work to make these PPX rewriters shorter. I’ve posted about this before ( Quasi-quotations for the OCaml AST and PPX rewriters ), but since then, (a) did a ton more work, and (b) got bored and wandered off before releasing code. But (c) now that OCaml 5.1.0 is coming out, I’m updating everything to work with that. So …
The punchline first: suppose you look at ppx_jsobject_conv
and observe that “wow, it’s complicated”. I would argue that that’s right, b/c it doesn’t use quasi-quotations. But that’s fixable, and at the bottom of this note, I have a link to a project where I rewrote the guts of ppx_jsobject_conv
with quasi-quotations, and it’s much, much more readable. At least, to me. I mean, I get that there are people who think “pervasive quasi-quotations” are useless or ugly or whatever.
So something you could do (or I could do, but I doubt anybody would be interested in it, so why would I bother wasting the effort?) would be to take the enum
deriver you pointed-at, and rewrite it using pa_ppx_parsetree
. Just to show how much more transparent it is. But hey, I already did that wiith the “show” deriver (pointer below) and nobody was interested, so … ah, nevertheless [h/t Atrios].
Now, the short explanation: I’ve been working on something called pa_ppx_parsetree
for a while: GitHub - camlp5/pa_ppx_parsetree: Tooling for doing things with OCaml's official AST
What is it? It’s a package that provides something like ppx_metaquot
, but for every major syntactic category and pretty much every parsing rule of the OCaml grammar, and does so for every version of the OCaml grammar from 4.10.0 thru 5.1.0, inclusive. So what do I mean?
pattern-match longidents: [%longident_t {| $longid:li1$. $lid:l$ |}]
pattern-match the list of cases in a match: [%expression {| match $e1$ with $list:cases$ |}]
pattern-match a case-branch: [%case {| $p1'$ when $e1'$ -> $e2'$ |}]
and of course, all of these work as expressions, too. [there’s some trickery done to get the locations to work without too much fuss].
pa_ppx_parsetree
has an example: a “show” deriver (though not hooked-into any infrastructure): https://github.com/camlp5/pa_ppx_parsetree/blob/master/tests/test_show.ml
and I’ve also used it to rewrite the guts of ppx_jsobject_conv
with quasi-quotations everywhere: https://github.com/chetmurthy/ppx_jsobject_conv/blob/experimental-parsetree-quotation-hacking/src2/code.orig.ml
In that project:
- it’s on the branch
experimental-parsetree-quotation-hacking
- in the directory
src2
(src
is the original deriver, so I can compare) - it’s set up so I can build it against the OCaml AST of any version 4.10-5.0 inclusive (haven’t tested it against 5.1). The idea being, sure/sure/SURE/SURE it’s nice to fix a single version of the AST and use
omp
to migrate to it, run your rewriter, and migrate back. But it’s not necessary, and this demonstrates that for this PPX deriver, you don’t have to do it: the code compiles with any version of the OCaml AST.