OCaml Weekly News

Previous Week Up Next Week

Hello

Here is the latest OCaml Weekly News, for the week of January 07 to 14, 2025.

Table of Contents

On concurrency models

Deep in this thread, Calascibetta Romain announced

For those interested, we've spent some time writing a book on how to use Miou and asynchronous programming with Miou — basically, it introduces Miou's design. In addition, resources that may be of interest are:

  • a retrospective of a handheld scheduler implementation compared to what Miou offers
  • a manifesto that says the same thing as what I said above

A next release of Miou is in preparation and additions to this ‘little book’ will be made. In particular, there will be an explanation of how we implemented happy-eyeballs, which remains a good example.

OCaml 5.3.0 released

octachron announced

We have the pleasure of announcing the release of OCaml version 5.3.0. dedicated to the memory of John William Mauchly and Paul Verlaine on the anniversary of their death.

De la musique avant toute chose,
Et pour cela préfère l’Impair

(Music first and foremost of all!
Choose your measure of odd not even)

Some of the highlights in OCaml 5.3.0 are:

  • Syntax for deep effect handlers

    There is now a dedicated syntax for installing deep effect handler

    match f () with
    | x -> x
    | effect Random_float, k -> Effect.Deep.continue k (Random.float 1.0)
    

    This new syntax adds a new effect keyword, which may break existing code. To improve backward compatibility, this new keyword can be disabled with the new -keywords flags if needed for backward compatibility.

  • Restored MSVC port

    It is now possible to use the MSVC toolchain on Windows, restoring the last missing port from OCaml 4 (except for the native compiler support for 32-bit architectures which is not planned)

  • Re-introduced statistical memory profiling (statmemprof)

    The submodule Gc.memprof is restored with a slightly different API. This submodule can be used to monitor memory allocation statistics inside a program. In OCaml 5, each domain can be monitored independently while child domains inherit the parent domain profiling profile (if there is one active).

  • utf-8 encoded Unicode source files and modest support of Unicode identifiers

    type saison = Hiver | Été | Printemps | Automne 
    

    The OCaml lexer has been extended to support a modest subset of Unicode characters in identifiers. This is mostly intended for pedagogical use. This extended support requires source files to be utf-8 encoded Unicode text.

  • More space-efficient implementation of Dynarray

    The internal implementation of Dynarray now uses an unboxed representation which avoids the need of storing items wrapped in a Some x block and thus save some spaces and indirections.

  • Improved metadata on the pairs of declarations and definitions for merlin.

    The metadata stored inside cmt files has been improved to better distinguish the provenance of identifiers (previous versions could confuse an interface and implementation identifier). Similarly, the metadata now tracks more precisely the association between declarations and definitions. For instance, in

    module X = struct let x = 0 end
    module M: sig
      val x: int
    end = struct
      let x = 1
      include X
    end
    

    Merlin can now determine that the definition of the M.x value lies inside the module X.

And a lot of incremental changes:

  • Around 20 new functions in the standard library (in the Domain, Dynarray, Format, List, Queue, Sys, and Uchar modules).
  • Many fixes and improvements in the runtime
  • Improved error messages for first-class modules, functors, labelled arguments, and type clashes.
  • Numerous bug fixes

Please report any unexpected behaviours on the OCaml issue tracker.

The full list of changes can be found in the changelog below.

editor note: please visit https://discuss.ocaml.org/t/ocaml-5-3-0-released/15916 for the changelog

Happy hacking, Florian Angeletti for the OCaml team.

dream-html and pure-html 3.9.5

Yawar Amin announced

Happy to announce that dream-html and pure-html 3.9.5 are now available on opam. This is a significant release with three main new things:

  1. Type-safe paths and routing
  2. Support for static asset caching
  3. HTML improvements

Type-safe paths and routing

Allows defining paths as values that can be handled by a router and also rendered by the HTML markup generator, so that the actual routed paths are in sync with the rendered paths in the application. These paths use OCaml's built-in format strings rather than a new DSL: eg /orders/%s/versions/%d. This makes it possible to extract type-safe values from path segments and pass them to the handler; render markup with guaranteed correct paths; and refactor the app's paths without having to hunt for hard-coded strings.

