From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Authentication-Results: plum.tunbury.org; dkim=pass (1024-bit key; unprotected) header.d=inria.fr header.i=@inria.fr header.a=rsa-sha256 header.s=dc header.b=Shdaq+Fh; dkim-atps=neutral Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=192.134.164.83; helo=mail2-relais-roc.national.inria.fr; envelope-from=caml-list-owner@inria.fr; receiver=tunbury.org Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by plum.tunbury.org (Postfix) with ESMTP id 9969040093 for ; Tue, 28 Jul 2026 12:44:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=inria.fr; s=dc; h=from:to:date:message-id:mime-version:subject:reply-to: sender:list-id:list-help:list-subscribe:list-unsubscribe: list-post:list-owner:list-archive; bh=UwJSF0WywJGbsP0RItyeOFHNeG+hdNOaoehOEU5WkpE=; b=Shdaq+FhzB4q2diOv0kj6NJDdNETsi8AQkdWJWZyKksINV+oDTOLI4Fu IN4MPZVCYA94K4n22ZonLJZxokKWw1xlPBS60rkT04ECR28y1fZjh3XVJ bzJWx2VO6GBcZmI28HyempPpUujQyoZVkOWXwFqM4r22SxVvOW4qrgsGJ 0=; X-CSE-ConnectionGUID: 7gkNtZgfRq6x2fPLPMJ2MQ== X-CSE-MsgGUID: aiNCTaY5SJq5PK+vTiwU8Q== Authentication-Results: mail2-relais-roc.national.inria.fr; dkim=none (message not signed) header.i=none; spf=SoftFail smtp.mailfrom=caml-list-owner@inria.fr; spf=None smtp.helo=postmaster@prod-sympa-app.inria.fr Received-SPF: SoftFail (mail2-relais-roc.national.inria.fr: domain of caml-list-owner@inria.fr is inclined to not designate 128.93.162.27 as permitted sender) identity=mailfrom; client-ip=128.93.162.27; receiver=mail2-relais-roc.national.inria.fr; envelope-from="caml-list-owner@inria.fr"; x-sender="caml-list-owner@inria.fr"; x-conformance=spf_only; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:128.93.142.0/24 ip4:192.134.164.0/24 ip4:128.93.162.160 ip4:128.93.162.3 ip4:128.93.162.88 ip4:89.107.174.7 mx ~all" Received-SPF: None (mail2-relais-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@prod-sympa-app.inria.fr) identity=helo; client-ip=128.93.162.27; receiver=mail2-relais-roc.national.inria.fr; envelope-from="caml-list-owner@inria.fr"; x-sender="postmaster@prod-sympa-app.inria.fr"; x-conformance=spf_only X-IronPort-AV: E=Sophos;i="6.25,190,1779141600"; d="asc'?scan'208,217";a="288206230" Received: from prod-sympa-app.inria.fr ([128.93.162.27]) by mail2-relais-roc.national.inria.fr with ESMTP; 28 Jul 2026 14:44:32 +0200 Received: by prod-sympa-app.inria.fr (Postfix, from userid 990) id 94C9F81C61; Tue, 28 Jul 2026 14:44:32 +0200 (CEST) Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by prod-sympa-app.inria.fr (Postfix) with ESMTP id 1DEAD80311 for ; Tue, 28 Jul 2026 14:44:23 +0200 (CEST) X-CSE-ConnectionGUID: tGUX8RVGT7iAR2Q5TlEVGg== X-CSE-MsgGUID: GmndNA91S+6cUBoUjvSAqA== IronPort-SDR: 6a68a424_T9M2ZgL5feOXZa51iwoh8zvx8MdqjUMy5AiE+n5NOEeIeHS ZbGRUGiGDIv9OLTVyWq6wd+I3NOFBrs5TxxA2jA== X-ThreatScanner-Verdict: Negative X-IPAS-Result: =?us-ascii?q?A0F1BTNqomhqhSIeaIFaFn+DAVspGwFuWgUzBwhJcYMrP?= =?us-ascii?q?INPhTSIcIEWkDeKfIFpgSsWIQIOBwEDAQgFLgEbBAECBAEBAQIBAgGCC4ItR?= =?us-ascii?q?gJPFY0AAh8GAQQ0EwECBAMCAwEBAQEBAQEBAQEBCwEBAQQBAQECAQECBAMBA?= =?us-ascii?q?QEBAhABAQEBQEmGFQczDYJFUVQdXgcJBjABAQEBAQEBAQEBAQEBAQEBAQEBA?= =?us-ascii?q?QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAgQIAQcSCgYHLjIOAQgEBhMBATAIG?= =?us-ascii?q?CMDFAEGAwIRATUDARMBEhQGAYIPWAGCIAICUAMFDAamCJtEen8zgQGCDAEBB?= =?us-ascii?q?oEIPgIBCwIFDy/aGIFgCQkUgSEYgViEGYJPDw0BBSVJagIBAhOEPQmBDneCM?= =?us-ascii?q?ycPgVVEgRU1YoESSgdvgVABbiIBAQEBAYEjBBQBAQhFCYMlgmqCERWBDIF4U?= =?us-ascii?q?EgFGSYsQRNhgxuBLIhGgkIsAVUTFwsHBV6BCAMqLy1uMh2BIz4XNFgbBwWBH?= =?us-ascii?q?YEsYYRYIxk5f4ExdUp3LWoSF4EagzwCghUDC209NxQZjFIQIQ2BOkkZFgyBS?= =?us-ascii?q?yUOCgEhDAcPIicJAgEXEwEKEQgGAQEgAg0nAgUeCgcFBwMCFxEIBAkKAQMEG?= =?us-ascii?q?AEiBQYLFA0ZA40NhUomAhwOj16hcoEKNAeEIIFgBgyJCYEmjjSHU4QEjRSHA?= =?us-ascii?q?5JRIphmI4leXUkJgW8fTJU0AioEBAuFRoF/I0liHgwHMxowQ4IzAQEyCUccD?= =?us-ascii?q?4k2hHYXgRQBAwWCQ4EBPYEmgXQ7gkXGZEI1AQEBATsHAgcBDASFawEBaYsfL?= =?us-ascii?q?QVrYQEB?= IronPort-PHdr: A9a23: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 h8U6RVQ6QkAkI5pY+2j55DHHsYk9g== IronPort-Data: A9a23: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 IronPort-HdrOrdr: A9a23:upEHvq/eDKbIPN0Ao4Zuk+DLI+orL9Y04lQ7vn2ZKCYlEPBw8v rEoB11726RtN98YhAdcLO7Scq9qA3nhPtICOAqVN/JMTUO3lHJEGgI1+TfKlPbdxEWjtQy6Z td X-Talos-CUID: 9a23:shOCO24Q1RMfoS7Bhtss6GEpKpAfTFLhk3b5GRWBVFptZYO6RgrF X-Talos-MUID: 9a23:UuqypAmJmIevPWhMYxPadnpNMcFkxY3/UXtOz547kc65NzJLEi602WE= X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="6.25,190,1779141600"; d="asc'?scan'208,217";a="288206135" X-IronPort-Outbreak-Status: No, level 1, Phish - Phish X-MGA-submission: =?us-ascii?q?MDH5vJ9rKpx19HaG1TOm8/X4c46CVGEOYjAvLf?= =?us-ascii?q?eipLXywkUVz8tek+leEUkkioAJM9JOinF9oKrSRfKcwuyUPwQh8QQa9C?= =?us-ascii?q?LX/VSJ0fAU/51hT+L3wBcFitii5T2EvcGcjaVrbsZ1alO4oNbcRcjcoV?= =?us-ascii?q?YY8FFf3ccLjahq/aDC324YfA=3D=3D?= Received: from mx1.polytechnique.org ([129.104.30.34]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Jul 2026 14:44:21 +0200 Received: from mac-03220211.irisa.fr (mac-03220211.irisa.fr [131.254.21.249]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ssl.polytechnique.org (Postfix) with ESMTPSA id 2B3A91A40E; Tue, 28 Jul 2026 14:44:21 +0200 (CEST) From: Alan Schmitt To: "lwn" , caml-list@inria.fr Date: Tue, 28 Jul 2026 14:44:18 +0200 Message-ID: MIME-Version: 1.0 Content-Type: multipart/signed; boundary="===-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" X-AV-Checked: ClamAV using ClamSMTP at svoboda.polytechnique.org (Tue Jul 28 14:44:21 2026 +0200 (CEST)) X-Spam-Flag: Unsure, tests=bogofilter, spamicity=0.499985, queueID=5D0291A421 X-Org-Mail: alan.schmitt.1995@polytechnique.org Subject: [Caml-list] Attn: Development Editor, Latest OCaml Weekly News Reply-To: Alan Schmitt X-Loop: caml-list@inria.fr X-Sequence: 19555 Errors-To: caml-list-owner@inria.fr Precedence: list Precedence: bulk Sender: caml-list-request@inria.fr X-no-archive: yes List-Id: List-Help: , List-Subscribe: , List-Unsubscribe: , List-Post: List-Owner: List-Archive: Archived-At: --===-=-= Content-Type: multipart/mixed; boundary="=-=-=" --=-=-= Content-Type: multipart/alternative; boundary="==-=-=" --==-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello Here is the latest OCaml Weekly News, for the week of July 21 to 28, 2026. Table of Contents =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80 Theo 0.1.0: a BDD library with theory support qiskit 2.0.1 Wax 0.1.0: a Rust-like syntax for WebAssembly Cascade: A Typed CSS Toolkit in OCaml Dune 3.24 ocaml-wire: a Binary wire format DSL with EverParse 3D output Eio 1.4 (effects-based concurrency library) ocaml-sbom 0.1.0 Union-find-lattice library Challenging Claude's creativity with IFS fractals and OCaml Simple_http.1.1 available Old CWN Theo 0.1.0: a BDD library with theory support =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90 Archive: J=C3=A9r=C3=B4me Vouillon announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 I'm pleased to announce the first release of [Theo], an OCaml library for /Binary Decision Diagrams (BDDs)/. BDDs give you a /canonical/ representation of boolean functions: two logically equivalent formulas always produce the exact same structure, so checking equivalence becomes a pointer comparison, O(1). Theo's key extension is /theory support/: atoms aren't just boolean variables but constraints like `ocaml >=3D 4.14' or `name =3D "foo"', and the engine understands their semantics. This makes it practical for real-world constraint problems. For example, a package manager can ask whether `(ocaml >=3D 4.14 AND dune >=3D 3.0) OR (ocaml >=3D 5.0)' is compatible with `ocaml < 5.0'. Theo reasons about the version constraints directly: it knows `ocaml >=3D 4.14' is redundant when `ocaml >=3D 5.0' holds, detects that the second disjunct contradicts `ocaml < 5.0', and can extract the simplest satisfying assignment (`ocaml >=3D 4.14, dune >=3D 3.0'). [Theo] Highlights of the 0.1.0 release: =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C= =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=80=A2 Core BDD engine with hash-consing (via weak tables) and a canon= ical negative-edge form =E2=80=A2 Boolean operations: AND, OR, NOT, IMPLIES, EQUIV, XOR, plus `exists~/~forall' quantifiers =E2=80=A2 Pluggable theory support over linear orders and equality (boole= ans, strings, integers, semantic versions), with a `Combine' functor to mix theories in the same BDD =E2=80=A2 `restrict' for partial evaluation under a set of external constraints, and constraint introspection via pattern matching =E2=80=A2 Minimal-witness extraction (shortest satisfying assignment) and zero-allocation entailment checks (implication, disjointness, exhaustiveness) =E2=80=A2 Irredundant sum-of-products (Minato=E2=80=93Morreale) computati= on =E2=80=A2 A property-based test suite Some implementation details that may be of interest: memoization caches are built on /ephemerons/, so cache entries are reclaimed automatically once the BDD nodes they depend on become unreachable, with no manual cache invalidation and no leaks. Theory-aware simplification happens /during/ BDD construction, using atom ordering to prune redundant bounds. The theory interface is a small functor-based API, and the same `Syntax' functor produces both BDD formulas and constraint lists. I've written a [companion blog post] that walks through the main ideas: hash-consing and ephemeron caches, theory-aware simplification, and the algorithmic techniques behind `restrict', minimal witnesses, and zero-allocation queries. =E2=80=A2 Source: =E2=80=A2 API docs: =E2=80=A2 Install: `opam install theo' Feedback and contributions welcome! [companion blog post] qiskit 2.0.1 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Davide Gessa announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 I'm glad to announce the release of qiskit 2.0.1 , an Ocaml wrapper for the Python quantum computing library "qiskit" form IBM. The latest release add support for qiskit > 2.0, which includes some breaking changes: =E2=80=A2 IBMProvider becomes IBMRuntime =E2=80=A2 Some gates addition and some gates removal Wax 0.1.0: a Rust-like syntax for WebAssembly =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90 Archive: J=C3=A9r=C3=B4me Vouillon announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 I'm happy to announce the first release of *Wax*, a toolchain that gives WebAssembly a familiar, expression-oriented syntax. It's written in OCaml and, as of 0.1.0, `wax' is available on the opam repository: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 opam install wax =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 *Why I'm building it.* The `wasm_of_ocaml' runtime is currently about 23k lines of hand-written WebAssembly text (WAT, the official human-readable text representation of WebAssembly). That is a lot of code to maintain in a format that, while readable, is quite verbose: it is built on S-expressions, and everything is explicit, from every variable access down to every type. I'm developing Wax at Tarides to address this, giving that runtime a more concise, type-checked syntax that still compiles to exactly the same bytecode. The WebAssembly text format spells everything out: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 (func $add (param $x i32) (param $y i32) (result i32) =E2=94=82 (i32.add (local.get $x) (local.get $y))) =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Wax reads like a programming language: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 fn add(x: i32, y: i32) -> i32 { =E2=94=82 x + y; =E2=94=82 } =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Both compile to identical bytecode. The payoff grows with the program; struct types, nullable references, casts, and loops stay readable where the equivalent WAT sprawls: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 type list =3D { value: i32, next: &?list }; =E2=94=82=20 =E2=94=82 #[export =3D "sum"] =E2=94=82 fn sum(l: &?list) -> i32 { =E2=94=82 let total: i32 =3D 0; =E2=94=82 while l is &list { =E2=94=82 total +=3D l!.value; =E2=94=82 l =3D l!.next; =E2=94=82 } =E2=94=82 total; =E2=94=82 } =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 A few highlights: =E2=80=A2 *Every direction.* All nine conversions between `wax', `wat', a= nd `wasm' work, including decompiling an arbitrary `.wasm' binary back into readable Wax. =E2=80=A2 *Full WebAssembly 3.0.* Garbage collection, exception handling,= tail calls, multiple and 64-bit memories, and SIMD, plus stack switching, threads, wide arithmetic, and branch hints. =E2=80=A2 *A real type checker.* Errors are caught before any output is produced and reported with source context. =E2=80=A2 *A toolchain, not just a compiler.* A formatter, a validator, configurable lints, conditional compilation, source maps, and a language server (LSP) with a VS Code extension and tree-sitter grammar. You can try it in your browser, no install required, on the [playground]: type Wax and see the WAT and diagnostics live. *This is an early, experimental release.* The syntax and the toolchain are still evolving, and I expect rough edges. That is exactly why I'm publishing it now: I'd be very interested in your feedback, whether on the syntax, the ergonomics, missing features, or anything that gets in your way. Bug reports and impressions are all very welcome. =E2=80=A2 Docs: =E2=80=A2 Source: [playground] Cascade: A Typed CSS Toolkit in OCaml =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Thomas Gazagnaire announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80 I'm happy to announce the first release of [cascade] available in opam (`opam install cascade') and in brew (`brew install samoht/tap/cascade'). Cascade is a library: =E2=80=A2 a typed AST to represent CSS documents; =E2=80=A2 a set of (cascade-order preserving) transformations over that AST. This includes: minification of (leaf) values (lots of fun with colour-space coordinate), optimisations (aka semantic-preserving node rewrites following the great [SatCSS paper]), semantic-preserving canonisation, and [more]; =E2=80=A2 a diff function to compare those (optionally canonised) ASTs; =E2=80=A2 an apply function to apply a CSS value to an HTML document as s= tyle attributes, preserving the cascade-order. But cascade is also a CLI tool! All of those operations are available as subcommands (with `cascade fmt', `cascade diff' and `cascade apply'). You can read more details here: You are very welcome to report issues or discuss about ideas on the [GH tracker]. [cascade] [SatCSS paper] [more] [GH tracker] Dune 3.24 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90 Archive: Continuing this thread, Ali Caglayan announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 The Dune team is pleased to announce [the release of dune 3.24.1]. See [the full changelog] for all new features and fixes, 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 tracker]. [the release of dune 3.24.1] [the full changelog] [our issue tracker] ocaml-wire: a Binary wire format DSL with EverParse 3D output =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90 Archive: Continuing this thread, Thomas Gazagnaire announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80 I am happy to announce the release 1.1.0 of ocaml-wire on opam! The release improves a few things: =E2=80=A2 the generated, formally-verified parsers can now be cross-compi= led (including to ocaml-freestanding to be included in a unikernel). The installed C headers are also now much smaller and only expose safe entry point. =E2=80=A2 ocaml-wire now use [] for uin= t32 fields. This helps to run the generated OCaml parsers/serialisers on safely on js_of_ocaml/wasm_of_ocaml (which is useful to encode TCP sequence numbers safely to run a full tcp/ip stack in wasm for instance). =E2=80=A2 parsing errors (in OCaml) are now much more precise and show the codecs, field names and stream location. =E2=80=A2 codecs are now safe to share across domains (each domain now ha= ve their own scratch buffers) The full changelog is available [here]. [here] Eio 1.4 (effects-based concurrency library) =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90 Archive: Thomas Leonard announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 [Eio 1.4] is now released and available from opam-repository. [Eio 1.4] About Eio =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C Eio provides an effects-based direct-style IO stack for OCaml 5. For example, you can use Eio to read and write files, make network connections, or perform CPU-intensive calculations, running multiple operations at the same time. It aims to be easy to use, secure, well documented, and fast. A generic cross-platform API is implemented by optimised backends for different platforms. Eio implements similar functionality to Lwt or Async, but using effects rather than monadic concurrency. Eio and Lwt libraries can be mixed freely using [lwt_eio], allowing programs to be converted to Eio incrementally. For a tutorial, see the [Eio README]. [lwt_eio] [Eio README] Highlights of the 1.4 release =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C= =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=80=A2 [Eio.Net] supports socket options (both the standard `Unix' one= s and many more, e.g. `TCP_KEEPINTVL'). =E2=80=A2 [Eio.Path] provides more file-system operations (`chmod', `chow= n', `read_dir_entries', `with_dir_entries'). These all use the modern `*at' system calls and `RESOLVE_BENEATH' to make it easy to restrict path operations to a subtree (see `Path.with_subtree'). =E2=80=A2 [Eio_unix.Pty] adds pseudoterminal support (for writing terminal emulators, SSH servers, etc). The `Eio_linux' backend (which uses [io_uring] rather than traditional POSIX system calls) now also supports `statx', `fallocate' and `fdatasync'. Important bug-fixes include a work-around for macOS `poll' failing for certain devices, `Path.load' working on 0-length-but-not-empty files (as found under `/proc' on Linux), better blocking behaviour with FIFOs (named pipes), and a fix for Windows using 100% CPU in some cases if an FD was used for both reading and writing. Note: `Eio.Net.getaddrinfo' previously returned `[]' if there was an error (following `Unix.getaddrinfo'), but now raises an exception with details of the actual error. For a full list of changes, see the [release notes]. [Eio.Net] [Eio.Path] [Eio_unix.Pty] [io_uring] [release notes] ocaml-sbom 0.1.0 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Nicolas Ojeda Bar announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80 We are happy to announce the first public release of `ocaml-sbom', a tool for generating Software Bills of Materials ([SBOMs]) for your OPAM-based projects. Software Bills of Materials are playing an increasingly important role in enterprise and regulated environments where compliance and security are priorities. Producing these reports by hand is impractical, so an automated solution was needed. `ocaml-sbom' provides exactly that. `ocaml-sbom' was developed by @mjambon as part of his collaboration with LexiFi. We are releasing it as open source because we believe it fills an unmet need and will be useful to the wider OCaml community. The tool invokes `opam' at runtime and requires OPAM 2.2.0 or later. To install it: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 $ opam install ocaml-sbom =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Generating an SBOM for your project is a two-step process. First, generate the SBOM in `ocaml-sbom''s internal format (this is the longer step). Run the command from the directory containing your `*.opam' files: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 $ ocaml-sbom -o myproject.sbom =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Then export the SBOM to one of the supported standard formats (this step is quick). Currently, CycloneDX 1.6, SPDX 2.3.1, and SPDX 3.0 are supported. By default, `ocaml-sbom' exports to CycloneDX: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 $ ocaml-sbom export myproject.sbom -o myproject.cdx =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 See the README or the `--help' output for more details. *Note:* This is an initial release and should be treated as such. We believe the tool is already useful and shows considerable promise, but it still needs real-world validation before it can be considered production-ready. Feedback is very welcome. Finally, I'd like to thank @mjambon for his work on this tool. Happy SBOM-ing! Cheers, Nicolas [SBOMs] Union-find-lattice library =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90 Archive: Dorian Lesbre announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 I'm happy to announce the release of [union-find-lattice v0.1.0] to opam ! This library provides a persistent union-find with fast operations to compute the join, meet and inclusion of two union-find instances (i.e. respectively the conjunction, disjunction and implication of the represented equivalence relations). These new algorithms are best explained in the [SAS 26 paper /A Lattice of Union-Finds/] I co-wrote with @Matthieu_Lemerre. We hope to use this data-structure to represent relations between variables in program analysis, but there may well be other uses cases as well. The core signature of the library is thus a functor of type: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 module UF(Node: NODE) =3D sig =E2=94=82 type t =E2=94=82=20 =E2=94=82 (** =3D=3D=3D=3D Standard union-find operations =3D=3D=3D=3D= =3D=3D=3D=3D=3D *) =E2=94=82 val make: int -> t =E2=94=82 val find: t -> Node.t =E2=94=82 val union: t -> Node.t -> Node.t -> t =E2=94=82 (** persistent union-find: union does not modify its argument= *) =E2=94=82=20 =E2=94=82 val check_related: t -> Node.t -> Node.t -> bool =E2=94=82 (** [check_related t a b] is true IFF [a] and [b] are in the = same class *) =E2=94=82=20 =E2=94=82 (** =3D=3D=3D=3D Lattice operations =3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D *) =E2=94=82 (** Lattice operands run in O(d*alpha(n)) where=20 =E2=94=82 - n is the number of nodes =E2=94=82 - d is the difference between both arguments (nodes with = different parents) =E2=94=82 - alpha is the inverse Ackermann function *) =E2=94=82=20 =E2=94=82=20 =E2=94=82 val join: t -> t -> t =E2=94=82 (** [check_related (join u v) a v <=3D> check_related u a b &= & check_related v a b] *) =E2=94=82=20 =E2=94=82 val meet: t -> t -> t =E2=94=82 (** [check_related (meet u v) a v] is true IFF=20 =E2=94=82 [a] and [b] are related in the transitive closure of [u] = and [v], i.e. =E2=94=82 there exists c1 .. cn, [check_related u a c1 && check_rel= ated v c1 c2 && .. && check_related u cn b] *) =E2=94=82=20 =E2=94=82 val incl: t -> t -> bool =E2=94=82 (** [incl uf_a uf_b] is lattice inclusion, [uf_a <=3D uf_b], = i.e. =E2=94=82 forall [x] [y], if [check_related uf_b x y] then [check_r= elated uf_a x y] *) =E2=94=82 end =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 We provide multiple implementations of this signature: =E2=80=A2 Internally, there three underlying data structure choices: *sta= ndard arrays* (with explicit copy), *persistent arrays* (same speed as array but pay a cost for all version switches) or *Patricia trees* (using our [patricia-tree library], truly immutable but add a log(nb_unions) cost to all operations). =E2=80=A2 We include variants for *labeled union-find* (extension which annotates the parent edges with a group of labels, it can represent more complex relations like equality up-to a constant) see our [PLDI 25 paper, /Relational Abstractions based on Labeled Union-Find/] and for *valued union-find*, where each class has a unique associated value (values also have a lattice structure). [union-find-lattice v0.1.0] [SAS 26 paper /A Lattice of Union-Finds/] [patricia-tree library] [PLDI 25 paper, /Relational Abstractions based on Labeled Union-Find/] Challenging Claude's creativity with IFS fractals and OCaml =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90 Archive: C=C3=A9dric announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Hello, Back in 2010, during a functional programming course, I wrote a small OCaml program that draws fractals with iterated function systems (IFS), using the graphics library and the chaos game. It is one of my oldest repositories still alive, and it had barely changed since: Each fractal is just a record: a list of affine transforms with cumulative weights, plus a viewport. The chaos game does the rest. The Barnsley fern is twenty-four coefficients. Last weekend I dusted it off, and as an experiment I asked Claude Fable 5 to invent new IFS fractals rather than fix or refactor anything. I wrote up the full story on my blog, but the parts that might interest people here: =E2=80=A2 The repo went from eleven predefined fractals to sixteen. The n= icest newcomer in my opinion is lace, Queen Anne's lace (wild carrot): an umbel of umbels, where five transforms place shrunken rotated copies of the whole plant on the rim of a dome and a sixth squashes everything into the stem. Thirty-six numbers total: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 let lace =3D =E2=94=82 { po =3D {x=3D -0.90 ; y=3D -0.55}; =E2=94=82 sz =3D {x=3D 1.80 ; y=3D 2.00}; =E2=94=82 lt =3D [{pb=3D 0.18; kf=3D [| 0.2649; 0.1408; -0.7048; -0.140= 8; 0.2649; 0.38|]}; =E2=94=82 {pb=3D 0.36; kf=3D [| 0.3493; 0.0871; -0.4302; -0.0871; 0.349= 3; 0.5013|]}; =E2=94=82 {pb=3D 0.54; kf=3D [| 0.38; 0.00; 0.00; 0.00; 0.38; 0.55|]}; =E2=94=82 {pb=3D 0.72; kf=3D [| 0.3493; -0.0871; 0.4302; 0.0871; 0.3493= ; 0.5013|]}; =E2=94=82 {pb=3D 0.90; kf=3D [| 0.2649; -0.1408; 0.7048; 0.1408; 0.2649= ; 0.38|]}; =E2=94=82 {pb=3D 1.00; kf=3D [| 0.02; 0.00; 0.00; 0.00; 0.55; 0.00|]}]}= ;; =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=80=A2 A sunflower built on phyllotaxis with only two transforms: one rotates by the golden angle (137.508=C2=B0) while contracting toward the center, the other plants a bud at the rim. Because the golden angle is the "most irrational" angle, the buds fill the disk evenly, just like real seed heads. =E2=80=A2 A fun negative result: I asked for the vegv=C3=ADsir, the Icela= ndic stave. Strictly speaking an IFS cannot draw it, since the attractor is a single self-similar set while the real symbol has a different rune on each of its eight arms. The workaround was a non-contracting map, a pure 45=C2=B0 rotation at scale 1.0 that draws nothing itself and only distributes points across the eight arms, so the other transforms only need to describe one arm. I had never thought of using a measure-preserving map as a "symmetry map" like that. =E2=80=A2 The takeaway I keep coming back to: plants make good IFS subjec= ts because they grow by iterating simple local rules, so their shape literally is an attractor. Designed symbols resist because nobody grew them. The write-up with all the images is here: If you want to play with it: opam install graphics ocamlfind, then in the toplevel `#use "ifs_fractals.ml";; and draw lace 300000;;'. I am curious whether others have used non-contracting symmetry maps in IFS before, or have favorite attractors worth adding. And if anyone remembers writing this kind of toy in an OCaml course, I would love to hear about it. Pull-requests are of course welcome! Simple_http.1.1 available =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Christophe Raffalli announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80 Dear Camlers, *Announcing Simple_httpd 1.1* I'm pleased to announce the release of *Simple_httpd 1.1*, a lightweight but feature-rich HTTP/HTTPS server library for *OCaml 5*, designed with a strong emphasis on *performance*, *simplicity*, and *production use*. It started as a fork of [tiny_httpd] to experiment with OCaml 5 domains and effects, Simple_httpd has now matured into a robust server used to host real websites. Documentation : (served by simple_httpd, and containing nice benchmarks) Github : . [tiny_httpd] Highlights =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C =E2=80=A2 *Very fast*: built around Linux *epoll*, *eventfd*, OCaml 5 *domains* and *effects*, with careful attention to latency and throughput. Benchmarks show excellent performance, competitive with or exceeding traditional web servers for many workloads. =E2=80=A2 *Production ready*: the server has been running real websites reliably for months, validating both its performance and stability in everyday use. =E2=80=A2 *Compiled server-side templates*: `.chaml' files provide an OCa= ml equivalent of PHP, except that templates are *compiled* rather than interpreted, combining flexibility with native performance. It is much faster than php. =E2=80=A2 *Flexible routing*: requests can be dispatched not only by path= and HTTP method, but also by host name, address and port, making virtual hosting straightforward. =E2=80=A2 *Static and embedded resources*: serve files directly from the filesystem, or package them into the executable using `vfs_pack'. Compression is supported in both cases and small file may even be cached in memory in the second case. =E2=80=A2 *Built-in monitoring*: integrated status pages expose CPU usage, memory consumption, active connections, file descriptors and logs, making deployment and debugging much easier. We also provide server sent event and websocket, with a full featured terminal as an application. =E2=80=A2 *Modern HTTP 1.1 features*: HTTPS, cookies, authentication, log= ging with levels, and optional database integration through Caqti are available out of the box. More are planned : anti attack! Simple_httpd remains true to its original philosophy: provide a web server that is *easy to use*, *easy to extend*, yet *fast enough for demanding production applications*. Feedback, bug reports and contributions are very welcome! Old CWN =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 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] --==-=-= Content-Type: text/html; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable OCaml Weekly News

