Metaprogramming and PPX
ppx
is the main syntax extension format supported by OCaml.
It allows for many features that aren’t included in the core language to be added on,
particularly ones that involve reducing boilerplate code.
For example, there’s usually no need to write code manually for the serialization or comparison of types.
A great introduction to ppx
metaprogramming can be found here.
The history and current situation of the PPX ecosystem is presented elegantly in this post.
PPX Extensions
This is a list of PPX extensions currently available. You should familiarize yourself with at least some of these, as they will save you a lot of programming time.
Basic Functionality
The basic functionality added to OCaml via ppx
is things like enumerating variants,
displaying type details etc.
- ppx_deriving:
Type-based framework for ppx extensions.
Contains built-in plugins for
show
: convert variants to strings for easy display.eq
: generate equality functions easily.ord
: generate comparison functions.enum
: variants without arguments can be converted to numbers.iter
,map
,fold
: easily create iteration functions for any type.make
: automatic creation functions for records.
- ppx_visitors: Automatically use the visitor object-oriented pattern on a data structure, extending it with behaviors rather than needing to specify each variant’s behavior.
- ppx_import:
Import is a syntax extension that allows to pull in types or signatures from other compiled interface files.
This can be handy when not wanting to repeat a type in both the
.ml
and.mli
file, for example. It’s also very useful when wanting to avoid other boilerplate, such as when a module need to export variants of a type defined in another module. - ppx_override:
Override allows you to import a module or its types, and then modify aspects of that module,
such as using
ppx_deriving
on that module’s types or even modifying specific types to be different. - ppx_optcomp:
Conditional compilation like
#ifdef
for OCaml. - ppx_string_interpolate:
A simple ppx filter to support string interpolation like
[%str "value of foo is $(foo)"]
. - ppx_monad: Monadic syntax extension.
- ppx_let: A monadic syntax extension from Jane Street.
- ocaml-monadic: Another monadic syntax extension.
- ppx_regex:
Contains 2 ppx parsers regex libraries:
- ppx_regexp: maps to use Re (untyped regex)
- ppx_tyre: maps to use Tyre for typed regex.
- ppx_inline_test: Inlined unit testing. See Testing.
- ppx_expect: Inlined expect-based unit testing. See Testing.
- bisect_ppx: Code coverage tool. See Code Tools.
- ppx_pgsql: A syntax extension for embedded SQL queries using PG’OCaml. See Databases.
- ppx_cstubs: Write C functions directly in your OCaml code. See FFI.
- ppx-tyxml:
Convert html/xml syntax to
tyxml
function calls. - ppx-loc: Display nice error messages with source location. For compilers etc.
- ppx_blob: Include arbitrary file data as a string in OCaml without having to worry about lexical conventions.
- ppx_deriving_cmdliner:
An easy way to write command-line argument code using the
cmdliner
library.
Protocol-specific PPX
- ppx_deriving_yojson: A Yojson codec generator for OCaml. See Serialization.
- ppx_yojson_conv:
Newer alternative to
ppx_deriving_yojson
from Jane Street. - ppx_yojson:
Convert JSON expressions in OCaml code to
yojson
AST, allowing your code to be cleaner. - ppx_deriving_protobuf: Derive Protobuf files from OCaml types. See Protocols.
- ppx_sexp_conv:
Derive converters to s-expressions,
the same serialization format used by
dune
. - ppx_protocol_conv: Framework for multiple serializers for different protocols.
Writing ppx Extensions
Writing ppx
libraries is generally not trivial,
but there are ongoing efforts to make it easier.
The excellent ppxlib user manual
explains in depth how to use the most modern methods.
- ppxlib:
The modern solution for writing PPX extensions.
Without this library, writing
ppx
extensions is fragile and breaks with OCaml version changes.ppxlib
merges several older projects together to provide a complete platform for writing efficient, resilient PPX extensions.
Articles
- A Guide to PreProcessor EXtensions
- Introduction to the PPX Ecosystem:
Nice and thorough introduction to writing PPXs using
ppxlib
. - A Guide to Extension Points in OCaml
- Extension Points, or how OCaml is becoming more like Lisp
- A guide to writing PPX Deriving plugins
- Am I missing some comprehensive ppxlib resource somewhere?:
A discuss post which turned into an important resource about aspects of PPX writing such as
Ast_pattern
. - ppxlib as the new standard
- Older: The Future of PPX: post on discuss
Other MetaProgramming Approaches
Some other approaches exist for metaprogramming in OCaml.
- cppo:
A simple C++-like preprocessor for OCaml files.
Allows for
#include
and#ifdef
. - MetaOCaml: An OCaml dialect for multi-stage programming.
- metapp:
A ppx extension that provides metaquoting facilities similar to
MetaOCaml
. - about_macros: Blog post describing an experimental system of typed macros in OCaml.
- Fan: Fan is a compile-time metaprogramming system for OCaml, originally inspired from Camlp4. It’s a combination of OCaml and Lispy Macros. It shares the same concrete syntax with OCaml.