Extension Points - Ppxlib & Dune Update

In a previous post, I’ve described what are the latest technologies used to construct and package ppx rewriters. In just eight months a couple important changes have occurred that require ppx authors to react. In this post, I’d like to describe these changes and demonstrate how to update your ppx rewriters to keep up with them.

Introduction of ppxlib

There’s been a welcome consolidation in the ppx ecosystem. First of all, important tools in the ppx ecosystem such ocaml-migrate-parsetree, ppx_tools_versioned, ppx_deriving have been moved to the ocaml-ppx organization. Second of all, Jane Street has consolidated the foundations of their ppx stack: ppx_core, ppx_driver, ppx_ast, ppx_traverse into a single library that they’ve kindly moved to ocaml-ppx and moved its development into the open, on github. The new library that encompasses this stack is called ppxlib, and now I’ll describe how to migrate the simple ppx_getenv2 plugin from the previous post to ppxlib.

Luckily, the transition is going to be trivial and maintainly consists of renaming dependencies and modules.

  • The findlib package ppx_metaquot has been renamed to ppxlib.metaquot, and ppx_core, ppx_traverse, ppx_driver, are all replaced by ppxlib.

  • All ppx libraries now live under the Ppxlib module. Driver related code has been to Ppxlib.Driver.

Here’s a diff of the (minimal) changes required for ppx_getenv2:

-open Ppx_core
+open Ppxlib

let name = "getenv"

@@ -14,4 +14,4 @@ let ext =
    Ast_pattern.(single_expr_payload (estring __))

-let () = Ppx_driver.register_transformation name ~extensions:[ext]
+let () = Ppxlib.Driver.register_transformation name ~extensions:[ext]

Changes in Dune

A couple of welcome changes in dune have also occurred to simplify using and testing ppx rewriters. Writing expectation tests for ppx rewriters is now simpler and doesn’t require any external diff tools. We can now rely on dune’s diff action to setup the rule:

 (targets pp.result)
 (deps test.ml)
 (action (setenv PPX_GETENV2 foobar (run ./pp.exe --impl %{deps} -o %{targets}))))

 (name runtest)
 (action (diff pp.expected pp.result)))

and then use dune’s promotion feature to update the expected results (pp.expected in this case).

The second change is a simplification with regard to drivers. Dune will now transparently select the “best” driver automatically. This is a welcome improvement because it’s yet another implementation detail that doesn’t concern the majority of users (and even authors). There exist only two ppx drivers today, the basic one from ocaml-migrate-parsetree and the full featured one from ppxlib. Given that we’re using ppxlib in ppx_getenv2 we get to use the best driver automatically. It is actually possible to implement your own driver, but I can’t imagine too many useful applications for this and will not document this.

Final Words

This isn’t the last chapter of updates regarding keeping your ppx up to date. There are more changes in the horizon that will require ppx authors to keep their code up to date, such as ppx_view to give one example.

If any of the changes described above were a bit too brief, the ppx_getenv2 repo is fully up to date. The purpose of this project is to be a reference point for packaging ppx, and I intend to keep it up to date for this purpose.


comments powered by Disqus