OCaml Weekly News

Previous Week Up Next Week


Here is the latest OCaml Weekly News, for the week of November 09 to 16, 2021.

Table of Contents

Early preview of the Algorithmic with OCaml Book

Damien Guichard announced

Please report bugs, bad English & nonsenses. But do not report omissions (it is work-in-progress plus it's not an ocaml bible).


Why the book is not bottom up, instead some concepts are used without explained ?

  • Because some notions (what is the unit type ? what is a queue ?) are considered easy-enough to go without saying.

What will be in the missing chapter 6 ?

  • Type polymorphism, universal quantification, Stdlib.compare, weak polymorphism, constrained polymorphism, phantom types, type variance.

What will be in the chapters 12 and more ?

  • High performance lexing
  • Recursive-descent parsing
  • The art of searching
  • Detailed construction of the ERic 0.3 application

Will the source files go to a repository ?

  • No. The source files are already included in the zip archive.

pyml_bindgen: a CLI app to generate Python bindings directly from OCaml value specifications

Ryan Moore announced

I wanted to announce the first release of pyml_bindgen, a CLI app for generating Python bindings using pyml directly from OCaml value specifications.

Manually writing bindings to Python libraries can get tedious pretty quickly. pyml_bindgen aims to help you avoid a lot of the repetitive work when binding Python libraries by letting you focus on the OCaml side of things and (mostly) not worrying about the implementation of the pyml bindings.

Quick start

First, install pyml_bindgen. It is available on Opam.

$ opam install pyml_bindgen

Say you have a Python class you want to bind and use in OCaml. (Filename: adder.py)

class Adder:
    def add(x, y):
        return x + y

To do so, you write OCaml value specifications for the class and methods you want to bind. (Filename: val_specs.txt)

val add : x:int -> y:int -> unit -> int

Then, you run pyml_bindgen.

$ pyml_bindgen val_specs.txt adder Adder --caml-module Adder > lib.ml

Now you can use your generated functions in your OCaml code. (Filename: run.ml)

open Lib

let () = Py.initialize ()

let result = Adder.add ~x:1 ~y:2 ()

let () = assert (result = 3)

Finally, set up a dune file and run it.

 (name run)
 (libraries pyml))
$ dune exec ./run.exe


For more information on installing and using pyml_bindgen, check out the docs. There you will find lots of tips and examples to help you get started!

ocaml-wayland (pure OCaml wayland protocol library)

Thomas Leonard announced

ocaml-wayland has been very stable over the last few months and so I've now released version 1.0. The main changes are improved error handling and diagnostics.

I've been using this to write an Xwayland adaptor, which acts as an X11 window manager to Xwayland, converting between the two protocols. This allows running X11 apps in VMs and having them appear alongside other application windows on the host. It can also be used to fix other problems, such as support for HiDPI screens and Sway's buggy clipboard support:


Set up OCaml 2.0.0-beta6

Sora Morimoto announced


  • Unlock opam 2.1 on the Ubuntu and macOS runners.


Set up OCaml 2.0.0-beta7

Sora Morimoto announced


  • Return an empty array to avoid depext failure when depext flags are not passed.


Set up OCaml 2.0.0-beta8

Sora Morimoto announced


  • Use 2.1 mode instead of 2.0 mode on the Ubuntu and macOS runners.


phylogenetics, a library for molecular evolution

Philippe announced

I'm happy to announce the availability on opam of phylogenetics, a bioinformatics library dedicated to molecular evolution and phylogeny. It provides a few algorithms and data structures that can be useful to study how biological sequences like proteins or genes have evolved, or to simulate datasets under various evolutionary models.

Comments/questions welcomed on the repo's issue tracker!

release of svmwrap: a wrapper around libsvm-tools

UnixJunkie announced

I am pleased to announce the availability in opam of the svmwrap package. A wrapper around libsvm's svm-train and svm-predict executables. Currently, only regression modeling is supported, using the linear, RBF, sigmoid or polynomial kernel.


The quite scary usage looks like this:

usage: svmwrap
  -i <filename>: training set or DB to screen
  --feats <int>: number of features
  [-o <filename>]: predictions output file
  [-np <int>]: ncores
  [--kernel <string>] choose kernel type {Lin|RBF|Sig|Pol}
  [-c <float>]: fix C
  [-e <float>]: epsilon in the loss function of epsilon-SVR;
  (0 <= epsilon <= max_i(|y_i|))
  [-g <float>]: fix gamma (for RBF and Sig kernels)
  [-r <float>]: fix r for the Sig kernel
  [--iwn]: turn ON instance-wise-normalization
  [--scale]: turn ON [0:1] scaling (NOT PRODUCTION READY)
  [--no-plot]: no gnuplot
  [{-n|--NxCV} <int>]: folds of cross validation
  [-q]: quiet
  [-v|--verbose]: equivalent to not specifying -q
  [--seed <int>]: fix random seed
  [-p <float>]: training set portion (in [0.0:1.0])
  [--pairs]: read from .AP files (atom pairs; will offset feat. indexes by 1)
  [--train <train.liblin>]: training set (overrides -p)
  [--valid <valid.liblin>]: validation set (overrides -p)
  [--test <test.liblin>]: test set (overrides -p)
  [{-l|--load} <filename>]: prod. mode; use trained models
  [{-s|--save} <filename>]: train. mode; save trained models
  [-f]: force overwriting existing model file
  [--scan-c]: scan for best C
  [--scan-e <int>]: epsilon scan #steps for SVR
  [--scan-g]: scan for best gamma
  [--regr]: regression (SVR); also, implied by -e and --scan-e
  [--e-range <float>:<int>:<float>]: specific range for e
  [--c-range <float,float,...>] explicit scan range for C
  [--g-range <float,float,...>] explicit range for gamma
  [--r-range <float,float,...>] explicit range for r