OCaml Weekly News

Previous Week<= /a> Up Next Week

Hello

Here is the latest OCaml Weekly News, for the week of July 21 to 28, 2026.

Theo 0.1.0: a BDD library with theory support

J=C3=A9r=C3=B4me Vouillon announced

I'm pleased to announce the first release of Theo, an OCaml library for Binary Decision Diagrams (= BDDs).

BDDs give you a canonical representation of boolean functions: two l= ogically equivalent formulas always produce the exact same structure, so ch= ecking equivalence becomes a pointer comparison, O(1). Theo's key extension= is theory support: atoms aren't just boolean variables but constrai= nts like ocaml >=3D 4.14 or name =3D "foo", an= d the engine understands their semantics. This makes it practical for real-= world constraint problems.

For example, a package manager can ask whether (ocaml >=3D 4.14 AN= D dune >=3D 3.0) OR (ocaml >=3D 5.0) is compatible with = ocaml < 5.0. Theo reasons about the version constraints directly:= it knows ocaml >=3D 4.14 is redundant when ocaml >= ;=3D 5.0 holds, detects that the second disjunct contradicts o= caml < 5.0, and can extract the simplest satisfying assignment (<= code>ocaml >=3D 4.14, dune >=3D 3.0).

Highlights of the 0.1.0 release:

  • Core BDD engine with hash-consing (via weak tables) and a canonical neg= ative-edge form
  • Boolean operations: AND, OR, NOT, IMPLIES, EQUIV, XOR, plus exist= s~/~forall quantifiers
  • Pluggable theory support over linear orders and equality (booleans, str= ings, integers, semantic versions), with a Combine functor to = mix theories in the same BDD
  • restrict for partial evaluation under a set of external co= nstraints, and constraint introspection via pattern matching
  • Minimal-witness extraction (shortest satisfying assignment) and zero-al= location entailment checks (implication, disjointness, exhaustiveness)
  • Irredundant sum-of-products (Minato=E2=80=93Morreale) computation
  • A property-based test suite

