[wg-camlp4] How Jane Street uses camlp4

Yaron Minsky yminsky at janestreet.com
Mon Jan 28 18:29:19 GMT 2013


Let me rattle a few off:

- type-conv style extensions.

  These include bin-prot, sexplib, fieldslib, variantslib, pa_compare...

  A few things to note about these:

  - generators may take argument, like [type t = ... with
    typehash(abstract)]. The generator is one that specifies how to
    parse the arguments (although they have to be well
    parenthesized). In the examples I can think of, either a few
    identifiers are accepted or, in a couple of cases, arbitrary
    expressions are accepted.
  - there can be generators (with optional argument too) on record
    field:

         type t =
           { a : int with default(2), sexp_drop_if(fun x -> x = 2);
           } with sexp

  - We also have some that rely only on quotations. The inside of
    quotations are usually types, sometimes expressions.

- pa_ounit: this gives a lightweight syntax for unit-testing.  You can
  write:

      TEST = <some expression>

  and it does a bunch of camlp4 magic, including capturing the text
  and location of the expression, as part of reporting a unit test
  failure effectively.  A test that runs the code is registered, but
  the actual code isn't run except when unit tests are run.

  You can also do:

      TEST_MODULE = struct ... end

  to create a whole module that won't be instantiated except within
  the running of a unit test.

- pa_nonrec: this is a small extension that adds the ability to
  define a type non-recursively.  Thus, you can write:

      type t
      module M = struct type nonrec t = t list end

  rather than the more annoying:

      type t
      module M = struct type z = t type t = z list end

- pa_pipebang: this converts

     <expr1> |! <expr2>

  into

    <expr2> (expr1)

  which is faster than a naively implemented |! operator

- pa_here: this converts the string _here_ to a source-code location.

- pa_custom_printf: If you put ! before a format string, it allows the
  use of a spec like "%{<Module>}" in the format string.  For example,
  using "%{Time}" wraps [Time.to_string] around the appropriate
  argument.

  It also allows different formats for a given type:
  "%{<Module>.<identifier>}" wraps <Module>.Format.<identifier> around
  the appropriate argument.  For example, "%{Float.pretty}" would wrap
  [Float.Format.pretty] around the appropriate argument.


More information about the wg-camlp4 mailing list