OCaml Weekly News

Previous Week Up Next Week


Here is the latest OCaml Weekly News, for the week of July 05 to 12, 2022.

Table of Contents

Dune how to define custom build task

cnmade explained

dune has very powerful extensions, but the documentation doesn't tell you directly. Today I'll share a specific example of how we can make dune do many things with a dune configuration.

For example

  • Publish compiled documents to our documentation server
  • Sending email notifications to email groups
  • Sending SMS notifications to administrators
  • Build a document and open a browser to preview the document page

Let's start with an example, we create a dune file in the root directory of our project, which you may not have originally, you have to create a new one, we enter the following

; now we tell you how to define a custom rule
; rule start with (rule )
; (alias is point  the command name , so you can run this rule by call  dune build @docopen
 (alias docopen)
 ; following line is very important, it tell dune do not cache this build command, so it will running every call
without any cache
 (deps (universe))
 ; action  (system  to told system run command by `sh` in your Linux/MacOS, windows user may running cmd.exe
 ; cd ../.. is change the base directory of the running command ,or the default directory will be _build/default
 (action (system "cd ../.. && pwd &&  dune build @doc && open _build/default/_doc/_html/index.html" ))
; end of one piece of rule

; and we define more and more rule as we want
  (alias whoami)
  (deps (universe))
  (action (system "uname -a;whoami"))

In this example, we define two rules, the rules are the tasks that dune can recognize, in dune, it is called rules

Because it is a custom build command, we use alias to take a unique and non-repeating alias.

The first build command is to build the document and open the browser preview.

Our alias is docopen

Then deps we add universe to tell dune that you don't want to cache and give me a new build every time. If you don't add this line, dune will only give you one build, and then because of the cache, you won't be able to execute it later.

action following by system here, action is the command to start, system means to use the system shell (windows is cmd, linux macos is sh) to give you the execution of the code you specify.

You can see the first we are first change the directory to the project root directory [because the default directory is _build/default], and then we perform the build document generation, and then open open the generated html page.

The first build command is this, if you want to perform the first build task, you can type

dune build @docopen

Then our second build command, relatively simple, with reference to the first, we can add a lot of build commands we want to add inside this dune configuration file.

We just need to specify different alias aliases for them, no duplication.

The official documentation also specifies some other available commands, I won't go into them one by one. Since I prefer to use shell scripts, I really only need the system to execute my shell scripts for me.

Timedesc 0.8.0 - modern date time handling

Darren announced

I'm pleased to announce the release of Timedesc 0.8.0.

Timedesc is a very comprehensive date time handling library with good support of time zone.



  • Timestamp and date time handling with platform independent time zone support
    • Subset of the IANA time zone database is built into this library
  • Supports Gregorian calendar date, ISO week date, and ISO ordinal date
  • Supports nanosecond precision
  • ISO8601 parsing and RFC3339 printing

Main changes since 0.6.0

  • Significantly reduced size of time zone database by using a custom compression scheme
    • Many thanks to @glennsl for the proposed scheme at issue #46
    • This yields reduction of roughly 82% for same date period. The exact range of years included has been tuned slightly as well and I've lost track of the exact size after compilation.
  • Significantly reduced the number of dependencies, and moved JS, JSON code into separate packages
    • Removed dependencies: fmt, containers, oseq
      • Introduced sexplib dependency for sexp handling consequently as previously containers CCSexp was used
    • Moved JSON code into timedesc-json package along with Yojson dependency
    • Moved tzlocal and tzdb stuff into their own separate packages (timedesc-tzlocal and timedesc-tzdb respectively)
    • Moved JS tzlocal backend into timedesc-tzlocal-js (along with JS specific dependencies)

Quality of life changes

  • Updated string conversion functions based on pretty printers which raise Date_time_cannot_deduce_offset_from_utc to raise the exception instead of returning None
    • This simplifies the handling as return type is now simply just string
    • And for serious stuff users are expected to use only unambiguous date times anyway, which would not trigger this exception
  • Added ISO8601 printing facilities to Timestamp module for consistency
    • They are just aliases to the RFC3339 printers

containers 3.9

Simon Cruanes announced

I'm happy to announce that containers 3.9 has just been released. Containers is a lightweight, modular extension of the stdlib that tries to remains compatible with it.

Containers is starting to sprout some serialization primitives: it now has codecs for Bencode and CBOR. This release also contains a revamp of the testlib system (bye qtest) and the use of ocamlformat, for potential contributors who enjoy that. Containers should also be compatible with OCaml 5.0.

OBazl 2.0.0-alpha-1 (Building OCaml SW with Bazel)

Gregg Reynolds announced

I've tagged alpha versions of OBazl rules_ocaml and tools_opam. The best way to start exploring is via demos_obazl, which contains over 100 mostly simple demo/test programs, many of which are commented. Three simple commands get you configured and then bazel test test runs all the tests.

Tested on MacOS 12.4 and Ubuntu 20.

Documentation is still in progress but there is useful info at The OBazl Book.

Lot's of things to say about this version but I'll stick to one point of interest. The four basic OCaml compilers are modeled by Bazel's platforms and toolchains mechanisms. Two of the compilers are actually cross-compilers (e.g. ocamlc.opt runs on the system arch but targets the OCaml vm), so to pick a compiler you tell OBazl which buildhost and targethost platforms you want. I've predefined configurations in .bazelrc; for example:

build:bcnc --host_platform=@opam//tc/host/build:bc
build:bcnc --platforms=@opam//tc/host/target:nc

which means to select the ocamlopt.byte (cross-)compiler, pass --config=bcnc.

Kinda cool IMHO. Maybe overkill for the basic compilers, but the mechanism is essential to support remote builds, custom compiler implementations and genuine cross-compilers.

Feedback welcome.

QCheck 0.19

Jan Midtgaard announced

I'm happy to share the release of QCheck 0.19 - a library for property-based testing in OCaml in the style of Haskell's QuickCheck.

The 0.19 release brings a range of new features and improvements detailed below and combines the effort of several individual contributors.

It is now available on opam.

Release notes:

  • new features and feature extensions
    • add optional debug_shrink parameters in alcotest interface and expose default debug_shrinking_choices in test runners
    • add missing ?handler parameter to Test.check_cell_exn
    • add an option retries parameter to Test.make et al. for checking a property repeatedly while shrinking. This can be useful when testing non-deterministic code.
    • add tup2 to tup9 for generators
    • add Test.make_neg for negative property-based tests, that are expected not to satisfy the tested property.
    • add environment variable QCHECK_LONG_FACTOR similar to QCHECK_COUNT
    • rename Gen.opt to Gen.option but keep the old binding for compatibility.
    • shrinker changes
      • recursive list shrinker with better complexity
      • string shrinker reuses improved list shrinker and adds char shrinking
      • function shrinker now shrinks default entry first and benefits from list shrinker improvements
      • replacing the linear-time char shrinker with a faster one reusing the bisecting int shrinker algorithm
      • add Shrink.char_numeral and Shrink.char_printable
      • add shrinking for char arbitrary~s ~char, printable_char, and numeral_char
  • bug fixes
    • fix function generation affecting reproducability
    • fix distribution of QCheck2.printable which would omit certain characters
    • use Float.equal for comparing float~s in the ~Observable module underlying function generators.
  • documentation updates:
    • clarify upper bound inclusion in Gen.int_bound and Gen.int_range
    • clarify printable_char and Gen.printable distributions
    • add missing string_gen_of_size and small_printable_string documentation
    • document QCheck_alcotest.to_alcotest
    • fix documented size distribution for arbitrary generators string_gen, string, printable_string, numeral_string, list, and array
    • fix exception documentation for check_result, check_cell_exn, and check_exn
    • fix documentation for the distribution of Gen.printable and printable_char
    • fix documentation for the shrinking behaviour of QCheck2.printable
  • internal and test suite changes
    • add additional expect and unit tests and refactor expect test suite
    • add a shrinker performance benchmark
    • remove --no-buffer option on dune runtest to avoid garbling the test output
    • make test suite run on 32-bit architectures

Opam-cross-windows now supports OCaml 4.14.0!

Romain Beauxis announced

Bit of a late announcement but the opam-cross-windows project now supports the OCaml compiler version 4.14.0: https://github.com/ocaml-cross/opam-cross-windows

The opam-cross-windows project is part of an initiative started by @whitequark to provide cross-compilation support to existing opam packages. This allows users to compile binaries for windows but also android and ios on a linux or macos host.

Support for packages is a on best-effort basis and is always looking for more contributors. Adding a package can be a little tricky at times but, if your package uses dune, the cross-compilation support there is pretty wonderful and makes it pretty easy to add cross-compiled packages.

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.