For people who know my linwrap opam package (a wrapper around liblinear tools), this is quite similar. https://github.com/UnixJunkie/linwrap

GeoPub - A XMPP web client

pukkamustard announced

I'd like to announce an initial, proof-of-concept release of GeoPub - an XMPP web client. Unlike many XMPP clients the focus is not on instant messaging but on creating, displaying and managing things such as events, maps, information on local organizations and other local knowledge (see the openEngiadina project for the context).

This initial release is not really anything useful but a proof-of-concept how such an application can be developed using XMPP and OCaml. There are many rough edges and broken hacks that need fixing. I'd be very grateful for your feedback, thoughts and ideas.

The source code of the app is on codeberg and a pre-built hosted version is available here.

The application consists of some parts and ideas that I'd like to illustrate separately:


ocaml-xmpp is a XMPP client library for OCaml (documentation available online.


ocaml-xmpp is reactive in the sense that the XMPP connection is abstracted as a React event of Stanzas (small pieces of information that flow over XMPP):

val stanzas : t -> Stanza.t React.event

This React event can be filtered for messages in a specific conversation, for example.


XMPP works with different transport mechanisms and ocaml-xmpp supports this. Currently ocaml-xmpp can be used from Unix with a TCP/SSL connection to a XMPP server and from web browsers with a WebSocket connection. This is implemented by abstracting the XMPP transport:

module type TRANSPORT = sig
  (** {2 Connection} *)

  type options
  (** Additional options that may be passed to the transport *)

  type t
  (** Type of an instantiated connection to an XMPP server *)

  val connect : host:string -> options -> t Lwt.t

  val close : t -> unit Lwt.t

  val closed : t -> unit Lwt.t

  (** {2 XML Stream} *)

  type stream

  val open_stream : t -> to':string -> stream Lwt.t

  val stream_id : stream -> string Lwt.t

  val send_xml : stream -> Xmlc.t -> unit Lwt.t

  val signals : stream -> Xmlc.signal Lwt_stream.t

  val stop_stream : stream -> unit Lwt.t

A transport establishes the underlying connection to a server and can create XML streams (in XMPP a connection is by multiple XML streams sequentially). For technical reasons XML parsing is also handled by the transport and a stream of XML signals (element start, data, element end) is returned. This is due to the fact that XML parsing in XMPP needs to be done slightly differently when using TCP (a single XML document over the entire stream) or WebSockets (every WebSocket frame is a parse-able XML document).

The Unix/TCP/SSL transport uses Markup.ml and whereas the WebSocket transport uses Xmlm (and Brrr).

Parser combinators for XML

For parsing streams of XML signals to OCaml types ocaml-xmpp contains a parser combinator helper library: Xmlc. This allows parser for XML such as this:

<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><jid>w4iu4ckn3kjbqvcd@demo.openengiadina.net/z8Pkzfa8</jid></bind>

to be parses like this:

  element (Ns.bind "bind") (fun _ ->
    element (Ns.bind "jid") (fun _ ->
      text >>| String.concat "" >>= fun jid_s ->
      match Jid.of_string jid_s with
      | Some jid -> return jid
      | None -> fail_with "invalid JID")))
XMPP extensions

Inspiration for the scope of the core library is taken from the Strophe XMPP libraries - everything that does not have directly to do with XMPP transport, authentication or stream management is kept outside of the core library.

There are already some "extension" libraries outside of the core for useful XMPP features (e.g. Roster management, PubSub and pinging).

One thing that I do want to add to the core library is stream management according to XEP-0198. I expect this addition to change the core library API - the API is not stable yet!

Much inspiration was taken from Jackline - an OCaml XMPP client - and in particular this post on Jackline. Many thanks to @hannes.


GeoPub uses Brr. I had some trouble figuring out a suitable "architecture" for managing complex logic and ended up hacking an Elm inspired helper library: reactor.mli. State updates for the entire application are then handled in a single update function.

I'm not yet very happy with this machinery and I'm pretty sure I'm using react in wrong and dangerous ways. I'd be very grateful for ideas on how to improve this. THis might be related to this discussion: https://discuss.ocaml.org/t/structuring-frp-specifically-note-applications/8645/17.

The reason for using React over Note is because ocaml-xmpp uses a lot of Lwt and Lwt_react provides nice bindings for working with both. I guess something similar could be created for Note (e.g. Lwt_note) and I'm open to using Note (also in ocaml-xmpp).


GeoPub displays a map using the Leaflet.js JavaScript library. GeoPub contains OCaml bindings to Leaflet using Brr: leaflet.mli. Writing this was very straightforward and pleasant (I like Brr!).

One issue I have is that the Leaflet map needs to be manipulated very imperatively, whereas the rest of the application is much more functional. This causes some mismatches. I guess one needs to find a way of hiding the impressiveness of Leaflet (e.g. like react-leaflet).

Guix for build and development environments

I use Guix for providing a build and development environment. With guix installed one can run guix shell in the GeoPub repository to get a reproducible build environment. All dependencies are fetched and made available by Guix in this environment (e.g. ocaml-xmpp or the OCaml compiler).

I will publish ocaml-xmpp on OPAM once the API is more stable and an initial release can be made.


If you happen to miss a CWN, you can send me a message and I'll mail it to you, or go take a look at the archive or the RSS feed of the archives.

If you also wish to receive it every week by mail, you may subscribe online.