Some implementation details that may be of interest: memoization caches are= built on ephemerons, so cache entries are reclaimed automatically o= nce the BDD nodes they depend on become unreachable, with no manual cache i= nvalidation and no leaks. Theory-aware simplification happens during= BDD construction, using atom ordering to prune redundant bounds. The theor= y interface is a small functor-based API, and the same Syntax = functor produces both BDD formulas and constraint lists.

I've written a comp= anion blog post that walks through the main ideas: hash-consing and eph= emeron caches, theory-aware simplification, and the algorithmic techniques = behind restrict, minimal witnesses, and zero-allocation querie= s.

Feedback and contributions welcome!

qiskit 2.0.1

Davide Gessa announced

I'm glad to announce the release of qiskit 2.0.1 , an Ocaml wrapper for the= Python quantum computing library "qiskit" form IBM. The latest release add= support for qiskit > 2.0, which includes some breaking changes:

  • IBMProvider becomes IBMRuntime
  • Some gates addition and some gates removal

https://op= am.ocaml.org/packages/qiskit/qiskit.2.0.1/

https://github.com/dakk/ca= ml_qiskit/

Wax 0.1.0: a Rust-like syntax for WebAssembly

J=C3=A9r=C3=B4me Vouillon announced

I'm happy to announce the first release of Wax, a toolchain that giv= es WebAssembly a familiar, expression-oriented syntax. It's written in OCam= l and, as of 0.1.0, wax is available on the opam repository:

opam install wax

Why I'm building it. The wasm_of_ocaml runtime is curre= ntly about 23k lines of hand-written WebAssembly text (WAT, the official hu= man-readable text representation of WebAssembly). That is a lot of code to = maintain in a format that, while readable, is quite verbose: it is built on= S-expressions, and everything is explicit, from every variable access down= to every type. I'm developing Wax at Tarides to address this, giving that = runtime a more concise, type-checked syntax that still compiles to exactly = the same bytecode.

The WebAssembly text format spells everything out:

(func $add (param $x i32) (param $y i32) (=
result i32)
  (i32.add (local.get $x) (local.get $y)))

Wax reads like a programming language:

fn add(x: i32, y: i32) -> i32 {
    x + y;
}

Both compile to identical bytecode. The payoff grows with the program; stru= ct types, nullable references, casts, and loops stay readable where the equ= ivalent WAT sprawls:

type list =3D { value: i32, next: &?l=
ist };

#[export =3D "sum"]
fn sum(l: &?list) -> i32 {
    let total: i32 =3D 0;
    while l is &list {
        total +=3D l!.value;
        l =3D l!.next;
    }
    total;
}

A few highlights:

  • Every direction. All nine conversions between wax, = wat, and wasm work, including decompiling an arbi= trary .wasm binary back into readable Wax.
  • Full WebAssembly 3.0. Garbage collection, exception handling, ta= il calls, multiple and 64-bit memories, and SIMD, plus stack switching, thr= eads, wide arithmetic, and branch hints.
  • A real type checker. Errors are caught before any output is prod= uced and reported with source context.
  • A toolchain, not just a compiler. A formatter, a validator, conf= igurable lints, conditional compilation, source maps, and a language server= (LSP) with a VS Code extension and tree-sitter grammar.