See the docs for details.

Static assets support

Automates the handling of static assets in the application so that they can easily be served by the router with an immutable cache policy and their paths can be rendered in markup with a content-based revision hash, for easy cache-busting.

Added a new CLI tool dreamwork which helps with scaffolding this static assets setup. The intention is to use it for more scaffolding tasks in the future–stay tuned.

See the docs for details, and this screen recording for a short demo.

HTML improvements

Thanks to RezwanArefin01 for prettifying the generated HTML. It is now formatted and much easier to read. See the snapshots for some examples.

Lastly, added HTML.as_ which is the as attribute.

Enjoy!

Building an OCaml cross compiler with OCaml 5.3

shym announced

A cross compiler is a compiler that runs on some host machine, for instance one running Linux on a 64-bit ARM processor, and generates code for a different target machine, for instance one running Windows with a 64-bit x86 processor. Building OCaml cross compilers used to be quite tricky and hackish but many incremental changes to the build system over the last years have improved radically the situation. So much so that, with the most recent changes (1, 2) in the development branch of the compiler, it should be possible to build many cross compilers without extra changes :crossed_fingers:

This is all well and good, you might say, but you would rather play with the brand new 5.3 instead of a development branch! So I’ve backported the necessary changes to 5.3.

How to build and use a OCaml 5.3 cross compiler

To make it easy to test, I’ve written an example OPAM file that can be customised to suit your goal. It takes the example of building a cross compiler to 64-bit x86 Windows MinGW, in particular because that always reveals unexpected issues :-)

  1. Start by creating a 5.3.0 OPAM switch if you haven’t already.
  2. Choose the target you want to create a cross compiler for and find its target triplet. The GCC C cross compilers and the GNU cross binutils use target triplets as prefixes for the commands, so an easy way to find your triplet is to install the tools. So:
  3. Install the C cross compiler and toolchain for your target. Many Linux distributions package some cross compilers. For instance, the CI tests for cross compilers installs on Ubuntu:
    • the gcc-mingw-w64-x86-64 package (which depends on the matching binutils) to cross compile to 64-bit x86 Windows MinGW; in that case, that target machine is identified by the x86_64-w64-mingw32 triplet, so it calls configure with the argument --target=x86_64-w64-mingw32,
    • the gcc-aarch64-linux-gnu package to cross compile to 64-bit arm Linux; in that case, the target machine is identified by the aarch64-linux-gnu triplet.
  4. Create a new OPAM package interactively for instance by choosing the name of the package (ocaml-xyz or even ocaml-cross-xyz are good choices I’d say; my example uses ocaml-cross-windows, for instance) and run:

    opam pin add --edit ocaml-cross-xyz -
    

    This will open an editor so that you can fill in the instructions on how to build your cross compiler. Use my example to get you started. In particular you’ll want to configure the --target parameter with the triplet for your target (that could be the only change!). If your toolchain and C compiler use that triplet as a prefix for all the commands, configure will find them automatically. Otherwise you’ll need to explicitly set them, by adding arguments such as CC=... to configure. The CI tests for cross compilers contains such an example to cross compile to Android where CC, AR, PARTIALLD, RANLIB and STRIP are explicitly set… In other words, I suggest to experiment first with an example with automatic configuration!

You should now have a cross compiler! Let’s use it on a simple sanity check test.ml:

(* Is the proper (target) OS identified? *)
let _ =
  Printf.printf "Version: %s\nOS: %s\nUnix: %b\nWin: %b\nCygwin: %b\n"
    Sys.ocaml_version Sys.os_type Sys.unix Sys.win32 Sys.cygwin

(* Do the compiler libs work? *)
(* The interface for [Arch] is not the same across processor architectures, the
   following assumes your target is 64-bit x86 *)
let _ =
  Printf.printf "allow_unaligned_access = %b\n" Arch.allow_unaligned_access;
  Printf.printf "win64 = %b\n" Arch.win64

The package ocaml-cross-xyz will install an ocamlfind toolchain called xyz. So we can compile test.ml thus:

ocamlfind -toolchain xyz opt -package compiler-libs.optcomp -linkpkg test.ml -verbose

