package ppx_sexp_value

  1. Overview
  2. Docs
A ppx rewriter that simplifies building s-expressions from ocaml values

Install

Dune Dependency

Authors

Maintainers

Sources

ppx_sexp_value-v0.14.0.tar.gz
md5=8bc8a75c992e8af371dfd71804ac2133

Description

Part of the Jane Street's PPX rewriters collection.

Published: 31 May 2020

README

ppx_sexp_value

A ppx rewriter that simplifies building s-expressions from ocaml values.

Basic use

The building block of this preprocessor is the extension:

[%sexp expr]

in expressions. It evaluates to an s-expression. This is done by recursing down the expression and converting all data constructors into s-expressions. If an expression with a type annotation is found, then the type is used to convert to s-expression. Expressions that are neither data constructors nor annotated with a type will be rejected.

For instance:

[%sexp { a = "hello" ; b = (Time.now () : Time.t) } ]

will be preprocessed into:

List [List [Atom "a"; Atom "hello"];
      List [Atom "b"; [%sexp_of: Time.t] (Time.now ())];
     ]

This does not require a record with fields a and b to exist (and if one does exist, its sexp_of function will be ignored unless a type annotation is added around the record). One can annotate a record field with the attribute [@sexp.option] or with [@sexp.omit_nil] to achieve the same result as when using sexplib. They both have the same behavior inside tuples.

Variant, polymorphic variants, tuples and lists are supported as well. Variants are analogous to records in that a type containing the variant does not have to exist unless a type annotation is added to the variant.

Expressions with their evaluations

It is sometimes convenient to include the expression itself in the s-expression. This is especially true for debugging, as it avoids having to think of a label for a value; one can simply use the expression itself.

Ppx_sexp_value allows this by reserving the ~~ operator. Inside [%sexp], ~~<expr> is the same as ("<expr>", <expr>), where the type annotation in <expr> is stripped off in the s-expression (~~<expr> isn't allowed if <expr> is a data constructor).

For instance:

[%sexp (~~(x : int), ~~(y + z : int), "literal") ]

will be preprocessed into:

List [List [Atom "x";     [%sexp_of: int] x];
      List [Atom "y + z"; [%sexp_of: int] (y + z)];
      [%sexp_of: string] "literal";
     ]

Recommended use for errors

This extension is primarily intended to build better errors, by making building errors easier and more readable, particularly when using records to add context:

try Unix.rename ~src:tmpfile ~dst
with exn ->
  raise_s
    [%sexp
     "Error while renaming file",
      { source = (tmpfile : string)
      ; dest   = (dst     : string)
      ; exn    = (exn     : exn   )
      }
    ]

Dependencies (6)

  1. ppxlib >= "0.11.0"
  2. dune >= "2.0.0"
  3. ppx_sexp_conv >= "v0.14" & < "v0.15"
  4. ppx_here >= "v0.14" & < "v0.15"
  5. base >= "v0.14" & < "v0.15"
  6. ocaml >= "4.04.2"

Dev Dependencies

None

Used by (4)

  1. base_quickcheck >= "v0.14.0" & < "v0.15.0"
  2. ppx_bap
  3. ppx_jane = "v0.14.0"
  4. routes >= "2.0.0"

Conflicts

None