You can try it in your browser, no install required, on the playground: type Wax and see the W= AT and diagnostics live.

This is an early, experimental release. The syntax and the toolchain= are still evolving, and I expect rough edges. That is exactly why I'm publ= ishing it now: I'd be very interested in your feedback, whether on the synt= ax, the ergonomics, missing features, or anything that gets in your way. Bu= g reports and impressions are all very welcome.

Cascade: A Typed CSS Toolkit in OCaml

Thomas Gazagnaire announced

I'm happy to announce the first release of cascade available in opam (opam install cascade) and in brew (brew install samoht/tap/cascade).

Cascade is a library:

  • a typed AST to represent CSS documents;
  • a set of (cascade-order preserving) transformations over that AST. This= includes: minification of (leaf) values (lots of fun with colour-space coo= rdinate), optimisations (aka semantic-preserving node rewrites following th= e great SatCSS paper), sema= ntic-preserving canonisation, and more;
  • a diff function to compare those (optionally canonised) ASTs;
  • an apply function to apply a CSS value to an HTML document as style att= ributes, preserving the cascade-order.

But cascade is also a CLI tool! All of those operations are available as su= bcommands (with cascade fmt, cascade diff and cascade apply).

You can read more details here: https://gazagnaire.org/blog/2026-07-22-cascade-= minify.html