where -verbose let you check what is actually being run. If your target is Windows MinGW (so cross compiling from some unix), you probably need an extra step before this compilation can go through: the tool flexlink.exe which is used to link the final Windows binary has been built as part of the package but ocamlopt will expect to find a command flexlink (note in particular the absence of .exe) so I suggest to ln -s the flexlink binary somewhere in your PATH. For instance, it could be:

ln -s "$(opam show --list-files ocaml-cross-xyz | grep flexlink.opt.exe)" ~/bin/flexlink

and then you will be able to run the ocamlfind -toolchain ... command to compile your program.

Gotchas and details

  1. Beware that having a flexlink command in PATH breaks OCaml (5.3 and before)’s configure if you’re not on Windows; this will be fixed in 5.4.
  2. The example OPAM package contains SHA256 sums for .patch files generated on the fly from the corresponding commits but they might change without notice (to add an extra digit to the SHA1 they contain, for instance). If you notice that, ping me so that I can update the SHA256 sums in the gist.
  3. The example OPAM package pulls the official OCaml 5.3.0 archive along with two patches:

    • the first one is a large commit that squashes all the commits that I backported from upstream,
    • the second one is a small commit that adds the generation of the ocamlfind toolchain configuration.

    You can find the detailed backport on my 5.3+ocross branch and its comparison with the official release. The squashed commit lives on its own branch.

Ppx deriving decoders

Ben Bellick announced

A little late but wanted to share a package I have released!

For those familiar with the excellent ocaml-decoders package, I have written ppx_deriving_decoders to automatically generate the corresponding decoders (and encoders) based off of type definitions.

In my view, this gives the best of both worlds in terms of:

  1. automatically generating (e.g. JSON) serialization and deserialization based off of a type definition, and
  2. having a readable and expressive language for handwriting encoders and decoders when necessary by using combinators.

The instructions in the README demonstrate how you can use the generated decoder as a base point from which to hand tweak and get your own custom decoder.

Please let me know if you find it useful or have any feedback. Thanks!

Ortac 0.5.0 testing higher order functions

Nicolas Osborne announced

Hi everyone!

I'm very pleased to announce the release of the Ortac-0.5.0 packages for specification-driven testing!

Ortac/QCheck-STM is a test generator based on the QCheck-STM model-based testing framework and the Gospel specification language for OCaml.

This new release brings three new features.

In the effort to increase the coverage of the generated tests and thanks to Jan Midtgaard, we now support testing higher order functions. Thanks Jan!

It is also now possible to test a module exposed as a sub-module by Dune, specifying the module's prefix in a CLI optional argument. A feature that we've been asked to add.

And to test an actual sub-module defined inside an OCaml file, specifying the sub-module in a CLI optional argument as well.

Ortac/Dune generates the Dune boilerplate for you. It has been updated to support the two new optional arguments.

You can install those packages via opam:

$ opam install ortac-qcheck-stm ortac-dune

Then you write some Gospel specifications in your library's interface file foo.mli:

type 'a t
(*@ mutable model contents : 'a sequence *)

val make : int -> 'a -> 'a t
(*@ t = make i a
    ensures t.contents = Sequence.init i (fun _ -> a) *)

val for_all : ('a -> bool) -> 'a t -> bool
(*@ b = for_all p t
    ensures b = Sequence.fold_left (fun acc a -> acc && p a) true t.contents *)

Then a simple configuration file foo_config.ml:

type sut = char t

let init_sut = make 42 'a'

And you can generate some specification-driven model-based tests for your library just by running:

$ ortac qcheck-stm foo.mli foo_config.ml

If you want to integrate the generation and the running of the tests to your dune setup (which is highly recommended), just add the following stanza to your dune file in your test directory:

(rule
 (alias runtest)
 (mode promote)
 (action
  (with-stdout-to
   dune.inc
   (run ortac dune qcheck-stm foo.mli))))

(include dune.inc)

You'll find more information in the Ortac/QCheck-STM documentation, the Ortac/Dune README and the examples folder. I'm also happy to answer questions.

Happy testing!

Other OCaml News

From the ocaml.org blog

Here are links from many OCaml blogs aggregated at the ocaml.org blog.

Old CWN

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 to the caml-list.