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.9.0.tar.gz
md5=1f1f86eaa3e840d5c1c4d5bb95f922ed

Description

Part of the Jane Street's PPX rewriters collection.

Published: 22 Mar 2017

README

title: ppx_sexp_value parent: ../README.md

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 type sexp_option to achieve the same result as when using sexplib. sexp_option has 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   )
      }
    ]

Application syntax (deprecated)

The toplevel expression of [%sexp] can be a function application. In this case it is treated the same as a tuple, and ~~ is added to elements that are of the form (expr : type). For instance:

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

is the same as:

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

The first form is more compact but doesn't follow the general idea of ppx_sexp_value. It is explored more in details in ppx_sexp_message.

Derived extensions (deprecated)

Some derived extensions are built on top of the base extension.

[%structural_sexp expr]

in an alias for [%sexp expr].

[%structural_error string-expr expr]

will build a value of type Error.t rather than return a sexp. The string expression is a message which will appear in the error.

[%raise_structural_sexp string-expr expr]

is equivalent to Error.raise [%structural_error string-expr expr].

[%structural_or_error string-expr expr]

is equivalent to Result.Error [%structural_error string-expr expr].

Dependencies (9)

  1. ocaml-migrate-parsetree >= "0.4" & < "2.0.0"
  2. sexplib >= "v0.9" & < "v0.10"
  3. ppx_sexp_conv >= "v0.9" & < "v0.10"
  4. ppx_metaquot >= "v0.9" & < "v0.10"
  5. ppx_here >= "v0.9" & < "v0.10"
  6. ppx_driver >= "v0.9" & < "v0.10"
  7. ppx_core >= "v0.9" & < "v0.10"
  8. jbuilder >= "1.0+beta4"
  9. ocaml >= "4.03.0"

Dev Dependencies

None

Used by (5)

  1. parsexp < "v0.10.0"
  2. ppx_bap < "v0.14.0"
  3. ppx_jane = "v0.9.0"
  4. routes >= "2.0.0"
  5. typerep_extended >= "v0.9.0"

Conflicts

None