You are very welcome to report issues or discuss about ideas on the GH tracker.

Dune 3.24

Continuing this thread, Ali Caglayan announced

The Dune team is pleased to announce the release of dune 3.24.1.

See the full = changelog for all new features and fixes, and for attribution to the co= ntributors who made it all possible. Thank you, contributors!

If you encounter a problem with this release, please report it in our issue tracker.

ocaml-wire: a Binary wire format DSL with EverParse 3D output<= /h2>

Continuing this thread, Thomas Gazagnaire announced

I am happy to announce the release 1.1.0 of ocaml-wire on opam!

The release improves a few things:

  • the generated, formally-verified parsers can now be cross-compiled (inc= luding to ocaml-freestanding to be included in a unikernel). The installed = C headers are also now much smaller and only expose safe entry point.
  • ocaml-wire now use [https:= //github.com/mirage/optint] for uint32 fields. This helps to run the ge= nerated OCaml parsers/serialisers on safely on js_of_ocaml/wasm_of_ocaml (w= hich is useful to encode TCP sequence numbers safely to run a full tcp/ip s= tack in wasm for instance).
  • parsing errors (in OCaml) are now much more precise and show the codecs= , field names and stream location.
  • codecs are now safe to share across domains (each domain now have their= own scratch buffers)

The full changelog is available here.

Eio 1.4 (effects-based concurrency library)

Thomas Leonard announced

Eio 1.= 4 is now released and available from opam-repository.

About Eio

Eio provides an effects-based direct-style IO stack for OCaml 5. For exampl= e, you can use Eio to read and write files, make network connections, or pe= rform CPU-intensive calculations, running multiple operations at the same t= ime. It aims to be easy to use, secure, well documented, and fast. A generi= c cross-platform API is implemented by optimised backends for different pla= tforms.

Eio implements similar functionality to Lwt or Async, but using effects rat= her than monadic concurrency. Eio and Lwt libraries can be mixed freely usi= ng lwt_eio, allo= wing programs to be converted to Eio incrementally.

For a tutorial, see the Eio README.

Highlights of the 1.4 release

  • Eio.Net supports socket options (both the standard Unix = ones and many more, e.g. TCP_KEEPINTVL).
  • Eio.Path provides more file-system operations (chmod, <= code>chown, read_dir_entries, with_dir_entries). These all use the modern *at system calls and RES= OLVE_BENEATH to make it easy to restrict path operations to a subtre= e (see Path.with_subtree).
  • Eio_unix.Pty adds pseudoterminal support (for writing terminal e= mulators, SSH servers, etc).

The Eio_linux backend (which uses io_uring rather than traditional POSIX system calls) = now also supports statx, fallocate and fdat= async.

Important bug-fixes include a work-around for macOS poll faili= ng for certain devices, Path.load working on 0-length-but-not-= empty files (as found under /proc on Linux), better blocking b= ehaviour with FIFOs (named pipes), and a fix for Windows using 100% CPU in = some cases if an FD was used for both reading and writing.

Note: Eio.Net.getaddrinfo previously returned [] = if there was an error (following Unix.getaddrinfo), but now ra= ises an exception with details of the actual error.

For a full list of changes, see the release notes.

ocaml-sbom 0.1.0

Nicolas Ojeda Bar announced

We are happy to announce the first public release of ocaml-sbom, a tool for generating Software Bills of Materials (SBOMs) for your OPAM-based p= rojects.

Software Bills of Materials are playing an increasingly important role in e= nterprise and regulated environments where compliance and security are prio= rities. Producing these reports by hand is impractical, so an automated sol= ution was needed. ocaml-sbom provides exactly that.

ocaml-sbom was developed by @mjambon as part of his collaborat= ion with LexiFi. We are releasing it as open source because we believe it f= ills an unmet need and will be useful to the wider OCaml community.

https://github.co= m/LexiFi/ocaml-sbom/releases

The tool invokes opam at runtime and requires OPAM 2.2.0 or la= ter. To install it:

$ opam install ocaml-sbom

Generating an SBOM for your project is a two-step process. First, generate = the SBOM in ocaml-sbom's internal format (this is the longer s= tep). Run the command from the directory containing your *.opam files:

$ ocaml-sbom -o myproject.sbom

Then export the SBOM to one of the supported standard formats (this step is= quick). Currently, CycloneDX 1.6, SPDX 2.3.1, and SPDX 3.0 are supported. = By default, ocaml-sbom exports to CycloneDX:

$ ocaml-sbom export myproject.sbom -o myproject.cdx

See the README or the --help output for more details.

Note: This is an initial release and should be treated as such. We b= elieve the tool is already useful and shows considerable promise, but it st= ill needs real-world validation before it can be considered production-read= y. Feedback is very welcome.

Finally, I'd like to thank @mjambon for his work on this tool.

Happy SBOM-ing!

Cheers,=20=20 Nicolas

Union-find-lattice library

Dorian Lesbre announced

I'm happy to announce the release of union-find-lattice v0.1.0 to opam ! This library provid= es a persistent union-find with fast operations to compute the join, meet a= nd inclusion of two union-find instances (i.e. respectively the conjunction= , disjunction and implication of the represented equivalence relations).

These new algorithms are best explained in the SAS 26 pap= er A Lattice of Union-Finds I co-wrote with @Matthieu_Lemerre. W= e hope to use this data-structure to represent relations between variables = in program analysis, but there may well be other uses cases as well.

The core signature of the library is thus a functor of type:

module UF(Node: NODE=
) =3D sig
  type t

  (** =3D=3D=3D=3D Stan=
dard union-find operations =3D=3D=3D=3D=3D=3D=3D=3D=3D *)
  val make: int -> t
  val find: t -> Node.t
  val union: t -> Node.t -> Node.t -> t
  (** persistent union-=
find: union does not modify its argument *)

  val check_related: t -> Node.t -> Node.t -> bool
  (** [check_related t a b] is true IFF [a] =
and [b] are in the same class *)

  (** =3D=3D=3D=3D Latt=
ice operations =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D *)
  (** Lattice operands =
run in O(d*alpha(n)) where 
      - n is the number=
 of nodes
      - d is the differ=
ence between both arguments (nodes with different parents)
      - alpha is the in=
verse Ackermann function *)


  val join: t -> t -> t
  (** [check_related (join u v) =
a v <=3D> check_related u a b &&a=
mp; check_related v a b] *)

  val meet: t -> t -> t
  (** [check_related (meet u v) =
a v] is true IFF 
      [a] and ] are related in the transit=
ive closure of [=
u] and [v], i.e.
      there exists c1 .=
. cn, [ch=
eck_related u a c1 && check_=
related v c1 c2 && .. && check_related u cn b] *)

  val incl: t -> t -> bool
  (** [incl uf_a uf_b] is lattice inclusion, [uf_a <=3D uf_b], i.e.
      forall [x] [y]<=
span style=3D"color: #4f677f; font-style: italic;">, if [check_related uf_b x y] then [check_related uf_a x y] *)
end

