What does [@@deriving sexp] mean?

Hello everyone, I have a question below, I hope that the community friends can answer it for me, thank you!
I know this is a record definition syntax, but I don’t understand what the last tag [@@deriving sexp] means.

type multitable_flow = {
pattern : Frenetic_OpenFlow.Pattern.t;
cookie : int64;
idle_timeout : Frenetic_OpenFlow.timeout;
hard_timeout : Frenetic_OpenFlow.timeout;
instruction : instruction;
flowId : flowId;
} [@@deriving sexp]

1 Like

Most of [@...] and [@@...] directives are for a preprocessor.
This particular one is a directive to ask a preprocessor to add the code required to serialize this record as an s-expression.
Preprocessors are like macro processors in other languages, just more powerful but harder to implement.
OCaml is commonly used with many different preprocessors: camlp4, camlp5 and the newer ppx system (the one using the [@...] notations).

To the best of my knowledge the beginner friendlier documentation available for this ppx system is still this outdated blog post:
https://whitequark.org/blog/2014/04/16/a-guide-to-extension-points-in-ocaml/

6 Likes

You have done me a great favor and thank you very much for your sharing.

1 Like

And specifically, [@@deriving sexp] is using ppx_sexp_conv.

2 Likes

I used the [@@deriving fields] tag defining a record before. It can bring great convenience to me, and generate a bunch of auxiliary functions for me, such as changing the field of the record to the corresponding string.
In fact, I want to know whether the [@@deriving fields] marker can generate some auxiliary functions automatically for me.
Now I am debugging a project which has lots of definition of records like this. I want to print this record, but could not find the string conversion function, so I think this marker should be useful, just do not know how to use it.

You will need to add the “sexplib” package to convert s-expressions into other values.

To use [@@deriving sexp] you need to apply the generated function to convert your type to a sexp.
For example if you have the following,

open Sexplib.Std;;
type ty = { my_int : int } [@@deriving sexp]

it will automatically generate the function val sexp_of_ty : ty -> Sexplib.Sexp.t.
For debugging you can print your sexp’s like the following:
let my_int_value = { my_int = 42 } in
sexp_of_ty my_int_value |> Sexplib.Sexp.to_string |> print_string;;

Hope this helps!

2 Likes

Okay, I’ll try later. Thank you.