OCaml Weekly News

Previous Week Up Next Week


Here is the latest OCaml Weekly News, for the week of March 05 to 12, 2019.

Table of Contents


RJ asked

Is anyone interested in using the Matrix protocol as a form of communication via Riot.im? Its bridge functionality, reasonably well-designed GUI, and powerful encryption tools could potentially attract some exposure to the language; I am a big fan of it. There are official pages for Arch, F Droid, Haskell, etc. on it currently - among others. It seems to be more reliable on-the-go than tools like email, the discuss pages, etc.

Jim Tittsler replied

I monitor the #ocaml IRC channel using the Riot client thanks to the IRC bridge. This makes it easy to review activity during periods when I am not online.

Prochain meetup OUPS 19 mars 2019 / Next OUPS meetup March 19th 2019

Bruno Bernardo announced

The next OUPS meetup will take place on Tuesday, March 19, 7pm at IRILL on the Jussieu campus. As usual, we will have a few talks, followed by pizzas and drinks.

The talks will be the following:

Please do note that we are always in demand of talk proposals for future meetups.

To register, or for more information, go here: https://www.meetup.com/ocaml-paris/events/259363699

Registration is required! Access is not guaranteed after 7pm if you're not registered. (It also helps us to order the right amount of food.)

Access map:
IRILL - Université Pierre et Marie Curie (Paris VI)
Barre 15-16 1er étage
4 Place Jussieu
75005 Paris

The vmthreads library is deprecated in OCaml 4.08

Jeremie Dimino announced

I just wanted to bring your attention to the fact that the vmthreads library is deprecated in the upcoming OCaml 4.08 release. This library provides user-level threads for bytecode applications. We do not believe this library is still actively used. Additionally, several widely used alternatives exist, such as the Lwt [1] or Async [2] libraries. As a result, we decided to deprecate and then delete it from the compiler distribution in order to simplify its maintenance.

Note that the threads library, which provides support for system threads is still present and actively supported.



[1] https://github.com/ocsigen/lwt
[2] https://github.com/janestreet/async

Андрей Бергман asked and Jeremie Dimino replied

> Is it possible to develop multithread applications in Ocaml somehow in Linux?

You can use the "threads" library to write multi-threaded OCaml applications. It works on Linux, OSX, Windows, … There is however one limitation: only one system thread can run OCaml code at a time. There is a work-in-progress to enable multiple system threads to run OCaml code simultaneously, the following page describes the state of this project: https://github.com/ocamllabs/ocaml-multicore/wiki


Damien Doligez announced

The release of OCaml 4.08.0 is approaching. We have created a second beta version to help you adapt your software to the new features ahead of the release.

The source code is available at these addresses:


The compiler can also be installed as an OPAM switch with one of the following commands.

opam switch create ocaml-variants.4.08.0+beta2 --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git


opam switch create ocaml-variants.4.08.0+beta2+<VARIANT> --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git

where you replace <VARIANT> with one of these:

  • afl
  • default_unsafe_string
  • flambda
  • fp
  • fp+flambda

We want to know about all bugs. Please report them here: http://caml.inria.fr/mantis/bug_report_page.php

Happy hacking,

– Damien Doligez for the OCaml team.