We provide multiple implementations of this signature:

  • Internally, there three underlying data structure choices: standard = arrays (with explicit copy), persistent arrays (same speed as ar= ray but pay a cost for all version switches) or Patricia trees (usin= g our patricia-tree librar= y, truly immutable but add a log(nb_unions) cost to all operations).
  • We include variants for labeled union-find (extension which anno= tates the parent edges with a group of labels, it can represent more comple= x relations like equality up-to a constant) see our PLDI 25 paper, Relational Abstractions based on Labeled Unio= n-Find and for valued union-find, where each class has a uni= que associated value (values also have a lattice structure).

Challenging Claude's creativity with IFS fractals and OCaml

C=C3=A9dric announced

Hello,

Back in 2010, during a functional programming course, I wrote a small OCaml= program that draws fractals with iterated function systems (IFS), using th= e graphics library and the chaos game. It is one of my oldest repositories = still alive, and it had barely changed since:

htt= ps://github.com/cedricbonhomme/iterated-function-systems

Each fractal is just a record: a list of affine transforms with cumulative = weights, plus a viewport. The chaos game does the rest. The Barnsley fern i= s twenty-four coefficients.

Last weekend I dusted it off, and as an experiment I asked Claude Fable 5 t= o invent new IFS fractals rather than fix or refactor anything. I wrote up = the full story on my blog, but the parts that might interest people here:

  • The repo went from eleven predefined fractals to sixteen. The nicest newcom= er in my opinion is lace, Queen Anne's lace (wild carrot): an umbel of umbe= ls, where five transforms place shrunken rotated copies of the whole plant = on the rim of a dome and a sixth squashes everything into the stem. Thirty-= six numbers total:

    let lace =3D
    { po =3D {x=3D -0.90 ; y=3D -0.55};
    sz =3D {x=3D 1.80 ; y=3D 2.00};
    lt =3D [{pb=3D 0.18; kf=3D [| 0.2649; 0.1408; -0.7048; -0.1408; 0.2649; 0.3=
    8|]};
    {pb=3D 0.36; kf=3D [| 0.3493; 0.0871; -0.4302; -0.0871; 0.3493; 0.5013|]};
    {pb=3D 0.54; kf=3D [| 0.38; 0.00; 0.00; 0.00; 0.38; 0.55|]};
    {pb=3D 0.72; kf=3D [| 0.3493; -0.0871; 0.4302; 0.0871; 0.3493; 0.5013|]};
    {pb=3D 0.90; kf=3D [| 0.2649; -0.1408; 0.7048; 0.1408; 0.2649; 0.38|]};
    {pb=3D 1.00; kf=3D [| 0.02; 0.00; 0.00; 0.00; 0.55; 0.00|]}]};;
    
  • A sunflower built on phyllotaxis with only two transforms: one rotates = by the golden angle (137.508=C2=B0) while contracting toward the center, th= e other plants a bud at the rim. Because the golden angle is the "most irra= tional" angle, the buds fill the disk evenly, just like real seed heads.
  • A fun negative result: I asked for the vegv=C3=ADsir, the Icelandic sta= ve. Strictly speaking an IFS cannot draw it, since the attractor is a singl= e self-similar set while the real symbol has a different rune on each of it= s eight arms. The workaround was a non-contracting map, a pure 45=C2=B0 rot= ation at scale 1.0 that draws nothing itself and only distributes points ac= ross the eight arms, so the other transforms only need to describe one arm.= I had never thought of using a measure-preserving map as a "symmetry map" = like that.
  • The takeaway I keep coming back to: plants make good IFS subjects becau= se they grow by iterating simple local rules, so their shape literally is a= n attractor. Designed symbols resist because nobody grew them.

