Hello Here is the latest OCaml Weekly News, for the week of April 14 to 21, 2026. Table of Contents ───────────────── http-date v0.2 — Zero-dependency HTTP date parsing for OCaml Caqti 2.3.0 layoutz 0.1.0 🪶 - Zero-dep Elm-style TUIs and terminal plots for your OCaml apps Dune 3.22 ptt, a mailing list system as unikernel Mollymawk and Albatross orchestrating all virtual machines OUPS meetup april 2026 Stk 0.6 released opam 2.5.1 Restarting OCaml.jp: The OCaml Japan User Group Code navigation and search on Github Seeking maintainers for our OCaml SIP server, gRPC, and HTTP/2 libraries ppx_mixins: slightly more elegant mixin syntax Experience Report: Refining Dune’s Dependency Graph First beta release of OCaml 5.5.0 ocgtk 0.1: OCaml bindings for GTK 4 (preview release) Old CWN http-date v0.2 — Zero-dependency HTTP date parsing for OCaml ════════════════════════════════════════════════════════════ Archive: Bikal Lem announced ─────────────────── I just released v0.2 of http-date, an RFC 9110 compliant HTTP datetime decoder/encoder for OCaml. This is a major rewrite from v0.1. Here's what changed: Zero dependencies — Replaced the ocamllex/menhir parser with a hand-written implementation and removed the ptime dependency entirely. The library now only requires ocaml and dune. New type-safe API — The parsed result is now a polymorphic variant tagged by format (IMF, RFC850, `ASCTIME), so you always know which HTTP date format was parsed. The dayname, date, time, and datetime types are all exposed in the public API. Serious testing — Added property-based tests with alcobar and AFL fuzz testing infrastructure to build confidence in the hand-written parser. If you're working with HTTP headers in OCaml, give it a try: opam install http-date Caqti 2.3.0 ═══════════ Archive: Petter A. Urkedal announced ─────────────────────────── I would like to announce the release of [Caqti] 2.3.0. TL;DR: Consider adding the `caqti.classic' to your link line (available since this version). It currently only re-exports the `caqti' library, but will be replaced by a compatibility layer for the Caqti 2 API in Caqti 3 to allow incremental migration. [Caqti] Release Notes ╌╌╌╌╌╌╌╌╌╌╌╌╌ Note that some of the new features of this release are only accessible through the still unstable `caqti.template' library, which will soon be stabilized as part of an upcoming Caqti 3 API. Due to adjustments to module names, switching to `caqti.template' will not ensure future compatibility. Instead, users are encouraged to add the new `caqti.classic' to their dependencies to ease migration to Caqti 3. • Added an alias `caqti.classic' for the `caqti' library. This will be turned into a library providing compatibility with the current Caqti 2 API when Caqti 3 is released. The two APIs can be used side-by-side to allow incremental migration. • The dialect descriptor for MariaDB in `caqti.template' now provides the server version. • Added `Query.parens', `Query.litf', `Query.vars', `Row_type.fields' to the `caqti.template' library. • Revised the interface for creating row types to allow instantiating parametric types applicatively. Before this change, each application of a function representing a parametric type would generate a new type ID even when applied to the same type parameter argument. The key part of this interface is the `Caqti_template.Constructor_type' module. • The query functions provided to request templates are now memoized, so that they are only called once per dialect. This is meant as an optimization; it's still good practise to avoid side-effects here. • The new function `Query.with_pos_of' allows query generators to add source locations to the syntax tree, which will be emitted as SQL comments in the query string if the `enable_query_annotations' is set. This should simplify debugging when the query is assembled from different parts of the application code. • The still unstable `caqti.template' library now supports multiple statements in a single request template, sent opportunistically as a single query where allowed. This is still experimental. • Fixed package scoping of shim rules for sqlite3 (#133 by mefyl). • Fixed the error classification for the SQLite3 driver (#132). • Fixed reconnect after connection loss for PostgreSQL. layoutz 0.1.0 🪶 - Zero-dep Elm-style TUIs and terminal plots for your OCaml apps ═════════════════════════════════════════════════════════════════════════════════ Archive: Matthieu Court announced ──────────────────────── Hello all! Thanks for your feedback last time - [layoutz] now has an Elm-style TUI runtime (quite [different in spirit] than (the excellent) Minttea) … a smoothed API .. and terminal plot built-ins. Looking for feedback! Many thanks [layoutz] [different in spirit] Dune 3.22 ═════════ Archive: Continuing this thread, Shon announced ────────────────────────────────────── The Dune team is pleased to announce [the release of dune 3.22.2]. This is a patch release consisting of bug fixes. See [the full changelog] for all the changes and for attribution to the contributors who made it all possible. Thank you, contributors! If you encounter a problem with this release, please report it in [our issue [the release of dune 3.22.2] [the full changelog] Fixed ╌╌╌╌╌ • Revert the change in behavior of `--diff-command' back to 3.21. Non-existent files are now passed to this command instead of being replaced with /dev/null ([#14098], fixes 13891, [@rgrinberg]) [#14098] [@rgrinberg] ptt, a mailing list system as unikernel ═══════════════════════════════════════ Archive: Calascibetta Romain announced ───────────────────────────── Hey! We just launched a new mailing list powered entirely by OCaml unikernels. The website (itself a unikernel) is at . You can subscribe to ptt@mailingl.st by sending an email to ptt-subscribe@mailingl.st if you're interested in the development and deployment of SMTP-related unikernels. Fair warning: this is still a *public test* mailing list for now. In the long run, it will focus on our ptt project. The SMTP protocol: a long and winding road! ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ◊ In the beginning, email It all started with [Mr.MIME], our library for decoding and encoding emails. It's a synthesis of the relevant RFCs, but more importantly it's been battle-tested against real-world emails from the IEEE, [Enron], [KVM] and, most recently, the [caml-list]. This work also let us build [Hamlet], a database of valid random emails generated using a fuzzer. Under the hood, Mr.MIME relies on [unstrctrd] for decoding the most general form of values found in an email (with internationalisation support via [rosetta]) and [prettym] for encoding emails while respecting SMTP constraints and (Comment) Folding Whitespace handling. [Mr.MIME] [Enron] [KVM] [caml-list] [Hamlet] [unstrctrd] [rosetta] [prettym] ◊ Next, the protocol Then came [colombe], our OCaml implementation of the SMTP protocol. It uses [ocaml-tls] for `STARTTLS' support. The protocol is supposedly "simple" (though the Internet always has surprises in store), but from day one we designed colombe to be independent of any scheduler and network layer. That way it slots right into unikernels without friction. [colombe] [ocaml-tls] ◊ Finally, legitimacy On top of these core components, we built several email security layers: • [ocaml-dkim] handles signing and verifying email integrity in a streaming fashion (both for verification and signature generation) • [uspf] verifies sender identity and, like most of our libraries, stays independent of any scheduler or DNS implementation • [ocaml-dmarc] automates DKIM and SPF verification, stamps emails with the result, and checks alignment across a domain name • [ocaml-arc](github.com/robur-coop/ocaml-arc) lets you verify and sign emails to complete a chain of trust when an email passes through multiple SMTP servers (which is exactly what happens with a mailing list) We wrote a short article about all of this [here]. [ocaml-dkim] [uspf] [ocaml-dmarc] [here] All in the form of unikernels ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ Our first experiments already showed that we [could handle emails] with MirageOS unikernels. But we also hit real limitations: memory leaks, security vulnerabilities, and build issues. So we decided to start fresh, and take the opportunity to fully embrace OCaml 5 and effects. We rebuilt the key pieces from scratch: • a new effect-based scheduler: [Miou]/[Mkernel] • a much more complete TCP/IP stack: [Mnet] • a new FAT32 file system: [Mfat] `ptt' is built on this new stack, and so far we haven’t observed any memory leaks (thanks to [mkernel-memtrace] for tracing memory usage, viewable via [memtrace-viewer]). The CVEs related to [mirage-tcpip] were taken into account during ~mnet~’s development, and the build story is much simpler now. A GitHub action can build and actually run the unikernel to test it, as you can see with [mnet]. Other unikernels using this approach are available too. If you’re curious, check out [this tutorial] on creating a unikernel in OCaml. [could handle emails] [Miou] [Mkernel] [Mnet] [Mfat] [mkernel-memtrace] [memtrace-viewer] [mirage-tcpip] [mnet] [this tutorial] Deployment ╌╌╌╌╌╌╌╌╌╌ `ptt' also tackles the deployment question. We have [an article] presenting the "stateless" aspect of `ptt'. We'd also like to (re)introduce [Albatross](github.com/robur-coop/albatross), our secure unikernel orchestrator, and [Mollymawk], a web interface for deploying unikernels (which is itself a unikernel). More broadly, this is what [our cooperative] is working towards: we really want to improve the user experience, whether you're a developer or a deployer. We believe that actually developing, deploying, and using our unikernels is the only way to get them adopted more widely. So make sure to follow us on these projects too! [an article] [Mollymawk] [our cooperative] Usage ╌╌╌╌╌ Along the way, we found it really helpful to have a tool that lets you track every stage of an email’s lifecycle. That’s how [`blaze'] came about: a Swiss Army knife for handling emails. It’s still experimental, but it already lets you: • use our archive system (generate, read, index, etc.) • handle other archives such as `mbox' or `maildir' • communicate via the POP3 protocol • sign and verify emails (DKIM and ARC) • build emails from the command line • send emails • run a small local SMTP server `blaze' is how we iterate on our library APIs and validate implementations. It’s experimental, but it’s gradually turning into a full email client. [`blaze'] ◊ Archiving & Indexing We'd also like to present the [stem] project, which extracts word roots from a document (such as an email) and tokenises them to get something analysable without the complexity of natural language. This tokenisation is what powers our small [bm25] search engine. You can see results [here]. This is also what drives our caml-list search engine, available as a unikernel: [blame], which you can try at (powered by [vif]). Beyond search, there's also email indexing via Message-IDs. For that we built [bancos]: a *persistent* radix tree in OCaml that supports *parallel* access! More details [here]. Finally, our indexing system uses the PACKv2 format (the same one Git uses to store objects), implemented by the [carton] library. It has proven its stability through the [ocaml-git] project, so we decided to reuse it for archiving emails (much like [public-inbox] did, though in a different form). [stem] [bm25] [here] [blame] [vif] [bancos] [here] [carton] [ocaml-git] [public-inbox] Conclusion ╌╌╌╌╌╌╌╌╌╌ Thanks to all this work, OCaml now has a solid set of email-related projects. This journey started back in 2016 and there's still a long way to go, as we always aim to offer robu(r)st, battle-tested solutions. Unlike some implementations in other languages (though we are in discussion with folks in the Rust community), ours actually adhere to the standards! It may not seem like a big deal, and you won't see any major difference when just exchanging emails, but we believe this approach paves the way for a better internet. In the form of unikernels, it represents a genuine reclaiming of the means of communication! Mollymawk and Albatross orchestrating all virtual machines ══════════════════════════════════════════════════════════ Archive: Hannes Mehnert announced ──────────────────────── Dear everyone, we just finished and deployed [Albatross] and [Mollymawk] to support virtual machines that are not MirageOS unikernels. The reasoning is simple: we embedded so many nice features (metrics, console output, deploying via web UI, multi-tenant, startup dependencies, restart-on-failure,..) that we really wanted to deploy our non-MirageOS virtual machines as well with the same mechanism and don't have duplicated code all over. For the time being, it only supports FreeBSD BHyve, but let us know if you're interested in other virtualization technologies and we will prioritize that work! We also wrote a brief blog article with screenshots: [Albatross] [Mollymawk] OUPS meetup april 2026 ══════════════════════ Archive: ancolie announced ───────────────── The next OUPS meetup will take place on *Wednesday, 29th of April* 2026. It will start at *6:30pm* at the *45 rue d'Ulm* in Paris. It will be in the in the *Rataud amphitheater*. :warning: It's not in Jussieu as usual but in ENS Ulm! If you're not familiar with the place, there is a [map of the buildings]. Please, *[register on meetup ]* as soon as possible to let us know how many pizza we should order. For more details, you may check the [OUPS’ website ]. Moreover, we’d like to announce that the organizing team moved to the [OCaml Zulip]. Feel free to contact us there if you’d like to suggest talks. — This time we’ll have the following talks: *When Turing machines meet GADTs – Florian Angeletti* Have you ever wondered why one needs to write down explicit unreachable clauses in a GADT-pattern matching? Or how much computation one can sneak inside an OCaml type? This talk proposes to answers those questions and more with a deep dive into GADTs, the OCaml compiler implementation of the exhaustiveness checking for pattern match, and how to best trick the typechecker into finding the BB(3) champion by itself. *Extending OCaml's pattern matching – Yanni Lefki* Pattern matching has been studied for decades and has been the subject of extensive research and numerous extensions. Nevertheless, recent language features—such as Rust’s if-let construct, and recent work such as Cheng and Parreaux (OOPSLA 2024), suggest that there is still room for improvement. We propose a streamlined approach that unifies pattern matching with extended forms of conditionals. In particular, our prototype introduces binding-boolean-expressions, which allow variables to be bound within pattern guards, within if-conditions (and subsequently used in the then branch), and within while-conditions (and used in the loop body). Our system also incorporates Haskell-style views, enabling the definition of smart deconstructors, the dual of smart constructors. In this talk, we present an ML-like language equipped with evaluation rules, typing rules, and a simple compilation scheme. We conclude with a demonstration of our implementation: an OCaml PPX prototype that parses an extended ML syntax exposing these constructs, type-checks programs according to our (highly intuitive!) rules, and translates them into a correct OCaml AST via our (non-optimizing) transformation. — After the talks there will be some pizzas offered by the [OCaml Software Foundation] and later on we’ll move to a pub nearby as usual. [map of the buildings] [register on meetup ] [OUPS’ website ] [OCaml Zulip] [OCaml Software Foundation] Stk 0.6 released ════════════════ Archive: Zoggy announced ─────────────── Hello, Stk is a SDL-based graphical user interface toolkit. Its interface is inspired by Gtk and should look familiar to developers using Lablgtk. Stk 0.6 is available. Among changes listed [here], this release introduces [Tooltips] and [handling of user's configuration], including user-defined themes. The `stk*' packages are available from my [personal opam repository]. [here] [Tooltips] [handling of user's configuration] [personal opam repository] opam 2.5.1 ══════════ Archive: Kate announced ────────────── Hi everyone, opam 2.5.1 is now available. This release is fixing a security issue ([OSEC-2026-03]) and other minor things. /Thanks to [@andrew] for reporting this issue./ We invite everyone to upgrade to 2.5.1 as soon as possible. If you depend on the older opam package of your preferred distribution, distributions such as Debian Stable have already started backporting the relevant fix and the patched version should be available there very soon. You can read our [blog post] for relevant links and details. [OSEC-2026-03] [@andrew] [blog post] Try it! ╌╌╌╌╌╌╌ The upgrade instructions are unchanged: For Unix systems bash -c "sh <(curl -fsSL ) –version 2.5.1" or from PowerShell for Windows systems Invoke-Expression "& { $(Invoke-RestMethod ) } -Version 2.5.1" Please report any issues to the [bug-tracker]. Happy hacking, <> <> The opam team <> <> :camel: [bug-tracker] Restarting OCaml.jp: The OCaml Japan User Group ═══════════════════════════════════════════════ Archive: mt_caret announced ────────────────── Dear OCaml community, We're excited to announce the relaunch of *OCaml.jp* ([https://ocaml.jp/]), the OCaml Japan User Group! Our goal is to grow and energize the OCaml community in Japan by bringing together users to foster broader adoption and deeper engagement with OCaml across the country. [https://ocaml.jp/] Current Activities ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ We've already kicked off a couple of initiatives: • *OCaml Weekly News - Japanese Edition*: We're maintaining a Japanese translation of the OCaml Weekly News at [https://ocaml.jp/cwn-ja/], making it easier for Japanese speakers to stay up to date with the latest happenings in the OCaml ecosystem. • *OCaml Meetup in Tokyo (August 2026)*: We are currently preparing to host an OCaml Meetup in Tokyo this August, the first one in [over ten years]! More details will be shared soon; please stay tuned! [https://ocaml.jp/cwn-ja/] [over ten years] Join Us! ╌╌╌╌╌╌╌╌ We're using *Discord* as our primary communication platforms. Whether you're based in Japan, are a Japanese-speaking OCaml enthusiast anywhere in the world, or simply want to connect with the Japanese OCaml community, we'd love to have you join us! Please use the following link to join Discord: [https://discord.gg/qQTbny8KF4] We look forward to building a vibrant OCaml community in Japan together. よろしくお願いします! [https://discord.gg/qQTbny8KF4] Code navigation and search on Github ════════════════════════════════════ Archive: Pieter Goetschalckx announced ───────────────────────────── GitHub is now using [tree-sitter-ocaml] for [code navigation] and [code search]. • Code highlighting should be more accurate (compared to the old TextMate grammar) and supports all features up to OCaml 5.4. • There is a symbols side panel for each file. • You can click on symbols to find definitions and references. • You can [search for definitions]. • There is limited support for [nested structures]. They enabled it [a few months ago] already, but I forgot to post it here. The code navigation is not always 100% accurate, but good enough to be helpful. If you encounter any issues with incorrectly highlighted code, this could be a tree-sitter-ocaml issue. [tree-sitter-ocaml] [code navigation] [code search] [search for definitions] [nested structures] [a few months ago] Seeking maintainers for our OCaml SIP server, gRPC, and HTTP/2 libraries ════════════════════════════════════════════════════════════════════════ Archive: Wojtek Czekalski announced ────────────────────────── As we're moving off OCaml at [dialo], we'd like to donate the libraries we built to people who will properly maintain them. We built a highly performant telephony system using OCaml, but as a small team we ended up maintaining too much software for our liking. We initially built a SIP server implementation in OCaml, which was a perfect fit. We needed to connect it to the rest of our system in a language agnostic way. We chose gRPC and that's where things got difficult. At a smaller scale our own buggy implementation of gRPC on top of [h2] was good enough. Then we started scaling and at the same time transitioned to OCaml 5.0. The combination of those factors resulted in: 1. Performance regressions in 5.0 related to memory management, both inside of app code, SIP stack, and inside of h2. 2. We needed a more robust implementation of gRPC to handle errors and edge cases better. Long story short we ended up: 1. Writing our own implementation of [http2] 2. Rewriting the gRPC library exclusively for eio to limit the scope together with [decent codegen] and robust Then, in late 2025, we had to add new features to the SIP server and something inside us just broke. The SIP server had accumulated quite a bit of legacy code over 3.5 years, so we wanted to rewrite some parts. We were extremely excited to build the new architecture centered around effects — [only to discover that user-space effects and concurrency libraries don't really work well together], since callbacks lose their scope (duh). That was the final straw. We decided to run two 1-week stints to try rewriting the service in Rust and Go. We ended up choosing Rust. We still miss OCaml, but not having to implement and maintain our own http2/grpc/sip stack is a breath of fresh air. So here we are — we're gradually removing OCaml from our stack, and that's why we'd like to donate: • [ocaml-grpc] - the new code is on `dialo' branch, eio only at the moment, battle tested on production. It does have some bugs in it but few and it's pretty solid. • [haha (http2)] - overall good but could be better. We cancel fibers too often, it's a very low hanging fruit to make it much faster. • Our SIP stack — this is currently not open source, but we're happy to share the source code with the right person or team. Please write dms to me and feel free to ask me or @adamchol about specifics. [dialo] [h2] [http2] [decent codegen] [only to discover that user-space effects and concurrency libraries don't really work well together] [ocaml-grpc] [haha (http2)] ppx_mixins: slightly more elegant mixin syntax ══════════════════════════════════════════════ Archive: Sacha Ayoun announced ───────────────────── Hello, I've written a tiny ppx called [`ppx_mixins'] so that one can write: ┌──── │ type u [@@mixins Map.OrderedType + Printable] └──── which gets desugared to ┌──── │ type u │ include Map.OrderedType with type t := u │ include Printable with type t := u └──── Not much but increases readability in a codebase that uses the "mixin" pattern a lot [`ppx_mixins'] Constructing type signatures ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ In the upcoming release, one can also write ┌──── │ module type M = [%mixins Map.OrderedType + Printable] │ (* desugars to *) │ module type M = sig │ type t │ include Map.OrderedType with type t := t │ include Printable with type t := t │ end └──── Additional features ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ One can also override other types, e.g. ┌──── │ type u [@@mixins Mappable(key = int; value := v)] │ (* desugars to *) │ type u │ include Mappable with type t := u and type key = int and type value := v └──── Limitations ╌╌╌╌╌╌╌╌╌╌╌ • No support for parametric types, e.g. `with type 'a u = 'a v' • No support for tuple and function types, e.g. `with type t = int -> bool' This is because the preprocessor parses the payload as an expression, and these don't parse nicely a expressions. Deeper support (e.g. for mixins with type parameters) would probably also require language support. Experience Report: Refining Dune’s Dependency Graph ═══════════════════════════════════════════════════ Archive: Robin Bate Boerop announced ─────────────────────────── *Refining Dune's Dependency Graph: Per-Module Library Filtering* I've been working on improving Dune's inter-library dependency tracking, and wanted to share the experience — both the technical details and what it's like as a first-time contributor to this large open source OCaml project. The Problem I Took On ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ When `libA' depends on `libB', Dune gives every module in `libA' a glob dependency on /all/ `.cmi' files in `libB'. If any `.cmi' in `libB' changes, every module in `libA' is recompiled — even modules that never reference `libB'. For projects with many libraries, this creates a cascade of unnecessary recompilations. The issue that tracks this matter [#4572] has been open since 2021. [#4572] My Approach ╌╌╌╌╌╌╌╌╌╌╌ Dune already runs `ocamldep' to compute intra-library module dependencies. The key insight: that same output tells us which /libraries/ each module references, via their entry module names. We can use this to filter both the build dependencies and the `-I~/'-H~ compiler flags per-module. The implementation ([PR #14116] and [PR #14186]) works as follows: 1. For each module and its transitive intra-library dependencies, read the `ocamldep' output (both `.ml' and `.mli') 2. Union all referenced module names, including `-open' flags 3. Map those names to libraries via a `Lib_index' 4. Transitively close the filtered library set via `Lib.closure' 5. Use the result for both hidden deps and `-I~/'-H~ compiler flags, partitioning into direct (visible via `-I') and hidden (via `-H') based on `requires_compile' membership With both deps and flags filtered, a clean build will fail if a module references a library it doesn't declare — previously, overly-broad `-I' flags could mask such errors. [PR #14116] [PR #14186] A False Start ╌╌╌╌╌╌╌╌╌╌╌╌╌ My first attempt ([PR #14021]) tried to implement the filtering in a single PR without sufficient test coverage. It was closed after review revealed that the approach was fragile in edge cases I hadn't anticipated — particularly around transparent module aliases and virtual libraries. [PR #14021] Challenges ╌╌╌╌╌╌╌╌╌╌ *Transparent module aliases.* OCaml's module alias mechanism means `ocamldep' doesn't always report all libraries a module transitively depends on. If `libB' has `module M = LibC.Something', and a module in `libA' uses `LibB.M', `ocamldep' reports `LibB' but not `LibC'. The fix: transitively close the filtered library set using `Lib.closure', bounded by the compilation context. *Root modules.* The `(root_module)' stanza creates a module that implicitly aliases all libraries in the compilation context. When `ocamldep' reports a reference to a root module, we can't determine which underlying libraries are actually needed, so we fall back to the full dependency set. *Virtual libraries.* When virtual library implementations are present in the compilation context, parameter libraries may not appear in `requires_compile', so filtering could miss them. Another fallback case. *Menhir-generated modules.* These mock modules aren't in the `ocamldep' dependency graph, so we skip filtering for them. *Null build overhead.* The filtering reads `.d' files and computes library closures per-module. On a fresh `dune' process (no memo cache), this is new work on every build — including null builds where nothing changed. This is a real trade-off: better incremental rebuild performance at the cost of some null-build overhead. Prerequisite Test PRs ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ Before the implementation PRs, I submitted six test-only PRs to document existing behavior and establish a safety net: • [#14017] — Baseline tests documenting current inter-library recompilation behavior • [#14031] — Test documenting module name shadowing between stanzas and libraries • [#14100] — Test verifying library file deps in compilation rules and sandboxed builds • [#14101] — Test verifying transparent alias incremental build safety • [#14129] — Test verifying incremental builds with alias re-exported libraries • [#14178] — Test documenting `ocamldep' behavior with transparent alias chains This made the implementation PRs' diffs focused on the actual change, and gave reviewers confidence that existing behavior was preserved. It also helped me understand the edge cases that tripped up my first attempt. [#14017] [#14031] [#14100] [#14101] [#14129] [#14178] The Review Process ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ The Dune maintainers ([@rgrinberg] and [@art-w]) provided thorough, constructive reviews. Some highlights: • Replacing my hand-rolled transitive closure with `Lib.closure' from the existing library — a cleaner approach I wouldn't have found without familiarity with Dune's internals • Identifying that both `.ml' and `.mli' ocamldep output need to be read, since the interface can reference different libraries than the implementation • Suggesting per-module `-I~/'-H~ flag filtering, which makes clean builds more precise and improves caching • Questioning every fallback case and special-cased module kind, leading to simpler code The PRs went through significant refactoring during review — the final versions are substantially tighter than the initial submissions. [@rgrinberg] [@art-w] What Could Be Better ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ Working on this was a positive experience overall, but a few things created friction: *No way to benchmark before merging.* The null-build overhead question came up late in the process. I discovered through manual benchmarking that the change added \~70% to null build time — a significant regression. Dune's benchmark CI workflow runs only on pushes to main, not on PRs. Contributor-accessible performance tooling would help catch regressions before they land. *Review momentum vs. rebasing.* The test PRs merged quickly, but the implementation PR required multiple rounds of review over days. Between rounds, main moves forward, requiring rebases that risk introducing conflicts. The contributor carries the burden of keeping branches fresh. This is compounded when PRs depend on each other — every rebase of #14116 required rebasing #14186 as well. GitHub has no first-class support for PR stacks, so this is manual and error-prone. Of course, all GitHub-hosted repos suffer from this. *Flaky CI*. Many CI runs had errors that were not related to my code. It was often an upstream provider of an OCaml package that was unreachable or faulty (temporarily). These problems often resolved themselves, but caused day-long delays in the PR lifetimes. The problem stems from the setup code that is run and re-run over and over in CI jobs. Reflections ╌╌╌╌╌╌╌╌╌╌╌ The Dune codebase is well-structured, with clear separation between the build engine, rule generation, and scheduler. It is also of good quality, making it feel like time spent on keeping the quality high is worthwhile. I found the cram test infrastructure good for testing. Each test scenario is a self-contained shell script with expected output, making it easy to document and verify exact recompilation behavior. It inspires confidence in the code. The maintainers have been responsive and the review process, while slowed by thoroughness, is collaborative and professional. Thank you, maintainers! Steffen Smolka then replied ─────────────────────────── GitHub has no first-class support for PR stacks It does now: First beta release of OCaml 5.5.0 ═════════════════════════════════ Archive: octachron announced ─────────────────── With most developer tools available and the good stability of the compiler, I am happy to announce the first beta release of OCaml 5.5.0. Compared to the last alpha, this new version improves the manpage for ocamlopt and fixes: • two runtime bugs (for ephemerons and the bytecode interpreter) • two type system bugs (for classes and module-dependent functions) • three warning or error message bugs (See the Changelog below for a full list). Concerning the associated compiler tools, most of them are already available (as least in a preview version), and there are patches in progress for the remaining ones. You can track the last remaining update efforts on the [release readiness meta-issue]. Thus, it should be safe to test your libraries and programs with the new version OCaml 5.5.0 version in preparation of the final release. If everything goes well, we might see a release in May. If you find any bugs, please report them to the [GitHub issue tracker]. If you are interested by the full list of new features and bug fixes, the [changelog for OCaml 5.5.0] is the most up-to-date resource. Happy hacking, Florian Angeletti for the OCaml team. [release readiness meta-issue] [GitHub issue tracker] [changelog for OCaml 5.5.0] Installation Instructions ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ The base compiler can be installed as an opam switch with the following commands on opam 2.1 and later: ┌──── │ opam update │ opam switch create 5.5.0~beta1 └──── The source code for the beta is also available at these addresses: • GitHub: • OCaml archives at Inria: Fine-Tuned Compiler Configuration ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ If you want to tweak the configuration of the compiler, you can switch to the option variant with: ┌──── │ opam update │ opam switch create ocaml-variants.5.5.0~beta1+options └──── where `option_list' is a space separated list of `ocaml-option-*' packages. For instance, for a flambda and no-flat-float-array switch: ┌──── │ opam switch create 5.5.0~beta1+flambda+nffa ocaml-variants.5.5.0~beta1+options ocaml-option-flambda ocaml-option-no-flat-float-array └──── All available options can be listed with `opam search ocaml-option'. Changes compared to the last alpha ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ◊ Documentation update • [#14684]: Improve ocamlopt's manual page (Samuel Hym, review by Florian Angeletti) [#14684] ◊ Runtime fixes • [#14644], [#14647]: Fix a bug related to unhandled effects in bytecode. (Vincent Laviron, report by Thibaut Mattio, review by Nicolás Ojeda Bär, Stephen Dolan and Olivier Nicole) • [#14349], [#14718]: runtime, fix in the orphaning of ephemerons (Gabriel Scherer, review by Olivier Nicole and Damien Doligez, report by Jan Midtgaard) [#14644] [#14647] [#14349] [#14718] ◊ Type system fixes • [#14557], [#12150], [#14696]: ensure that the self type of class cannot escape through type constraints. (Leo White, review by Florian Angeletti) • [#14667]: enable application related warnings for module-dependent functions (Florian Angeletti, review by Gabriel Scherer) [#14557] [#12150] [#14696] [#14667] ◊ Error messages and warning fixes • [#14690]: Fix `Name_type_mismatch' error message when the expected type is an alias: print the expanded path on the right-hand side of the equality, not the alias twice. (Weixie Cui, review by Florian Angeletti) • [#14719], [#14721]: compute arity correctly for module-dependent function (Florian Angeletti, report by Jeremy Yallop, review by Stefan Muenzel) • [#14655], [#14691]: check for size overflow in caml_ba_reshape (Stephen Dolan, review by Xavier Leroy) [#14690] [#14719] [#14721] [#14655] [#14691] ocgtk 0.1: OCaml bindings for GTK 4 (preview release) ═════════════════════════════════════════════════════ Archive: Continuing this thread, Chris Armstrong announced ───────────────────────────────────────────────── /ocgtk preview1 release has landed in opam./ (preview0 was abandoned as considerable work was required to get it building on other Linux distributions and Mac). A special thanks to @jmid for helping me get it over the line. In addition to the features above, it includes: • Extended support for more GLib types, including integer primitives (guint8, int16, guint32, etc) and lists (GLib.SList and GLib.List) • Gobject interfaces The combination of the above enables more methods to be generated (that were previously excluded) when they include those types in their parameters and/or return types, opening up much more of the API surface of GTK (and related libraries). *Next steps*: my focus now is on internal cleanup and reorganisation to better structure the tests and split gir_gen (the GObject code generator) into a seperate dune project. This will reduce the dependency list considerably and enable targeting earlier OCaml versions, as well as reducing release headaches related to gir_gen (which is not required by packages just using ocgtk) 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] [the archive] [RSS feed of the archives] [caml-list] [Alan Schmitt]