The changes from beta1 are the following:

  • The –enable-flambda configuration option now works correctly (beta1 would ignore it).
  • * GPR#2104, GPR#2211, PR#4127, PR#7709: Fix Thread.sigmask. When system threads are loaded, Unix.sigprocmask is now an alias for Thread.sigmask. This changes the behavior at least on MacOS, where Unix.sigprocmask used to change the masks of all threads. (Jacques-Henri Jourdan, review by Jérémie Dimino)
  • GPR#2263: Delete the deprecated Bigarray.*.map_file functions in favour of *_of_genarray (Unix.map_file ...) functions instead. The Unix.map_file function was introduced in OCaml 4.06.0 onwards. (Jérémie Dimino, reviewed by David Allsopp and Anil Madhavapeddy)
  • GPR#2239: Fix match miscompilation with flambda (Leo White, review by Alain Frisch)
  • GPR#2223: ocamltest: fix the "bsd" and "not-bsd" built-in actions to recognize all BSD variants (Damien Doligez, review by Sébastien Hinderer and David Allsopp)
  • GPR#2264, MPR#7904: the configure script now sets the Unicode handling mode under Windows according to the value of the variable WINDOWS_UNICODE_MODE. If WINDOWS_UNICODE_MODE is "ansi" then it is assumed to be the current code page encoding. If WINDOWS_UNICODE_MODE is "compatible" or empty or not set at all, then encoding is UTF-8 with code page fallback. (Nicolás Ojeda Bär, review by Sébastien Hinderer and David Allsopp)
  • GPR#2266: ensure Cygwin ports configure with EXE=.exe, or the compiler is unable to find the camlheader files (subtle regression of GPR#2139/2041) (David Allsopp, report and review by Sébastien Hinderer)
  • MPR#7918, GPR#1703, GPR#1944, GPR#2213, GPR#2257: Add the module Compile_common, which factorizes the common part in Compile and Optcompile. This also makes the pipeline more modular. (Gabriel Radanne, help from Gabriel Scherer and Valentin Gatien-Baron, review by Mark Shinwell and Gabriel Radanne, regression spotted by Clément Franchini)
  • GPR#2160: restore –disable-shared support and ensure testsuite runs correctly when compiled without shared library support. (David Allsopp, review by Damien Doligez and Sébastien Hinderer)
  • GPR#2229: Env: remove prefix_idents cache (Thomas Refis, review by Frédéric Bour and Gabriel Scherer)
  • GPR#2231: Env: always freshen persistent signatures before using them (Thomas Refis and Leo White, review by Gabriel Radanne)
  • MPR#7923, GPR#2259: fix regression in FlexDLL bootstrapped build caused by refactoring the root Makefile for Dune in GPR#2093) (David Allsopp, report by Marc Lasson)
  • MPR#7929, GPR#2261: Subst.signature: call cleanup_types exactly once (Thomas Refis, review by Gabriel Scherer and Jacques Garrigue, report by Daniel Bünzli and Jon Ludlam)

Daniel Bünzli then said

Having installed the beta1 this invocation:

opam switch create ocaml-variants.4.08.0+beta2 --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git 

Resulted in: 

[ERROR] No compiler matching 'ocaml-variants.4.08.0+beta2' found, use 'opam switch list-available' to see what is available, or use '--packages' to select packages explicitly.

Updating the beta repo manually which was registred by my first install with 

  opam update beta

and then applying the above command works.

Drawing tree in OCaml GUI, best option?

Continuing this old thread, Darren announced

The project is finally published, here is the link to the relevant OCaml sources for drawing knowledge graph and HTML. src/cytoscape.ml is the binding to the Cytoscape JS library, src/dagre.ml is the binding to Dagre JS graph layout library.

We have a demo site where you can see it in action. You'll need to click "Show knowledge graph" to see the display of knowledge graph however.

Later on, Darren said and Gabriel Radanne replied

> Well writing a layout algorithm would be fairly easy I think.

Famous last words.

I have a project that aims to collect algorithms to layout trees: https://github.com/Drup/tree_layout

I suspect the "Layered" algorithm would be sufficient for your purpose, but you can also find lot's of different type of tree visualisation here. Formally, what you are looking for is an algorithm for layered trees where the rank of nodes is prescribed. There are several such algorithms.

If you end up implementing something from the literature (or improving on it), I would be happy to add it to the collection! :)

Uucd, Uucp, Uunf and Uuseg for Unicode 12.0.0

Daniel Bünzli announced

Unicode 12.0.0 was released on the 5th of march. 