The write-up with all the images is here:

https://www.cedricbonhomme.org/2026/07/27/challenging-clau= de-with-ifs-fractals/

If you want to play with it: opam install graphics ocamlfind, then in the t= oplevel #use "ifs_fractals.ml";; and draw lace 300000;;.

I am curious whether others have used non-contracting symmetry maps in IFS = before, or have favorite attractors worth adding. And if anyone remembers w= riting this kind of toy in an OCaml course, I would love to hear about it. = Pull-requests are of course welcome!

3D"82d90e9430e26168=

Simple_http.1.1 available

Christophe Raffalli announced

Dear Camlers,

Announcing Simple_httpd 1.1

I'm pleased to announce the release of Simple_httpd 1.1, a lightweig= ht but feature-rich HTTP/HTTPS server library for OCaml 5, designed = with a strong emphasis on performance, simplicity, and pro= duction use.

It started as a fork of ti= ny_httpd to experiment with OCaml 5 domains and effects, Simple_httpd h= as now matured into a robust server used to host real websites.

Documentation : https://raffalli.eu/simple_httpd/simple_httpd/index.html (ser= ved by simple_httpd, and containing nice benchmarks)

Github : https://github.c= om/craff/simple_httpd.

Highlights

  • Very fast: built around Linux epoll, eventfd, OCam= l 5 domains and effects, with careful attention to latency an= d throughput. Benchmarks show excellent performance, competitive with or ex= ceeding traditional web servers for many workloads.
  • Production ready: the server has been running real websites reli= ably for months, validating both its performance and stability in everyday = use.
  • Compiled server-side templates: .chaml files provid= e an OCaml equivalent of PHP, except that templates are compiled rat= her than interpreted, combining flexibility with native performance. It is = much faster than php.
  • Flexible routing: requests can be dispatched not only by path an= d HTTP method, but also by host name, address and port, making virtual host= ing straightforward.
  • Static and embedded resources: serve files directly from the fil= esystem, or package them into the executable using vfs_pack. C= ompression is supported in both cases and small file may even be cached in = memory in the second case.
  • Built-in monitoring: integrated status pages expose CPU usage, m= emory consumption, active connections, file descriptors and logs, making de= ployment and debugging much easier. We also provide server sent event and w= ebsocket, with a full featured terminal as an application.
  • Modern HTTP 1.1 features: HTTPS, cookies, authentication, loggin= g with levels, and optional database integration through Caqti are availabl= e out of the box. More are planned : anti attack!

Simple_httpd remains true to its original philosophy: provide a web server = that is easy to use, easy to extend, yet fast enough for d= emanding production applications.

Feedback, bug reports and contributions are very welcome!

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 loo= k at the archive or the <= a href=3D"https://alan.petitepomme.net/cwn/cwn.rss">RSS feed of the archive= s.

If you also wish to receive it every week by mail, you may subscribe to the= caml-list.

--==-=-=-- --=-=-=-- --===-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQFvBAEBCABZFiEE6lXof/BsSVW56ZmGBA0KO07S5ccFAmpopCIbFIAAAAAABAAO bWFudTIsMi41KzEuMTIsMCwzHxxhbGFuLnNjaG1pdHRAcG9seXRlY2huaXF1ZS5v cmcACgkQBA0KO07S5cdUugf8CRz57nzaCByzLQ7kKx2d2XrDZCCQEIErHAPu79Zv ysX3NjW+tmEubXDmBGbaUvQkDHThvhJCU/7J38xUd/v6UdhaissnPMHZLFItOK88 eQGQJTCkBdrX7YcDkbp76OuIoefX8FHXmQecqDm2LaGTX+98ogVbl3cGbmbr+ffr jNYWN5Ut6/5Us49bbhvgT4hYWN7tInVlxH2whtp6PcKFKwND/T926bL8gapRKznS BF9qCU2vxAxrxVOkOcKbmrRWQdFN5+aOKhDdQ7amocnHRMuO1MRi1k4LjTNeN1iC jH1rXZ1XPrpRIbQCf9MdJIpXqmC37JRReinOnMKKPj7rOQ== =YZ8D -----END PGP SIGNATURE----- --===-=-=--