[wg-camlp4] Camlp4 uses

Xavier Clerc xavier.clerc at inria.fr
Mon Jan 28 15:17:21 GMT 2013


Dear list,

As requested, here are my current uses of camlp4:
  1- in Bisect (code coverage tool), camlp4 is used
     to "inject" code;
  2- in Bolt (logging tool), camlp4 is used to provide
     a new "LOG ... LEVEL ..." expression (such expressions
     can be stripped at compile-time);
  3- in Mascot (style tool), camlp4 is used to get either
     a stream of lexical tokens or an AST, both being used
     to detect code smells;
  4- in Barista (library for handling of Java class files),
     camlp4 is used to provide @"..." and @'...' constructs
     akin to "..." and '...' ones except based upon UTF8;
  5- in Barista, camlp4 is also used to succinctly declare
     exceptions (*).


As previously stated by Alain, case 1 has already been
"ported" to ppx, with minimal effort. Case 4 seems easy
to support through ppx, and case 2 could as well modulo
a slight change in syntax (in the very same spirit as
what has been said about js_of_ocaml).

Case 3 may appear as a perfect fit for ppx, but indeed
it is quite pleasant to write some code smell in OCaml
syntax (through quotations), rather than by matching
against a bare AST. The latter becomes very verbose,
and very hard to read/maintain to say the least.

Case 5 may be adapted to ppx, at the cost of a syntax
change, which is not a big problem as the objective is
only to avoid writing boilerplate code.

At the end of the day, the only thing I am missing in
the current version of ppx is a quotation mechanism.
It is convenient to rely on such a mechanism in order
to easily either generate code, or match against code
patterns.


My two cents,

Xavier Clerc


(*) a small example should be self-explanatory:
  BARISTA_ERROR =
  | O -> "o"
  | A of (x : int) -> Printf.sprintf "%d" x
  | B of (y : float) * (z : string) * (t : char)-> Printf.sprintf "%f %S %C" y z t
being rewritten to:
  type error =
    | O
    | A of int
    | B of float * string * char
  exception Exception of error
  let fail e = raise (Exception e)
  let string_of_error e =
    match e with
    | O -> "o"
    | A x -> Printf.sprintf "%d" x
    | B ((y, z, t)) -> Printf.sprintf "%f %S %C" y z t
  let () =
    Printexc.register_printer
      (function | Exception e -> Some (string_of_error e) | _ -> None)




More information about the wg-camlp4 mailing list