It adds 553 characters to the standard including additional Tamil fractions for your [dividing pleasure][0]. See [here][1] for details about all the additions.

Accordingly the libraries mentioned at the end of this message had to be updated, consult the individual release notes for details. Both Uucd and Uucp are incompatible releases sinces new script and block enumerants had to be added.

As always if Unicode still puzzles you, have a look at Uucp’s absolute minimal Unicode [introduction][2].

Best and happy fractioning,


[0]: https://www.unicode.org/charts/PDF/U11FC0.pdf
[1]: http://blog.unicode.org/2019/03/announcing-unicode-standard-version-120.html
[2]: https://erratique.ch/software/uucp/doc/Uucp.html#uminimal

Uucd 12.0.0 Unicode character database decoder for OCaml.

Uucp 12.0.0 Unicode character properties for OCaml.

Uunf 12.0.0 Unicode text normalization for OCaml.

Uuseg 12.0.0 Unicode text segmentation for OCaml.

ppx_factory v0.0.0

Nathan Rebours announced

Cryptosense is happy to announce the initial release of ppx_factory!

ppx_factory is a ppx that will derive factory methods from your record and variant type definitions. It's partly inspired by factory_bot, factory_boy and such alternatives in various other languages. The idea of factory methods is that they are meant to replace test fixtures and allow you to build test values while only defining the bits that are relevant to your test.

For example, the following code:

type t =
  | A of {aa : int; ab: string}
  | B of {ba : bool; bb : float list }
[@@deriving factory]

will provide you with:

val a_factory : ?aa: int -> ?ab: string -> unit -> t
val b_factory : ?ba: int -> ?bb: string -> unit -> t

The use of factories improved the quality and legibility of our test code a lot and we hope ppx_factory can prove as helpful to you as it is to us!

It's in a beta release at this point so any feedback is appreciated!

You can find it on github and opam!

Dune 1.8.0

Rudi Grinberg announced

On behalf of the dune team, I'm pleased to announce release 1.8. The highlight of this release is a standalone preprocessor that allows OCaml programs to use the new let bindings introduced in 1.8 and still be compatible with OCaml versions all the way back to 4.02.

This release includes some important contributions from a new contributor: @aalekseyev. So I would like to use this opportunity to welcome him to the team. Thanks Arseniy!

The change log is replicated here for your convenience:

