[Caml-list] Attn: Development Editor, Latest OCaml Weekly News

Alan Schmitt
2025-01-14T08:20:59Z

[-- Attachment #1: Type: text/plain, Size: 21614 bytes --]

Hello

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

Table of Contents
─────────────────

On concurrency models
OCaml 5.3.0 released
dream-html and pure-html 3.9.5
Building an OCaml cross compiler with OCaml 5.3
Ppx deriving decoders
Ortac 0.5.0 testing higher order functions
Other OCaml News
Old CWN

On concurrency models
═════════════════════

Archive: <https://discuss.ocaml.org/t/on-concurrency-models/15899/24>

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.

[a book] <https://robur-coop.github.io/miou/introduction.html>

[a retrospective] <https://robur-coop.github.io/miou/retrospective.html>

[a manifesto] <https://robur-coop.github.io/miou/manifesto.html>

[happy-eyeballs] <https://github.com/robur-coop/happy-eyeballs>

OCaml 5.3.0 released
════════════════════

Archive: <https://discuss.ocaml.org/t/ocaml-5-3-0-released/15916/1>

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.

[OCaml issue tracker] <https://github.com/ocaml/ocaml/issues>

dream-html and pure-html 3.9.5
══════════════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-dream-html-pure-html-3-9-5/15917/1>

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.

[the docs]
<https://yawaramin.github.io/dream-html/dream-html/Dream_html/#type-safe-routing>

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.

[the docs]
<https://yawaramin.github.io/dream-html/dream-html/Dream_html/#dreamwork>

[this screen recording]
<https://x.com/yawaramin/status/1873091198380065132>

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!

[RezwanArefin01] <https://github.com/RezwanArefin01>

[snapshots]
<https://github.com/yawaramin/dream-html/blob/e2a66cc199a28fd3d4a5440a124c90f578b8ae90/test/pure_html_test.expected.txt>

[as attribute]
<https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link#as>

Building an OCaml cross compiler with OCaml 5.3
═══════════════════════════════════════════════

Archive:
<https://discuss.ocaml.org/t/building-an-ocaml-cross-compiler-with-ocaml-5-3/15918/1>

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.

[1] <https://github.com/ocaml/ocaml/pull/13526>

[2] <https://github.com/ocaml/ocaml/pull/13674>

[5.3] <https://discuss.ocaml.org/t/ocaml-5-3-0-released/15916>

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.

[target triplet]
<https://www.gnu.org/software/autoconf/manual/autoconf-2.71/html_node/Specifying-Target-Triplets.html>

[CI tests for cross compilers]
<https://github.com/ocaml/ocaml/blob/trunk/.github/workflows/build-cross.yml>

[example]
<https://gist.github.com/shym/44da1daaefe11c74e6c4363b14ae7ee0#file-ocaml-cross-windows-opam>

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].

[example]
<https://gist.github.com/shym/44da1daaefe11c74e6c4363b14ae7ee0#file-ocaml-cross-windows-opam>

[`5.3+ocross'] <https://github.com/shym/ocaml/tree/5.3+ocross/>

[comparison]
<https://github.com/ocaml/ocaml/compare/5.3.0...shym:ocaml:5.3+ocross>

[own branch] <https://github.com/shym/ocaml/tree/5.3.0+ocross-squashed/>

Ppx deriving decoders
═════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-ppx-deriving-decoders/15921/1>

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!

[ocaml-decoders] <https://github.com/mattjbray/ocaml-decoders>

[ppx_deriving_decoders]
<http://github.com/benbellick/ppx_deriving_decoders>

Ortac 0.5.0 testing higher order functions
══════════════════════════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-ortac-0-5-0-testing-higher-order-functions/15945/1>

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!

[QCheck-STM] <https://github.com/ocaml-multicore/multicoretests>

[Gospel] <https://github.com/ocaml-gospel/gospel>

[Ortac/QCheck-STM documentation]
<https://ocaml-gospel.github.io/ortac/ortac-qcheck-stm/index.html>

[Ortac/Dune README]
<https://github.com/ocaml-gospel/ortac/blob/main/plugins/dune-rules/README.md>

[`examples' folder]
<https://github.com/ocaml-gospel/ortac/tree/main/examples>

Other OCaml News
════════════════

From the ocaml.org blog
───────────────────────

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

• [The Most Elegant Configuration Language]

[the ocaml.org blog] <https://ocaml.org/blog/>

[The Most Elegant Configuration Language]
<https://chshersh.com/blog/2025-01-06-the-most-elegant-configuration-language.html>

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].

[Alan Schmitt]

[send me a message] <mailto:alan.schmitt@polytechnique.org>

[the archive] <https://alan.petitepomme.net/cwn/>

[RSS feed of the archives] <https://alan.petitepomme.net/cwn/cwn.rss>

[caml-list] <https://sympa.inria.fr/sympa/info/caml-list>

[Alan Schmitt] <https://alan.petitepomme.net/>

[-- Attachment #2: Type: text/html, Size: 37089 bytes --]