Attn: Development Editor, Latest OCaml Weekly News

Alan Schmitt <[email protected]> Tue, 28 Jul 2026 14:44:18 +0200
Newsgroups gmane.comp.lang.caml.inria
Message-ID <[email protected]>
--===-=-=
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:
  <https://discuss.ocaml.org/t/ann-theo-0-1-0-a-bdd-library-with-theory-sup=
port/18376/1>


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] <https://github.com/vouillon/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: <https://github.com/vouillon/theo>
  =E2=80=A2 API docs: <https://vouillon.github.io/theo/theo/Theo/>
  =E2=80=A2 Install: `opam install theo'

  Feedback and contributions welcome!


[companion blog post] <https://vouillon.github.io/blog/posts/theo/>


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: <https://discuss.ocaml.org/t/ann-qiskit-2-0-1/18378/1>


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

  <https://opam.ocaml.org/packages/qiskit/qiskit.2.0.1/>

  <https://github.com/dakk/caml_qiskit/>


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:
  <https://discuss.ocaml.org/t/wax-0-1-0-a-rust-like-syntax-for-webassembly=
/18379/1>


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: <https://ocsigen.org/wax/>
  =E2=80=A2 Source: <https://github.com/ocsigen/wax>


[playground] <https://ocsigen.org/wax/playground.html>


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:
  <https://discuss.ocaml.org/t/cascade-a-typed-css-toolkit-in-ocaml/18383/1>


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


[cascade] <https://github.com/samoht/cascade>

[SatCSS paper] <https://doi.org/10.1145/3310337>

[more] <https://github.com/samoht/cascade/blob/main/lib/css.mli>

[GH tracker] <https://github.com/samoht/cascade>


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: <https://discuss.ocaml.org/t/ann-dune-3-24/18316/2>


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]
<https://github.com/ocaml/dune/releases/tag/3.24.1>

[the full changelog] <https://github.com/ocaml/dune/releases/tag/3.24.1>

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


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:
  <https://discuss.ocaml.org/t/ann-ocaml-wire-a-binary-wire-format-dsl-with=
-everparse-3d-output/18009/5>


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 [<https://github.com/mirage/optint>] 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] <https://github.com/parsimoni-labs/ocaml-wire/releases/tag/1.1.0>


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:
  <https://discuss.ocaml.org/t/ann-eio-1-4-effects-based-concurrency-librar=
y/18391/1>


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] <https://github.com/ocaml-multicore/eio/releases/tag/v1.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] <https://github.com/ocaml-multicore/lwt_eio>

[Eio README]
<https://github.com/ocaml-multicore/eio#eio--effects-based-parallel-io-for-=
ocaml>


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] <https://ocaml-multicore.github.io/eio/eio/Eio/Net/index.html>

[Eio.Path]
<https://ocaml-multicore.github.io/eio/eio/Eio/Path/index.html>

[Eio_unix.Pty]
<https://ocaml-multicore.github.io/eio/eio/Eio_unix/Pty/index.html>

[io_uring] <https://github.com/axboe/liburing>

[release notes]
<https://github.com/ocaml-multicore/eio/releases/tag/v1.4>


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: <https://discuss.ocaml.org/t/ann-ocaml-sbom-0-1-0/18393/1>


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.

  <https://github.com/LexiFi/ocaml-sbom/releases>

  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] <https://en.wikipedia.org/wiki/Software_supply_chain>


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:
  <https://discuss.ocaml.org/t/ann-union-find-lattice-library/18394/1>


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] <https://codex.top/api/union-find-lattice/>

[SAS 26 paper /A Lattice of Union-Finds/]
<https://www.normalesup.org/~dlesbre/research/2026-sas-union-find-lattice.h=
tml.en>

[patricia-tree library] <https://codex.top/api/patricia-tree/>

[PLDI 25 paper, /Relational Abstractions based on Labeled Union-Find/]
<https://www.normalesup.org/~dlesbre/research/2025-pldi-relational-abstract=
ions-labeled-uf.html.en>


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:
  <https://discuss.ocaml.org/t/challenging-claudes-creativity-with-ifs-frac=
tals-and-ocaml/18398/1>


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:

  <https://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 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:

  <https://www.cedricbonhomme.org/2026/07/27/challenging-claude-with-ifs-fr=
actals/>

  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!

  <https://us1.discourse-cdn.com/flex020/uploads/ocaml/original/2X/8/82d90e=
9430e26168eb5407d9df00211ad6bbe08a.png>


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:
  <https://discuss.ocaml.org/t/simple-http-1-1-available/18399/1>


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 :
  <https://raffalli.eu/simple_httpd/simple_httpd/index.html> (served by
  simple_httpd, and containing nice benchmarks)

  Github : <https://github.com/craff/simple_httpd>.


[tiny_httpd] <https://github.com/c-cube/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] <mailto:[email protected]>

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

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

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

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


--==-=-=
Content-Type: text/html; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

<?xml version=3D"1.0" encoding=3D"utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns=3D"http://www.w3.org/1999/xhtml" lang=3D"en" xml:lang=3D"en">
<head>
<!-- 2026-07-28 Tue 14:43 -->
<meta http-equiv=3D"Content-Type" content=3D"text/html;charset=3Dutf-8" />
<meta name=3D"viewport" content=3D"width=3Ddevice-width, initial-scale=3D1"=
 />
<title>OCaml Weekly News</title>
<meta name=3D"generator" content=3D"Org Mode" />
<style type=3D"text/css">
  #content { max-width: 60em; margin: auto; }
  .title  { text-align: center;
             margin-bottom: .2em; }
  .subtitle { text-align: center;
              font-size: medium;
              font-weight: bold;
              margin-top:0; }
  .todo   { font-family: monospace; color: red; }
  .done   { font-family: monospace; color: green; }
  .priority { font-family: monospace; color: orange; }
  .tag    { background-color: #eee; font-family: monospace;
            padding: 2px; font-size: 80%; font-weight: normal; }
  .timestamp { color: #bebebe; }
  .timestamp-kwd { color: #5f9ea0; }
  .org-right  { margin-left: auto; margin-right: 0px;  text-align: right; }
  .org-left   { margin-left: 0px;  margin-right: auto; text-align: left; }
  .org-center { margin-left: auto; margin-right: auto; text-align: center; }
  .underline { text-decoration: underline; }
  #postamble p, #preamble p { font-size: 90%; margin: .2em; }
  p.verse { margin-left: 3%; }
  pre {
    border: 1px solid #e6e6e6;
    border-radius: 3px;
    background-color: #f2f2f2;
    padding: 8pt;
    font-family: monospace;
    overflow: auto;
    margin: 1.2em;
  }
  pre.src {
    position: relative;
    overflow: auto;
  }
  pre.src:before {
    display: none;
    position: absolute;
    top: -8px;
    right: 12px;
    padding: 3px;
    color: #555;
    background-color: #f2f2f299;
  }
  pre.src:hover:before { display: inline; margin-top: 14px;}
  /* Languages per Org manual */
  pre.src-asymptote:before { content: 'Asymptote'; }
  pre.src-awk:before { content: 'Awk'; }
  pre.src-authinfo::before { content: 'Authinfo'; }
  pre.src-c:before { content: 'C'; }
  pre.src-C:before { content: 'C'; }
  /* pre.src-C++ doesn't work in CSS */
  pre.src-clojure:before { content: 'Clojure'; }
  pre.src-css:before { content: 'CSS'; }
  pre.src-D:before { content: 'D'; }
  pre.src-ditaa:before { content: 'ditaa'; }
  pre.src-dot:before { content: 'Graphviz'; }
  pre.src-calc:before { content: 'Emacs Calc'; }
  pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
  pre.src-fortran:before { content: 'Fortran'; }
  pre.src-gnuplot:before { content: 'gnuplot'; }
  pre.src-haskell:before { content: 'Haskell'; }
  pre.src-hledger:before { content: 'hledger'; }
  pre.src-java:before { content: 'Java'; }
  pre.src-js:before { content: 'JavaScript'; }
  pre.src-latex:before { content: 'LaTeX'; }
  pre.src-ledger:before { content: 'Ledger'; }
  pre.src-lisp:before { content: 'Lisp'; }
  pre.src-lilypond:before { content: 'Lilypond'; }
  pre.src-lua:before { content: 'Lua'; }
  pre.src-matlab:before { content: 'MATLAB'; }
  pre.src-mscgen:before { content: 'Mscgen'; }
  pre.src-ocaml:before { content: 'Objective Caml'; }
  pre.src-octave:before { content: 'Octave'; }
  pre.src-org:before { content: 'Org mode'; }
  pre.src-oz:before { content: 'OZ'; }
  pre.src-plantuml:before { content: 'Plantuml'; }
  pre.src-processing:before { content: 'Processing.js'; }
  pre.src-python:before { content: 'Python'; }
  pre.src-R:before { content: 'R'; }
  pre.src-ruby:before { content: 'Ruby'; }
  pre.src-sass:before { content: 'Sass'; }
  pre.src-scheme:before { content: 'Scheme'; }
  pre.src-screen:before { content: 'Gnu Screen'; }
  pre.src-sed:before { content: 'Sed'; }
  pre.src-sh:before { content: 'shell'; }
  pre.src-sql:before { content: 'SQL'; }
  pre.src-sqlite:before { content: 'SQLite'; }
  /* additional languages in org.el's org-babel-load-languages alist */
  pre.src-forth:before { content: 'Forth'; }
  pre.src-io:before { content: 'IO'; }
  pre.src-J:before { content: 'J'; }
  pre.src-makefile:before { content: 'Makefile'; }
  pre.src-maxima:before { content: 'Maxima'; }
  pre.src-perl:before { content: 'Perl'; }
  pre.src-picolisp:before { content: 'Pico Lisp'; }
  pre.src-scala:before { content: 'Scala'; }
  pre.src-shell:before { content: 'Shell Script'; }
  pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
  /* additional language identifiers per "defun org-babel-execute"
       in ob-*.el */
  pre.src-cpp:before  { content: 'C++'; }
  pre.src-abc:before  { content: 'ABC'; }
  pre.src-coq:before  { content: 'Coq'; }
  pre.src-groovy:before  { content: 'Groovy'; }
  /* additional language identifiers from org-babel-shell-names in
     ob-shell.el: ob-shell is the only babel language using a lambda to put
     the execution function name together. */
  pre.src-bash:before  { content: 'bash'; }
  pre.src-csh:before  { content: 'csh'; }
  pre.src-ash:before  { content: 'ash'; }
  pre.src-dash:before  { content: 'dash'; }
  pre.src-ksh:before  { content: 'ksh'; }
  pre.src-mksh:before  { content: 'mksh'; }
  pre.src-posh:before  { content: 'posh'; }
  /* Additional Emacs modes also supported by the LaTeX listings package */
  pre.src-ada:before { content: 'Ada'; }
  pre.src-asm:before { content: 'Assembler'; }
  pre.src-caml:before { content: 'Caml'; }
  pre.src-delphi:before { content: 'Delphi'; }
  pre.src-html:before { content: 'HTML'; }
  pre.src-idl:before { content: 'IDL'; }
  pre.src-mercury:before { content: 'Mercury'; }
  pre.src-metapost:before { content: 'MetaPost'; }
  pre.src-modula-2:before { content: 'Modula-2'; }
  pre.src-pascal:before { content: 'Pascal'; }
  pre.src-ps:before { content: 'PostScript'; }
  pre.src-prolog:before { content: 'Prolog'; }
  pre.src-simula:before { content: 'Simula'; }
  pre.src-tcl:before { content: 'tcl'; }
  pre.src-tex:before { content: 'TeX'; }
  pre.src-plain-tex:before { content: 'Plain TeX'; }
  pre.src-verilog:before { content: 'Verilog'; }
  pre.src-vhdl:before { content: 'VHDL'; }
  pre.src-xml:before { content: 'XML'; }
  pre.src-nxml:before { content: 'XML'; }
  /* add a generic configuration mode; LaTeX export needs an additional
     (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
  pre.src-conf:before { content: 'Configuration File'; }

  table { border-collapse:collapse; }
  caption.t-above { caption-side: top; }
  caption.t-bottom { caption-side: bottom; }
  td, th { vertical-align:top;  }
  th.org-right  { text-align: center;  }
  th.org-left   { text-align: center;   }
  th.org-center { text-align: center; }
  td.org-right  { text-align: right;  }
  td.org-left   { text-align: left;   }
  td.org-center { text-align: center; }
  dt { font-weight: bold; }
  .footpara { display: inline; }
  .footdef  { margin-bottom: 1em; }
  .figure { padding: 1em; }
  .figure p { text-align: center; }
  .equation-container {
    display: table;
    text-align: center;
    width: 100%;
  }
  .equation {
    vertical-align: middle;
  }
  .equation-label {
    display: table-cell;
    text-align: right;
    vertical-align: middle;
  }
  .inlinetask {
    padding: 10px;
    border: 2px solid gray;
    margin: 10px;
    background: #ffffcc;
  }
  #org-div-home-and-up
   { text-align: right; font-size: 70%; white-space: nowrap; }
  textarea { overflow-x: auto; }
  .linenr {
    font-size: smaller;
    @supports (content: attr(data-linenr)) {
      visibility: hidden;
      &::before { content: attr(data-linenr); visibility: visible; }
    }
  }
  .code-highlighted { background-color: #ffff00; }
  .org-info-js_info-navigation { border-style: none; }
  #org-info-js_console-label
    { font-size: 10px; font-weight: bold; white-space: nowrap; }
  .org-info-js_search-highlight
    { background-color: #ffff00; color: #000000; font-weight: bold; }
  .org-svg { }
</style>
<style type=3D"text/css">#table-of-contents h2 { display: none } .title { d=
isplay: none } .authorname { text-align: right }</style>
<style type=3D"text/css">.outline-2 {border-top: 1px solid black;}</style>
</head>
<body>
<div id=3D"content" class=3D"content">
<h1 class=3D"title">OCaml Weekly News</h1>
<p>
<a href=3D"https://alan.petitepomme.net/cwn/2026.07.21.html">Previous Week<=
/a> <a href=3D"https://alan.petitepomme.net/cwn/index.html">Up</a> <a href=
=3D"https://alan.petitepomme.net/cwn/2026.08.04.html">Next Week</a>
</p>

<p>
Hello
</p>

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

<div id=3D"table-of-contents" role=3D"doc-toc">
<h2>Table of Contents</h2>
<div id=3D"text-table-of-contents" role=3D"doc-toc">
<ul>
<li><a href=3D"#1">Theo 0.1.0: a BDD library with theory support</a></li>
<li><a href=3D"#2">qiskit 2.0.1</a></li>
<li><a href=3D"#3">Wax 0.1.0: a Rust-like syntax for WebAssembly</a></li>
<li><a href=3D"#4">Cascade: A Typed CSS Toolkit in OCaml</a></li>
<li><a href=3D"#5">Dune 3.24</a></li>
<li><a href=3D"#6">ocaml-wire: a Binary wire format DSL with EverParse 3D o=
utput</a></li>
<li><a href=3D"#7">Eio 1.4 (effects-based concurrency library)</a></li>
<li><a href=3D"#8">ocaml-sbom 0.1.0</a></li>
<li><a href=3D"#9">Union-find-lattice library</a></li>
<li><a href=3D"#10">Challenging Claude's creativity with IFS fractals and O=
Caml</a></li>
<li><a href=3D"#11">Simple_http.1.1 available</a></li>
<li><a href=3D"#org96a9746">Old CWN</a></li>
</ul>
</div>
</div>
<div id=3D"outline-container-1" class=3D"outline-2">
<h2 id=3D"1">Theo 0.1.0: a BDD library with theory support</h2>
<div class=3D"outline-text-2" id=3D"text-1">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-theo-0-1-0-a-bdd-librar=
y-with-theory-support/18376/1">https://discuss.ocaml.org/t/ann-theo-0-1-0-a=
-bdd-library-with-theory-support/18376/1</a>
</p>
</div>
<div id=3D"outline-container-org1687f6a" class=3D"outline-3">
<h3 id=3D"org1687f6a">J=C3=A9r=C3=B4me Vouillon announced</h3>
<div class=3D"outline-text-3" id=3D"text-org1687f6a">
<p>
I'm pleased to announce the first release of <a href=3D"https://github.com/=
vouillon/theo">Theo</a>, an OCaml library for <i>Binary Decision Diagrams (=
BDDs)</i>.
</p>

<p>
BDDs give you a <i>canonical</i> 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 <i>theory support</i>: atoms aren't just boolean variables but constrai=
nts like <code>ocaml &gt;=3D 4.14</code> or <code>name =3D "foo"</code>, an=
d the engine understands their semantics. This makes it practical for real-=
world constraint problems.
</p>

<p>
For example, a package manager can ask whether <code>(ocaml &gt;=3D 4.14 AN=
D dune &gt;=3D 3.0) OR (ocaml &gt;=3D 5.0)</code> is compatible with <code>=
ocaml &lt; 5.0</code>. Theo reasons about the version constraints directly:=
 it knows <code>ocaml &gt;=3D 4.14</code> is redundant when <code>ocaml &gt=
;=3D 5.0</code> holds, detects that the second disjunct contradicts <code>o=
caml &lt; 5.0</code>, and can extract the simplest satisfying assignment (<=
code>ocaml &gt;=3D 4.14, dune &gt;=3D 3.0</code>).
</p>
</div>
<div id=3D"outline-container-org1e4b8e6" class=3D"outline-4">
<h4 id=3D"org1e4b8e6">Highlights of the 0.1.0 release:</h4>
<div class=3D"outline-text-4" id=3D"text-org1e4b8e6">
<ul class=3D"org-ul">
<li>Core BDD engine with hash-consing (via weak tables) and a canonical neg=
ative-edge form</li>
<li>Boolean operations: AND, OR, NOT, IMPLIES, EQUIV, XOR, plus <code>exist=
s~/~forall</code> quantifiers</li>
<li>Pluggable theory support over linear orders and equality (booleans, str=
ings, integers, semantic versions), with a <code>Combine</code> functor to =
mix theories in the same BDD</li>
<li><code>restrict</code> for partial evaluation under a set of external co=
nstraints, and constraint introspection via pattern matching</li>
<li>Minimal-witness extraction (shortest satisfying assignment) and zero-al=
location entailment checks (implication, disjointness, exhaustiveness)</li>
<li>Irredundant sum-of-products (Minato=E2=80=93Morreale) computation</li>
<li>A property-based test suite</li>
</ul>

<p>
Some implementation details that may be of interest: memoization caches are=
 built on <i>ephemerons</i>, 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 <i>during</i>=
 BDD construction, using atom ordering to prune redundant bounds. The theor=
y interface is a small functor-based API, and the same <code>Syntax</code> =
functor produces both BDD formulas and constraint lists.
</p>

<p>
I've written a <a href=3D"https://vouillon.github.io/blog/posts/theo/">comp=
anion blog post</a> that walks through the main ideas: hash-consing and eph=
emeron caches, theory-aware simplification, and the algorithmic techniques =
behind <code>restrict</code>, minimal witnesses, and zero-allocation querie=
s.
</p>

<ul class=3D"org-ul">
<li>Source: <a href=3D"https://github.com/vouillon/theo">https://github.com=
/vouillon/theo</a></li>
<li>API docs: <a href=3D"https://vouillon.github.io/theo/theo/Theo/">https:=
//vouillon.github.io/theo/theo/Theo/</a></li>
<li>Install: <code>opam install theo</code></li>
</ul>

<p>
Feedback and contributions welcome!
</p>
</div>
</div>
</div>
</div>
<div id=3D"outline-container-2" class=3D"outline-2">
<h2 id=3D"2">qiskit 2.0.1</h2>
<div class=3D"outline-text-2" id=3D"text-2">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-qiskit-2-0-1/18378/1">h=
ttps://discuss.ocaml.org/t/ann-qiskit-2-0-1/18378/1</a>
</p>
</div>
<div id=3D"outline-container-orga249928" class=3D"outline-3">
<h3 id=3D"orga249928">Davide Gessa announced</h3>
<div class=3D"outline-text-3" id=3D"text-orga249928">
<p>
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 &gt; 2.0, which includes some breaking changes:
</p>

<ul class=3D"org-ul">
<li>IBMProvider becomes IBMRuntime</li>
<li>Some gates addition  and some gates removal</li>
</ul>

<p>
<a href=3D"https://opam.ocaml.org/packages/qiskit/qiskit.2.0.1/">https://op=
am.ocaml.org/packages/qiskit/qiskit.2.0.1/</a>
</p>

<p>
<a href=3D"https://github.com/dakk/caml_qiskit/">https://github.com/dakk/ca=
ml_qiskit/</a>
</p>
</div>
</div>
</div>
<div id=3D"outline-container-3" class=3D"outline-2">
<h2 id=3D"3">Wax 0.1.0: a Rust-like syntax for WebAssembly</h2>
<div class=3D"outline-text-2" id=3D"text-3">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/wax-0-1-0-a-rust-like-synta=
x-for-webassembly/18379/1">https://discuss.ocaml.org/t/wax-0-1-0-a-rust-lik=
e-syntax-for-webassembly/18379/1</a>
</p>
</div>
<div id=3D"outline-container-org8d6c3c0" class=3D"outline-3">
<h3 id=3D"org8d6c3c0">J=C3=A9r=C3=B4me Vouillon announced</h3>
<div class=3D"outline-text-3" id=3D"text-org8d6c3c0">
<p>
I'm happy to announce the first release of <b>Wax</b>, a toolchain that giv=
es WebAssembly a familiar, expression-oriented syntax. It's written in OCam=
l and, as of 0.1.0, <code>wax</code> is available on the opam repository:
</p>

<pre class=3D"example" id=3D"org5aed8e5">
opam install wax
</pre>

<p>
<b>Why I'm building it.</b> The <code>wasm_of_ocaml</code> 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.
</p>

<p>
The WebAssembly text format spells everything out:
</p>

<div class=3D"org-src-container">
<pre class=3D"src src-wat"><code>(func $add (param $x i32) (param $y i32) (=
result i32)
  (i32.add (local.get $x) (local.get $y)))
</code></pre>
</div>

<p>
Wax reads like a programming language:
</p>

<div class=3D"org-src-container">
<pre class=3D"src src-rust"><code>fn add(x: i32, y: i32) -&gt; i32 {
    x + y;
}
</code></pre>
</div>

<p>
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:
</p>

<div class=3D"org-src-container">
<pre class=3D"src src-rust"><code>type list =3D { value: i32, next: &amp;?l=
ist };

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

<p>
A few highlights:
</p>

<ul class=3D"org-ul">
<li><b>Every direction.</b> All nine conversions between <code>wax</code>, =
<code>wat</code>, and <code>wasm</code> work, including decompiling an arbi=
trary <code>.wasm</code> binary back into readable Wax.</li>
<li><b>Full WebAssembly 3.0.</b> Garbage collection, exception handling, ta=
il calls, multiple and 64-bit memories, and SIMD, plus stack switching, thr=
eads, wide arithmetic, and branch hints.</li>
<li><b>A real type checker.</b> Errors are caught before any output is prod=
uced and reported with source context.</li>
<li><b>A toolchain, not just a compiler.</b> 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.</li>
</ul>

<p>
You can try it in your browser, no install required, on the <a href=3D"http=
s://ocsigen.org/wax/playground.html">playground</a>: type Wax and see the W=
AT and diagnostics live.
</p>

<p>
<b>This is an early, experimental release.</b> 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.
</p>

<ul class=3D"org-ul">
<li>Docs: <a href=3D"https://ocsigen.org/wax/">https://ocsigen.org/wax/</a>=
</li>
<li>Source: <a href=3D"https://github.com/ocsigen/wax">https://github.com/o=
csigen/wax</a></li>
</ul>
</div>
</div>
</div>
<div id=3D"outline-container-4" class=3D"outline-2">
<h2 id=3D"4">Cascade: A Typed CSS Toolkit in OCaml</h2>
<div class=3D"outline-text-2" id=3D"text-4">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/cascade-a-typed-css-toolkit=
-in-ocaml/18383/1">https://discuss.ocaml.org/t/cascade-a-typed-css-toolkit-=
in-ocaml/18383/1</a>
</p>
</div>
<div id=3D"outline-container-org1124677" class=3D"outline-3">
<h3 id=3D"org1124677">Thomas Gazagnaire announced</h3>
<div class=3D"outline-text-3" id=3D"text-org1124677">
<p>
I'm happy to announce the first release of <a href=3D"https://github.com/sa=
moht/cascade">cascade</a> available in opam (<code>opam install cascade</co=
de>) and in brew (<code>brew install samoht/tap/cascade</code>).
</p>

<p>
Cascade is a library:
</p>

<ul class=3D"org-ul">
<li>a typed AST to represent CSS documents;</li>
<li>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 <a href=3D"https://doi.org/10.1145/3310337">SatCSS paper</a>), sema=
ntic-preserving canonisation, and <a href=3D"https://github.com/samoht/casc=
ade/blob/main/lib/css.mli">more</a>;</li>
<li>a diff function to compare those (optionally canonised) ASTs;</li>
<li>an apply function to apply a CSS value to an HTML document as style att=
ributes, preserving the cascade-order.</li>
</ul>

<p>
But cascade is also a CLI tool! All of those operations are available as su=
bcommands (with <code>cascade fmt</code>, <code>cascade diff</code> and <co=
de>cascade apply</code>).
</p>

<p>
You can read more details here: <a href=3D"https://gazagnaire.org/blog/2026=
-07-22-cascade-minify.html">https://gazagnaire.org/blog/2026-07-22-cascade-=
minify.html</a>
</p>

<p>
You are very welcome to report issues or discuss about ideas on the <a href=
=3D"https://github.com/samoht/cascade">GH tracker</a>.
</p>
</div>
</div>
</div>
<div id=3D"outline-container-5" class=3D"outline-2">
<h2 id=3D"5">Dune 3.24</h2>
<div class=3D"outline-text-2" id=3D"text-5">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-dune-3-24/18316/2">http=
s://discuss.ocaml.org/t/ann-dune-3-24/18316/2</a>
</p>
</div>
<div id=3D"outline-container-org1a78fe0" class=3D"outline-3">
<h3 id=3D"org1a78fe0">Continuing this thread, Ali Caglayan announced</h3>
<div class=3D"outline-text-3" id=3D"text-org1a78fe0">
<p>
The Dune team is pleased to announce <a href=3D"https://github.com/ocaml/du=
ne/releases/tag/3.24.1">the release of dune 3.24.1</a>.
</p>

<p>
See <a href=3D"https://github.com/ocaml/dune/releases/tag/3.24.1">the full =
changelog</a> for all new features and fixes, and for attribution to the co=
ntributors who made it all possible. Thank you, contributors!
</p>

<p>
If you encounter a problem with this release, please report it in <a href=
=3D"https://github.com/ocaml/dune/issues">our issue tracker</a>.
</p>
</div>
</div>
</div>
<div id=3D"outline-container-6" class=3D"outline-2">
<h2 id=3D"6">ocaml-wire: a Binary wire format DSL with EverParse 3D output<=
/h2>
<div class=3D"outline-text-2" id=3D"text-6">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-ocaml-wire-a-binary-wir=
e-format-dsl-with-everparse-3d-output/18009/5">https://discuss.ocaml.org/t/=
ann-ocaml-wire-a-binary-wire-format-dsl-with-everparse-3d-output/18009/5</a>
</p>
</div>
<div id=3D"outline-container-orgdc101c1" class=3D"outline-3">
<h3 id=3D"orgdc101c1">Continuing this thread, Thomas Gazagnaire announced</=
h3>
<div class=3D"outline-text-3" id=3D"text-orgdc101c1">
<p>
I am happy to announce the release 1.1.0 of ocaml-wire on opam!
</p>

<p>
The release improves a few things:
</p>
<ul class=3D"org-ul">
<li>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.</li>
<li>ocaml-wire now use [<a href=3D"https://github.com/mirage/optint">https:=
//github.com/mirage/optint</a>] 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).</li>
<li>parsing errors (in OCaml) are now much more precise and show the codecs=
, field names and stream location.</li>
<li>codecs are now safe to share across domains (each domain now have their=
 own scratch buffers)</li>
</ul>

<p>
The full changelog is available <a href=3D"https://github.com/parsimoni-lab=
s/ocaml-wire/releases/tag/1.1.0">here</a>.
</p>
</div>
</div>
</div>
<div id=3D"outline-container-7" class=3D"outline-2">
<h2 id=3D"7">Eio 1.4 (effects-based concurrency library)</h2>
<div class=3D"outline-text-2" id=3D"text-7">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-eio-1-4-effects-based-c=
oncurrency-library/18391/1">https://discuss.ocaml.org/t/ann-eio-1-4-effects=
-based-concurrency-library/18391/1</a>
</p>
</div>
<div id=3D"outline-container-org74a4641" class=3D"outline-3">
<h3 id=3D"org74a4641">Thomas Leonard announced</h3>
<div class=3D"outline-text-3" id=3D"text-org74a4641">
<p>
<a href=3D"https://github.com/ocaml-multicore/eio/releases/tag/v1.4">Eio 1.=
4</a> is now released and available from opam-repository.
</p>
</div>
<div id=3D"outline-container-org71e4308" class=3D"outline-4">
<h4 id=3D"org71e4308">About Eio</h4>
<div class=3D"outline-text-4" id=3D"text-org71e4308">
<p>
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.
</p>

<p>
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 <a href=3D"https://github.com/ocaml-multicore/lwt_eio">lwt_eio</a>, allo=
wing programs to be converted to Eio incrementally.
</p>

<p>
For a tutorial, see the <a href=3D"https://github.com/ocaml-multicore/eio#e=
io--effects-based-parallel-io-for-ocaml">Eio README</a>.
</p>
</div>
</div>
<div id=3D"outline-container-org3450424" class=3D"outline-4">
<h4 id=3D"org3450424">Highlights of the 1.4 release</h4>
<div class=3D"outline-text-4" id=3D"text-org3450424">
<ul class=3D"org-ul">
<li><a href=3D"https://ocaml-multicore.github.io/eio/eio/Eio/Net/index.html=
">Eio.Net</a> supports socket options (both the standard <code>Unix</code> =
ones and many more, e.g. <code>TCP_KEEPINTVL</code>).</li>

<li><a href=3D"https://ocaml-multicore.github.io/eio/eio/Eio/Path/index.htm=
l">Eio.Path</a> provides more file-system operations (<code>chmod</code>, <=
code>chown</code>, <code>read_dir_entries</code>, <code>with_dir_entries</c=
ode>). These all use the modern <code>*at</code> system calls and <code>RES=
OLVE_BENEATH</code> to make it easy to restrict path operations to a subtre=
e (see <code>Path.with_subtree</code>).</li>

<li><a href=3D"https://ocaml-multicore.github.io/eio/eio/Eio_unix/Pty/index=
.html">Eio_unix.Pty</a> adds pseudoterminal support (for writing terminal e=
mulators, SSH servers, etc).</li>
</ul>

<p>
The <code>Eio_linux</code> backend (which uses <a href=3D"https://github.co=
m/axboe/liburing">io_uring</a> rather than traditional POSIX system calls) =
now also supports <code>statx</code>, <code>fallocate</code> and <code>fdat=
async</code>.
</p>

<p>
Important bug-fixes include a work-around for macOS <code>poll</code> faili=
ng for certain devices, <code>Path.load</code> working on 0-length-but-not-=
empty files (as found under <code>/proc</code> 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.
</p>

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

<p>
For a full list of changes, see the <a href=3D"https://github.com/ocaml-mul=
ticore/eio/releases/tag/v1.4">release notes</a>.
</p>
</div>
</div>
</div>
</div>
<div id=3D"outline-container-8" class=3D"outline-2">
<h2 id=3D"8">ocaml-sbom 0.1.0</h2>
<div class=3D"outline-text-2" id=3D"text-8">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-ocaml-sbom-0-1-0/18393/=
1">https://discuss.ocaml.org/t/ann-ocaml-sbom-0-1-0/18393/1</a>
</p>
</div>
<div id=3D"outline-container-orgef73302" class=3D"outline-3">
<h3 id=3D"orgef73302">Nicolas Ojeda Bar announced</h3>
<div class=3D"outline-text-3" id=3D"text-orgef73302">
<p>
We are happy to announce the first public release of <code>ocaml-sbom</code=
>, a tool for generating Software Bills of Materials (<a href=3D"https://en=
.wikipedia.org/wiki/Software_supply_chain">SBOMs</a>) for your OPAM-based p=
rojects.
</p>

<p>
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. <code>ocaml-sbom</code> provides exactly that.
</p>

<p>
<code>ocaml-sbom</code> 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.
</p>

<p>
<a href=3D"https://github.com/LexiFi/ocaml-sbom/releases">https://github.co=
m/LexiFi/ocaml-sbom/releases</a>
</p>

<p>
The tool invokes <code>opam</code> at runtime and requires OPAM 2.2.0 or la=
ter. To install it:
</p>

<pre class=3D"example" id=3D"orge122e53">
$ opam install ocaml-sbom
</pre>

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

<pre class=3D"example" id=3D"org8ba94ac">
$ ocaml-sbom -o myproject.sbom
</pre>

<p>
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, <code>ocaml-sbom</code> exports to CycloneDX:
</p>

<pre class=3D"example" id=3D"orgcc4bfd0">
$ ocaml-sbom export myproject.sbom -o myproject.cdx
</pre>

<p>
See the README or the <code>--help</code> output for more details.
</p>

<blockquote>
<p>
<b>Note:</b> 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.
</p>
</blockquote>

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

<p>
Happy SBOM-ing!
</p>

<p>
Cheers,=20=20
Nicolas
</p>
</div>
</div>
</div>
<div id=3D"outline-container-9" class=3D"outline-2">
<h2 id=3D"9">Union-find-lattice library</h2>
<div class=3D"outline-text-2" id=3D"text-9">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-union-find-lattice-libr=
ary/18394/1">https://discuss.ocaml.org/t/ann-union-find-lattice-library/183=
94/1</a>
</p>
</div>
<div id=3D"outline-container-org1ae1d9a" class=3D"outline-3">
<h3 id=3D"org1ae1d9a">Dorian Lesbre announced</h3>
<div class=3D"outline-text-3" id=3D"text-org1ae1d9a">
<p>
I'm happy to announce the release of <a href=3D"https://codex.top/api/union=
-find-lattice/">union-find-lattice v0.1.0</a> 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).
</p>

<p>
These new algorithms are best explained in the <a href=3D"https://www.norma=
lesup.org/~dlesbre/research/2026-sas-union-find-lattice.html.en">SAS 26 pap=
er <i>A Lattice of Union-Finds</i></a> 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.
</p>

<p>
The core signature of the library is thus a functor of type:
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">module</span> <span style=3D"color: #557400; font-weight: bold;"=
>UF</span><span style=3D"color: #007a9f;">(Node: </span><span style=3D"colo=
r: #444fcf; font-weight: bold;">NODE</span><span style=3D"color: #007a9f;">=
) </span>=3D <span style=3D"color: #242521; font-weight: bold;">sig</span>
  <span style=3D"color: #242521; font-weight: bold;">type</span> <span styl=
e=3D"color: #444fcf; font-weight: bold;">t</span>

  <span style=3D"color: #4f677f; font-style: italic;">(** =3D=3D=3D=3D Stan=
dard union-find operations =3D=3D=3D=3D=3D=3D=3D=3D=3D *)</span>
  <span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">make</span>: int -&gt; t
  <span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">find</span>: t -&gt; <span style=3D"color: #557400; fo=
nt-weight: bold;">Node.</span>t
  <span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">union</span>: t -&gt; <span style=3D"color: #557400; f=
ont-weight: bold;">Node.</span>t -&gt; <span style=3D"color: #557400; font-=
weight: bold;">Node.</span>t -&gt; t
  <span style=3D"color: #4f677f; font-style: italic;">(** persistent union-=
find: union does not modify its argument *)</span>

  <span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">check_related</span>: t -&gt; <span style=3D"color: #5=
57400; font-weight: bold;">Node.</span>t -&gt; <span style=3D"color: #55740=
0; font-weight: bold;">Node.</span>t -&gt; bool
  <span style=3D"color: #4f677f; font-style: italic;">(** </span><span styl=
e=3D"color: #804f60; font-style: italic;">[</span>check_related t a b<span =
style=3D"color: #804f60; font-style: italic;">]</span><span style=3D"color:=
 #4f677f; font-style: italic;"> is true IFF </span><span style=3D"color: #8=
04f60; font-style: italic;">[</span>a<span style=3D"color: #804f60; font-st=
yle: italic;">]</span><span style=3D"color: #4f677f; font-style: italic;"> =
and </span><span style=3D"color: #804f60; font-style: italic;">[</span>b<sp=
an style=3D"color: #804f60; font-style: italic;">]</span><span style=3D"col=
or: #4f677f; font-style: italic;"> are in the same class *)</span>

  <span style=3D"color: #4f677f; font-style: italic;">(** =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 *)</span>
  <span style=3D"color: #4f677f; font-style: italic;">(** Lattice operands =
run in O(d*alpha(n)) where </span>
<span style=3D"color: #4f677f; font-style: italic;">      - n is the number=
 of nodes</span>
<span style=3D"color: #4f677f; font-style: italic;">      - d is the differ=
ence between both arguments (nodes with different parents)</span>
<span style=3D"color: #4f677f; font-style: italic;">      - alpha is the in=
verse Ackermann function *)</span>


  <span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">join</span>: t -&gt; t -&gt; t
  <span style=3D"color: #4f677f; font-style: italic;">(** </span><span styl=
e=3D"color: #804f60; font-style: italic;">[</span>check_related (join u v) =
a v &lt;=3D&gt; check_related u a b <span style=3D"color: #9f0d0f;">&amp;&a=
mp;</span> check_related v a b<span style=3D"color: #804f60; font-style: it=
alic;">]</span><span style=3D"color: #4f677f; font-style: italic;"> *)</spa=
n>

  <span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">meet</span>: t -&gt; t -&gt; t
  <span style=3D"color: #4f677f; font-style: italic;">(** </span><span styl=
e=3D"color: #804f60; font-style: italic;">[</span>check_related (meet u v) =
a v<span style=3D"color: #804f60; font-style: italic;">]</span><span style=
=3D"color: #4f677f; font-style: italic;"> is true IFF </span>
<span style=3D"color: #4f677f; font-style: italic;">      </span><span styl=
e=3D"color: #804f60; font-style: italic;">[</span>a<span style=3D"color: #8=
04f60; font-style: italic;">]</span><span style=3D"color: #4f677f; font-sty=
le: italic;"> and </span><span style=3D"color: #804f60; font-style: italic;=
">[</span>b<span style=3D"color: #804f60; font-style: italic;">]</span><spa=
n style=3D"color: #4f677f; font-style: italic;"> are related in the transit=
ive closure of </span><span style=3D"color: #804f60; font-style: italic;">[=
</span>u<span style=3D"color: #804f60; font-style: italic;">]</span><span s=
tyle=3D"color: #4f677f; font-style: italic;"> and </span><span style=3D"col=
or: #804f60; font-style: italic;">[</span>v<span style=3D"color: #804f60; f=
ont-style: italic;">]</span><span style=3D"color: #4f677f; font-style: ital=
ic;">, i.e.</span>
<span style=3D"color: #4f677f; font-style: italic;">      there exists c1 .=
. cn, </span><span style=3D"color: #804f60; font-style: italic;">[</span>ch=
eck_related u a c1 <span style=3D"color: #9f0d0f;">&amp;&amp;</span> check_=
related v c1 c2 <span style=3D"color: #9f0d0f;">&amp;&amp;</span> .. <span =
style=3D"color: #9f0d0f;">&amp;&amp;</span> check_related u cn b<span style=
=3D"color: #804f60; font-style: italic;">]</span><span style=3D"color: #4f6=
77f; font-style: italic;"> *)</span>

  <span style=3D"color: #242521; font-weight: bold;">val</span> <span style=
=3D"color: #a7601f;">incl</span>: t -&gt; t -&gt; bool
  <span style=3D"color: #4f677f; font-style: italic;">(** </span><span styl=
e=3D"color: #804f60; font-style: italic;">[</span>incl uf_a uf_b<span style=
=3D"color: #804f60; font-style: italic;">]</span><span style=3D"color: #4f6=
77f; font-style: italic;"> is lattice inclusion, </span><span style=3D"colo=
r: #804f60; font-style: italic;">[</span>uf_a &lt;=3D uf_b<span style=3D"co=
lor: #804f60; font-style: italic;">]</span><span style=3D"color: #4f677f; f=
ont-style: italic;">, i.e.</span>
<span style=3D"color: #4f677f; font-style: italic;">      forall </span><sp=
an style=3D"color: #804f60; font-style: italic;">[</span>x<span style=3D"co=
lor: #804f60; font-style: italic;">]</span><span style=3D"color: #4f677f; f=
ont-style: italic;"> </span><span style=3D"color: #804f60; font-style: ital=
ic;">[</span>y<span style=3D"color: #804f60; font-style: italic;">]</span><=
span style=3D"color: #4f677f; font-style: italic;">, if </span><span style=
=3D"color: #804f60; font-style: italic;">[</span>check_related uf_b x y<spa=
n style=3D"color: #804f60; font-style: italic;">]</span><span style=3D"colo=
r: #4f677f; font-style: italic;"> then </span><span style=3D"color: #804f60=
; font-style: italic;">[</span>check_related uf_a x y<span style=3D"color: =
#804f60; font-style: italic;">]</span><span style=3D"color: #4f677f; font-s=
tyle: italic;"> *)</span>
<span style=3D"color: #242521; font-weight: bold;">end</span>
</code></pre>
</div>

<p>
We provide multiple implementations of this signature:
</p>
<ul class=3D"org-ul">
<li>Internally, there three underlying data structure choices: <b>standard =
arrays</b> (with explicit copy), <b>persistent arrays</b> (same speed as ar=
ray but pay a cost for all version switches) or <b>Patricia trees</b> (usin=
g our <a href=3D"https://codex.top/api/patricia-tree/">patricia-tree librar=
y</a>, truly immutable but add a log(nb_unions) cost to all operations).</l=
i>
<li>We include variants for <b>labeled union-find</b> (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 <a href=3D"https://www.=
normalesup.org/~dlesbre/research/2025-pldi-relational-abstractions-labeled-=
uf.html.en">PLDI 25 paper, <i>Relational Abstractions based on Labeled Unio=
n-Find</i></a> and for <b>valued union-find</b>, where each class has a uni=
que associated value (values also have a lattice structure).</li>
</ul>
</div>
</div>
</div>
<div id=3D"outline-container-10" class=3D"outline-2">
<h2 id=3D"10">Challenging Claude's creativity with IFS fractals and OCaml</=
h2>
<div class=3D"outline-text-2" id=3D"text-10">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/challenging-claudes-creativ=
ity-with-ifs-fractals-and-ocaml/18398/1">https://discuss.ocaml.org/t/challe=
nging-claudes-creativity-with-ifs-fractals-and-ocaml/18398/1</a>
</p>
</div>
<div id=3D"outline-container-org8184896" class=3D"outline-3">
<h3 id=3D"org8184896">C=C3=A9dric announced</h3>
<div class=3D"outline-text-3" id=3D"text-org8184896">
<p>
Hello,
</p>

<p>
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:
</p>

<p>
<a href=3D"https://github.com/cedricbonhomme/iterated-function-systems">htt=
ps://github.com/cedricbonhomme/iterated-function-systems</a>
</p>

<p>
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.
</p>

<p>
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:
</p>

<ul class=3D"org-ul">
<li><p>
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:
</p>
<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><code><span style=3D"color: #242521; font-weig=
ht: bold;">let</span> <span style=3D"color: #007a9f;">lace</span> =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|]}]}<span style=3D=
"color: #9f0d0f;">;;</span>
</code></pre>
</div></li>
<li>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.</l=
i>
<li>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.</li>
<li>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.</li>
</ul>

<p>
The write-up with all the images is here:
</p>

<p>
<a href=3D"https://www.cedricbonhomme.org/2026/07/27/challenging-claude-wit=
h-ifs-fractals/">https://www.cedricbonhomme.org/2026/07/27/challenging-clau=
de-with-ifs-fractals/</a>
</p>

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

<p>
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!
</p>


<div id=3D"orga865e15" class=3D"figure">
<p><img src=3D"https://us1.discourse-cdn.com/flex020/uploads/ocaml/original=
/2X/8/82d90e9430e26168eb5407d9df00211ad6bbe08a.png" alt=3D"82d90e9430e26168=
eb5407d9df00211ad6bbe08a.png" width=3D"80%" />
</p>
</div>
</div>
</div>
</div>
<div id=3D"outline-container-11" class=3D"outline-2">
<h2 id=3D"11">Simple_http.1.1 available</h2>
<div class=3D"outline-text-2" id=3D"text-11">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/simple-http-1-1-available/1=
8399/1">https://discuss.ocaml.org/t/simple-http-1-1-available/18399/1</a>
</p>
</div>
<div id=3D"outline-container-org33d2fce" class=3D"outline-3">
<h3 id=3D"org33d2fce">Christophe Raffalli announced</h3>
<div class=3D"outline-text-3" id=3D"text-org33d2fce">
<p>
Dear Camlers,
</p>

<p>
<b>Announcing Simple_httpd 1.1</b>
</p>

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

<p>
It started as a fork of <a href=3D"https://github.com/c-cube/tiny_httpd">ti=
ny_httpd</a> to experiment with OCaml 5 domains and effects, Simple_httpd h=
as now matured into a robust server used to host real websites.
</p>

<p>
Documentation : <a href=3D"https://raffalli.eu/simple_httpd/simple_httpd/in=
dex.html">https://raffalli.eu/simple_httpd/simple_httpd/index.html</a> (ser=
ved by simple_httpd, and containing nice benchmarks)
</p>

<p>
Github : <a href=3D"https://github.com/craff/simple_httpd">https://github.c=
om/craff/simple_httpd</a>.
</p>
</div>
<div id=3D"outline-container-orgbafaa75" class=3D"outline-4">
<h4 id=3D"orgbafaa75">Highlights</h4>
<div class=3D"outline-text-4" id=3D"text-orgbafaa75">
<ul class=3D"org-ul">
<li><b>Very fast</b>: built around Linux <b>epoll</b>, <b>eventfd</b>, OCam=
l 5 <b>domains</b> and <b>effects</b>, with careful attention to latency an=
d throughput. Benchmarks show excellent performance, competitive with or ex=
ceeding traditional web servers for many workloads.</li>

<li><b>Production ready</b>: the server has been running real websites reli=
ably for months, validating both its performance and stability in everyday =
use.</li>

<li><b>Compiled server-side templates</b>: <code>.chaml</code> files provid=
e an OCaml equivalent of PHP, except that templates are <b>compiled</b> rat=
her than interpreted, combining flexibility with native performance. It is =
much faster than php.</li>

<li><b>Flexible routing</b>: 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.</li>

<li><b>Static and embedded resources</b>: serve files directly from the fil=
esystem, or package them into the executable using <code>vfs_pack</code>. C=
ompression is supported in both cases and small file may even be cached in =
memory in the second case.</li>

<li><b>Built-in monitoring</b>: 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.</li>

<li><b>Modern HTTP 1.1 features</b>: 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!</li>
</ul>

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

<p>
Feedback, bug reports and contributions are very welcome!
</p>
</div>
</div>
</div>
</div>
<div id=3D"outline-container-org96a9746" class=3D"outline-2">
<h2 id=3D"org96a9746">Old CWN</h2>
<div class=3D"outline-text-2" id=3D"text-org96a9746">
<p>
If you happen to miss a CWN, you can <a href=3D"mailto:alan.schmitt@polytec=
hnique.org">send me a message</a> and I'll mail it to you, or go take a loo=
k at <a href=3D"https://alan.petitepomme.net/cwn/">the archive</a> or the <=
a href=3D"https://alan.petitepomme.net/cwn/cwn.rss">RSS feed of the archive=
s</a>.
</p>

<p>
If you also wish to receive it every week by mail, you may subscribe to the=
 <a href=3D"https://sympa.inria.fr/sympa/info/caml-list">caml-list</a>.
</p>

<div class=3D"authorname" id=3D"org3107d33">
<p>
<a href=3D"https://alan.petitepomme.net/">Alan Schmitt</a>
</p>

</div>
</div>
</div>
</div>
</body>
</html>


--==-=-=--

--=-=-=--

--===-=-=
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-----
--===-=-=--