1.8.0 (07/03/2019)

  • Clean up watch mode polling loop: improves signal handling and error handling during polling (#1912, fix #1907, fix #1671, @aalekseyev)
  • Change status messages during polling to be one-line, so that the messages are correctly erased by ^K. (#1912, @aalekseyev)
  • Add support for .cxx extension for C++ stubs (#1831, @rgrinberg)
  • Add DUNE_WORKSPACE variable. This variable is equivalent to setting --workspace in the command line. (#1711, fix #1503, @rgrinberg)
  • Add c_flags and cxx_flags to env profile settings (#1700 and #1800, @gretay-js)
  • Format dune printenv output (#1867, fix #1862, @emillon)
  • Add the (promote-into <dir>) and (promote-until-clean-into <dir>) modes for (rule ...) stanzas, so that files can be promoted in another directory than the current one. For instance, this is used in merlin to promote menhir generated files in a directory that depends on the version of the compiler (#1890, @diml)
  • Improve error message when dune subst fails (#1898, fix #1897, @rgrinberg)
  • Add more GC counters to catapult traces (fix908, @rgrinberg)
  • Add a preprocessor shim for the let+ syntax of OCaml 4.08 (#1899, implements #1891, @diml)
  • Fix generation of .merlin files on Windows. \ characters needed to be escaped (#1869, @mlasson)
  • Fix 0 error code when $ dune format-dune-file fails. (#1915, fix #1914, @rgrinberg)
  • Configurator: deprecated query_expr and introduced query_expr_err which is the same but with a better error in case it fails. (#1886, @ejgallego)
  • Make sure (menhir (mode promote) ...) stanzas are ignored when using --ignore-promoted-rules or -p (#1917, @diml)

owl 0.5.0 released

Marcello Seri announced

owl 0.5.0

We are happy to announce the new release of owl, a dedicated system for scientific and engineering computing in OCaml.

The project is thoroughly documented at ocaml.xyz where you can find multiple examples of use. Notable demos are the Google Inception demo and the Neural Style Transfer demo

This release, coming a year after the latest 0.4.0 release, includes multiple improvements in terms of fixed bugs, performance and in the internals of the algorithmic differentiation engine.

It also comes with a large rewrite on the way both owl and some of the libraries it depends on are built, hopefully making its installation much easier and more flexible. Currently owl 0.5.0 should compile seamlessly on osx and multiple linux distributions (including debian, fedora and alpine), with the only known exception of ubuntu (that requires a custom manual build of OpenBLAS). You can now also enable experimental features, like the OpenMP/AEOS, or customise the c/c++ build flags, directly when building wih opam by setting or passing the right env variables (refer to owl and eigen READMEs for further information).

This release also reduces he number of dependencies and stubs, moving toward a more modular approach for the framework: the tensorflow graph and plplot bindings are now provided by separate packages, with owl-plplot already released and owl-tensorflow coming soon. A new plot package (and its jupyter integration module) are also in development, allowing to generate plots using gnuplot.

You can read more about it on the official documentation page ocaml.xyz and on the odoc generated one ocaml.xyz/owl.


In conjunction with this release we are also happy to announce the first release of owl-ode and owl-ode-sundials.

The first is a small OCaml library providing the most common numerical ode integrators, in single-step and adaptive versions and fully compatible with owl type system. One interesting feature of owl~vis that a larger and larger part of its core supports compilation via ~js_of_ocaml, owl-ode falls in the category of packages that support compilation to js. owl-ode also comes with support for symplectic integrators, providing an interesting framework to develop Hamiltonian Monte Carlo methods.

You can access the documentation of owl-ode inclusive of a small tutorial at ocaml.xyz/owl_ode/owl-ode and ocaml.xyz/apidoc/ode.html. Further examples are available on the sources repository.

The second library is a wrapper to the sundialsml library, allowing to use the battle tested cvode directly on owl.

Both libraries are in their early days, and multiple features are still missing, but have been designed keeping in mind the ergonomics and flexibility from day one. To demonstrate this we synced the release with ocaml-cviode, a small OCaml library that provides lower order contact geometric integrators and is fully reliant on owl-ode to do the heavy lifting and provide the integration interface.

The future plans for owl-ode include:

  • making the libraries more robust and better tested
  • complete the sundialsml wrapper and document it
  • add a wrapper to ocaml-odepack
  • replicate Neural ODEs directly in owl

Every help is welcome!

Odig 0.0.4

Daniel Bünzli announced

It's my pleasure to announce a new release of odig.

 odig is a command line tool to lookup documentation of installed  OCaml packages. It shows package metadata, readmes, change logs,  licenses, cross-referenced odoc API documentation and manuals.

To browse the documentation of your opam switch's packages simply proceed with:

    opam install ocaml-manual odig
    odig doc

An odig manual and the packaging conventions can be consulted via:

    odig doc odig # or see https://b0-system.github.io/odig/doc/odig

A sample output on a best-effort maximal set of packages of the opam repository can be found here:


The highlights of this release are:

  • Support for the latest odoc (includes navigation improvements).
  • Support for mld manuals and package landing page customization. See for example: https://b0-system.github.io/odig/doc/odig
  • Support for API documentation themes. The default odoc theme and light and dark themes optimized for legibility are bundled with odig; and you can bring your own via opam packages. The odig default themes can be spotted online by following the links here: https://github.com/b0-system/odig#sample-odoc-api-documentation-and-manuals
  • Support for OCaml manual theming when the ocaml-manual package is installed. Provides a best-effort (for better results a closer rework of the manual HTML gen would be needed) seamless style transition between API docs and the OCaml manual. For example follow the link to the manual on: https://b0-system.github.io/odig/doc/

The release notes have all the details, especially removals details from 0.0.3:


Most of this is brought to you thanks to support added in odoc by Thomas Refis and Rizo Isrof. Thanks also to Thomas Refis for helping with odoc driving details, with odoc bug chasing and discussions.

Homepage: http://erratique.ch/software/odig

An intermediate abstraction between applicatives and monads

Jérémie Dimino announced

I'm happy to share the following paper introducing an abstraction between applicatives and monads. The paper uses Dune as a case study and in particular gives some insights as to how Dune makes use of such abstractions.

One typical example of applicative in OCaml is the Cmdliner library, and one typical example of monad in the Lwt library. Selective functors come in between, allowing to fully analyse a computation beforehand, just as cmdliner does in order to produce man pages, while still allowing to select between different branches at runtime, as one can do with Lwt.

You can also find OCaml examples in this github repository: https://github.com/snowleopard/selective-ocaml


some questions were asked and Andrey Mokhov replied

Yaron Minsky: > Do you know where the origin of selective functors is? Does this come out of Dune itself, or is it older still?

Yaron: I personally got interested in selective functors in the context of hardware design, but after learning from Jeremie about Dune, I got curious about "selective build systems", which have unique features unavailable to applicative or monadic ones. Haxl came later as a complete surprise.

Selective-like type classes have previously appeared in the context of parsing and web programming. For example, in his dissertation Jeremy Yallop mentions DynamicIdiom type class with the method branch :: f Bool -> f a -> f a -> f a, which is our derived ifS combinator, but doesn't really explore it (we've learned about this after the submission).

Tim Mc Gilchrist: > I was expecting a discussion of Function Reactive Programming.

Tim: you are right, FRP is relevant and we should have probably mentioned it. I've added this to our TODO list.

As for Incremental, I think it relies on monads in a fundamental way. I don't think it can be made selective.

> Is the equivalent OCaml library available yet?

Yes: https://opam.ocaml.org/packages/selective/

Yaron Minsky then said

I'm a bit doubtful of your analysis of Incremental. Incremental has a monadic interface, for sure. But there are big differences between the performance of the applicative subset of that monadic interface, and most Incremental programming is done using the applicative subset alone.

I think this is a common situation with monadic libraries, where the applicative subset is in some sense special. I'm not sure selective would be useful here, but I could imagine it turning out to be helpful in exposing APIs that are more expressive than the applicative subset and more performant than the monadic part of the API. An example that was raised internally is that Incremental.if is special-cased in a way that might fit nicely into Selective.

Later on, Gabriel Radanne mentioned some related work

Original write up: https://mirage.io/blog/introducing-functoria
relevant API: https://docs.mirage.io/mirage/Mirage/index.html#val-if_impl
Note that there is quite a bit of staging going on, so it doesn't really respect your API, but the spirit is there.

release of iter 1.2

Simon Cruanes announced

@Drup and myself have the pleasure to announce the first release of Iter (née Sequence). Its version is 1.2, following Sequence 1.1. We renamed Sequence into Iter to remove some confusion with Seq (the stdlib's iterator type).

Iter provides combinators to create, consume, and transform iterators of type ('a -> unit) -> unit; in other words, partially applied iter function such as Hashtbl.iter, List.iter, Array.iter, etc. It has a wealth of advanced combinators and performs very well even with nested flat_map, map, etc. A very simple example that manipulates a series of integers:

# #require "iter";;
# let p x = x mod 5 = 0 in
  Iter.(1 -- 5_000
   |> filter p
   |> map (fun x -> x * x)
   |> fold (+) 0);;
- : int = 8345837500

Here is a comparison with the standard Seq, explaining their differences and the use case for both.

link to the release

Let+ syntax backported to OCaml >= 4.02

Jérémie Dimino announced

The upcoming OCaml 4.08 release will allow developers to define custom bindings operators. We were eager to use this feature in the code of Dune but because we are currently keeping compatibility with all versions of OCaml since 4.02, we decided to implement a preprocessor shim for older OCaml versions. Given that this shim works quite well, we are also making it available for users of Dune starting with version 1.8 which will be released soon. This post explains how to use this new feature.

The future_syntax preprocessor

If you want to use custom bindings in your code but need to keep your code compatible with OCaml < 4.08, you can use the special future_syntax preprocessor introduced in Dune 1.8. To do that, simply add the following field to your library/executable stanza:

(preprocess future_syntax)

When using OCaml >= 4.08, this is exactly equivalent to just deleting this field. This means that future_syntax doesn't add overheard when using a recent version of the compiler. When using using OCaml < 4.08, this will automatically add a pre-processor that will translate special let+, let*, and+, … operators into valid pre-4.08 OCaml code, allowing your code to compile with an older compiler.


The shim preprocessor converts bindings operators to OCaml identifiers of the form let__XXX and and__XXX. For instance, let+* is translated to let__plus_star. So you must make sure to not use such identifiers in your code.

Complete example

The following example uses the future_syntax preprocessor and bindings operators in code using the cmdliner library.

dune file:

 (name foo)
 (libraries cmdliner)
 (preprocess future_syntax))

foo.ml file:

open Cmdliner

let ( let+ ) t f =
  Term.(const f $ t)
let ( and+ ) a b =
  Term.(const (fun x y -> x, y) $ a $ b)

let term =
  let+ a = Arg.(value & flag & info ["a"] ~doc:"blah")
  and+ b = Arg.(value & flag & info ["b"] ~doc:"blah")
  and+ c = Arg.(value & flag & info ["c"] ~doc:"blah")
  Printf.printf "a=%B b=%B c=%B\n" a b c

let cmd = (term, Term.info "foo" ~version:"v1.0.3" ~doc:"example")

let () = Term.(exit @@ eval cmd)

You can test this example with:

dune exec ./foo.exe -- -a -b

Without bindingins operators, foo.ml would have to be written as follow:

open Cmdliner

let term =
  let main a b c =
    Printf.printf "a=%B b=%B c=%B\n" a b c
  Term.(const main
        $ Arg.(value & flag & info ["a"] ~doc:"blah")
        $ Arg.(value & flag & info ["b"] ~doc:"blah")
        $ Arg.(value & flag & info ["c"] ~doc:"blah")

let cmd = (term, Term.info "foo" ~version:"v1.0.3" ~doc:"example")

let () = Term.(exit @@ eval cmd)

Which shows that binding operators are especially nice when working with such API; indeed, without binding operators the authors and readers of the code have to manually match the order of arguments passed to main with the order of the Arg.(...) expressions inside the Term.(...) expression. With binding operators, the OCaml variable to which the evaluation of the command line argument is bound is right next to its definition, which is much nicer to read and write.

Richard Davison

This looks awesome! Just got a question about versioning of the future_syntax preprocessor. I like how easy it is to specify it in the dune files, but I'm concerned about what will happen if one day you want to deprecate this preprocessor and support yet another "future_syntax".

For example, in the python2 community, it's common to see people specifically select which future syntaxes to use by writing:

from __future__ import print_function

Jérémie Dimino

future_syntax will be versioned in the same way as other features provided by dune. If in the future we decide to change what future_syntax means, then its meaning will simply be tied to the (lang dune x.y) you write in your dune-project file.

That said, I don't think we will be able to provide much more than custom binding operators in dune. Indeed, the only form of extensibility provided by the OCaml parser is a lexer hook and ast mappers. This was enough to easily retrofit the let+ syntax, but it won't be enough for other more complex new syntax forms. At some point, we would need to import the whole OCaml frontend, which doesn't seem viable.

Cucumber.ml v1.0.1

Christopher Yocum announced

I just wanted to let anyone who might be interested know that I have released v1.0.1 of Cucumber.ml. There is not much in this release, hence the minor version bump. Cucumber.ml relies on Janestreet's Base library and there was a change in that library around the Base.List.zip function. Users should not notice any changes in functionality as it was only used in a private module function.

On a related note, if you actually use Cucumber.ml, I would be very happy to hear it.

Developer position at Be Sport, Paris

Vincent Balat announced

Be Sport has open positions for OCaml software developers in Paris. Depending on their skills, the developers will either join our data team or our app development team. Beginners or experimented programmers welcome.

For more information or if you are interested, please send me a private message here or email jobs@besport.com

Be Sport is developing the Be Sport social platform for athletes, teams and sport fans (https://www.besport.com + Android and iOS apps, fully developed in OCaml with Ocsigen). Be Sport is also the main contributor to the Ocsigen project.

Knowledge welcome (but not mandatory):

  • iOS development
  • Web development
  • Data science
  • Database

Jamie asked and Vincent Balat replied

> Is remote work an option?

Unfortunately not for now.

IMPORTANT: Switching from Mantis to GitHub issues on March 14th

Nicolás Ojeda Bär announced

We are going to switch the OCaml bug tracker from Mantis to GitHub issues on Thursday, March 14. Existing bug reports will be migrated with the help of a script. On this day, Mantis will be offline and the GitHub repository will be read-only until the migration is finished.

A reminder will be sent to this list shortly before the migration.

IMPORTANT: if you wish to have the migrated issues use your GitHub user name instead of your Mantis user name, you MUST send me both user names before March 14 so this is taken into account during migration. This may be convenient if you want to be automatically subscribed to issues you authored and/or monitored in Mantis and you do not already subscribe to all GitHub notifications.

Do not hesitate to get back to me if you have any questions.

Best wishes, Nicolás on behalf of the OCaml development team

Odoc 1.4.0 — new OCaml documentation generator

Anton Bachin announced

We are pleased to announce release 1.4.0 of odoc, the new, Dune-friendly documentation generator for OCaml and ReasonML.

Some sample output, which you can browse here:


You can install odoc and generate docs for your Dune project with:

opam update
opam install odoc
dune build @doc

Then, view the docs by opening _build/default/_doc/_html/index.html!

While release 1.4.0 has new features, it is mainly focused on stability and maintainability. See its full changelog here. The previous release, 1.3.0 last October, included a lot of new code. Because of concerns about its stability, we chose not to widely announce 1.3.0. So, this message serves as an announcement for both releases :) The full changelog for 1.3.0 can be found here.

In summary, compared with 1.2.0, odoc now has:

For now, we plan to continue improving the stability of odoc and the quality of its output. In the longer term, odoc has two significant goals:

  • To replace ocamldoc as OCaml's primary documentation generator. At the core of odoc is a powerful cross-referencer, capable of fully handling the complexity of OCaml's module system. Shortcomings in ocamldoc's ability to resolve cross-references in complex projects were one of the original motivations for starting odoc.
  • To create centrally-hosted, cross-referenced, searchable online documentation for all the published packages in opam, a “~docs.ocaml.org~.”

Thanks to the odoc users and contributors, and happy documenting!


Later in the discussion, Daniel Bünzli said

JaneStreet's documentation has precisely been updated with this tool. If you are unhappy with the theme they choose you can simply:

opam install ocaml-manual base odig
odig odoc-theme list # spot the theme id you'd like
odig odoc-theme set --default mytheme
odig doc base

Regarding the OCaml API reference just odig doc ocaml and if you install the manual as above it will theme accordingly (see for example here for the manual themed according to odig.light — though the api reference that comes with the manual itself doesn't, just use the odig generated one).

If you are still unhappy about the selection of themes just provide your own and distribute it via opam.

Other OCaml News


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.