bryan garza
S-expressions as a Lightweight Serialization Format 2016-02-17

Table of contents

I've been writing a desktop application that uses OCaml for the backend, and Racket for the GUI frontend. To communicate between the two, I call the OCaml program as a subprocess from Racket, and have s-expressions be the serialization mechanism that both languages can understand. Jane Street's Core, along with the sexplib syntax extension mentioned in my previous post, offer an easy way to translate OCaml types to sexps that Racket can then read.

With a type like:

type book = {
  title        : string;
  authors      : string list;
  pubdate      : string;
  publishers   : string list;
  subjects     : string list
} with sexp

A sexp_of_book function is automatically generated.

Now racket can receive:

'((title "Purely functional data structures")
  (authors ("Chris Okasaki"))
  (pubdate 1999)
  (publishers ("Cambridge University Press"))
  (subjects ("Functional programming languages" "Data structures (Computer science)")))

I take this sexp, and create a book struct:

(struct book (title authors pubdate publishers subjects))

(define (isbn-lookup isbn)
  (let ([cmd (string-join (list homelib-binary isbn))])
    ((λ~>> process    ; -> '(stdout stdin proc-id stderr f)
           read       ; from an input port
           (map cadr) ; (k v) -> v
           (apply book))

Finally, we can test it out on the REPL to make sure it works:

racket@app.rkt> (isbn-lookup "0521663504")

racket@app.rkt> (book-title (isbn-lookup "0521663504"))
"Purely functional data structures"

racket@app.rkt> (book-subjects (isbn-lookup "0521663504"))
'("Functional programming languages" "Data structures (Computer science)")

Similarly, I can work in the other direction, and pass Racket s-expressions to OCaml, and using sexplib, convert them back to OCaml types. What a time to be alive!