Ppx deriving enum

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:

  1. it’s on the branch experimental-parsetree-quotation-hacking
  2. in the directory src2 (src is the original deriver, so I can compare)
  3. 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.