Posts
Media
Videos
Starter Packs
OCaml
@ocaml.org
· 19h
OCaml Weekly News
opam-publish 2.7.0
Archive: https://discuss.ocaml.org/t/ann-opam-publish-2-7-0/17358/1
Kate announced
Hi everyone,
We are happy to announce the release of opam-publish 2.7.0 (and 2.6.0), which together brought the ability to more easily publish your releases automatically, thanks to @filipeom:
A new OPAM_PUBLISH_GH_TOKEN environment variable and --token argument are now available to pass the GitHub token
SSH keys aren't used to push the branch to the user's fork anymore. Instead the token we already require is used.
If undefined, the git config variables user.name and user.email are automatically filled with the github username and username@opam-publish as a backup
An example of the new automated setup can be found in this CI job.
Other minor changes include:
The addition of a message after the PR is open, to notify users that they can re-run opam-publish to update the PR. Thanks to @punchagan
The switch from lwt_ssl to tls-lwt which avoid one dependency and avoid depending on the system libssl
Happy publishing!
<> <> The opam team <> <> :camel:
OCaml.org: Introducing Backstage OCaml - Separate Feeds for Stable and Experimental Features
Archive: https://discuss.ocaml.org/t/ocaml-org-introducing-backstage-ocaml-separate-feeds-for-stable-and-experimental-features/17359/1
Sabine Schmaltz announced
We're pleased to announce that OCaml.org now has dedicated RSS feeds and pages for stable and experimental announcements, introduced in PR #3278!
What's new:
OCaml Changelog at ocaml.org/changelog — Official stable release announcements and updates from the OCaml compiler, OCaml infrastructure, and the OCaml Platform Tools
Backstage OCaml at ocaml.org/backstage — Updates on experimental releases, work-in-progress, and opportunities to contribute to the development of the OCaml Platform and its infrastructure
This separation helps keep the main changelog focused on production-ready releases while providing a dedicated space for those interested in experimental work, early testing, and contributing to OCaml's development.
Both pages have their own RSS feeds, so you can subscribe to whichever matches your needs—or both!
We welcome your feedback as we continue improving OCaml.org.
LexiFi at FUN OCaml 2025
Archive: https://discuss.ocaml.org/t/lexifi-at-fun-ocaml-2025/17363/1
Nicolas Ojeda Bar announced
Dear OCaml enthusiasts,
LexiFi participated in this year's FUN OCaml that took place in Warsaw this past September 15 and 16. The event was a great success, thanks to the efforts of the organizers and the other participants. Hopefully the event will continue to take place and develop in the future.
LexiFi both sponsored and contributed (two) presentations to the event: a 30-minute retrospective on 25 years of using OCaml at LexiFi, and a 2-hour workshop on implementing a toy version of our type-reflection extension to the compiler.
If you are interested, we wrote a short blog post https://www.lexifi.com/blog/ocaml/fun-ocaml-2025/ where you will find the slides and the video for the 30-minute presentation, as well as the code and the slides for the 2-hour workshop (the video recording for this part is not yet available).
Enjoy!
Best wishes, Nicolas
Introducing oui
Archive: https://discuss.ocaml.org/t/introducing-oui/17364/1
Nathan Rebours announced
At OCamlPro we're happy to announce our new ongoing project funded by the CEA-List: ocaml-universal-installer or oui!
oui's goal is to help teams developping applications in OCaml to package them for their users outside the OCaml World by building binary installers for all major platforms: Linux, Windows and macOS.
oui builds standalone installers: you just need to download and run the file. No need to install OCaml, Opam and to compile anything on the target system anymore.
The tool will be used to package and distribute Frama-C and its plugins to non opam users.
It is still in development but we'd like to present it to the community with the hope that it will prove helpful to you as well.
How it works
You take care of building your application and provide oui the list of your binaries and extra files you'd like installed alongside them and it will assemble an installer from those.
It uses different tools and build different types of installers for all three main platfoms:
on Linux, we build self extracting archives using makeself.
on macOS, we build regular OSX installers using pkgbuild~/~productbuild
We started oui on top of an older but very similar project: opam-wix. opam-wix was an opam plugin used to build a Windows MSI from a locally installed opam package. This feature, though not the core focus of the early development, is still available via opam-oui and will be extended with the ability to build installers for the other supported platforms.
A tool for the community
Though it is initially developped for Frama-C's distribution, both the CEA-List and ourselves at OCamlPro would like to make oui a community tool that can help open source OCaml developpers ship their applications easily.
The goal of this early announcement is to gather data and feedback on other use cases for binary installers across the OCaml Ecosystem to help us shape oui into the right tool from the start.
This is an ongoing project, if you'd like to follow the development, it is publicly hosted here.
OCaml 5.4.0 released
octachron announced
We have the pleasure of celebrating the birthdays of Camille Saint-Saëns and Karl Schwarzschild by announcing the release of OCaml version 5.4.0.
Some of the highlights of OCaml 5.4.0 are:
Labelled tuples
It is now possible to add labels on tuple fields
let ( * ) (x,~dx) (y, ~dy) =
x*.y, ~dx:(x *. dy +. y *. dx )
Those labeled tuples are equivalent to SML records: they are an ordered and structurally-typed variants of records. In particular this implies that partial pattern matching on tuples is only possible for labelled tuples with a known type:
type t = float * dx:float
let v (x_and_dx:t) = let (x,..) = x_and_dx in x
Those types are mostly intended for local types where previous code was using tuples.
Array literal syntax support for immutable arrays and ~floatarray~s
The array literal syntax is now shared by array-like primitive types, like 'a array, floatarray and immutable array iarray. For instance, this code
let x = Float.Array.of_list [0.;1.;2.]
can now be written
let x : floatarray = [|0.; 1.; 2.|]
This also supported in patterns
let one = match x with
| [|_;y;_|] -> Some y
| _ -> None
However array indexing still needs to go through user-defined indexing operators
let (.$()) = Float.Array.get
let (.$()<-) = Float.Array.set
let () = x.$(0) <- x.$(1)
Immutable arrays
Along with shared array literals, OCaml 5.4 adds support for immutable arrays.
Immutable arrays are covariant in the type of their elements, it is thus possible to coerce immutable arrays with no costs at runtime:
let i1: _ iarray = [|object method m = 0 end|]
let i2 = ( i1 :> < > iarray)
Atomic record fields
It is now possible to mark a field of a record as atomic. Atomic operations on those fields require to use the new Atomic.Loc submodule after accessing the location with the [%atomic.loc ...] builtin extension. For instance,
type 'a mpsc_list = { mutable head:'a list; mutable tail: 'a list [@atomic] }
let rec push t x =
let before = Atomic.Loc.get [%atomic.loc t.tail] in
let after = x :: before in
if not (Atomic.Loc.compare_and_set [%atomic.loc t.tail] before after) then
push t x
...
Moreover, it is forbidden to pattern match on atomic fields:
let f { head; tail } = tail
Error: Atomic fields (here tail) are forbidden in patterns,
as it is difficult to reason about when the atomic read
will happen during pattern matching: the field may be read
zero, one or several times depending on the patterns around it.
in order to make all reads on those atomic fields explicit.
Four new standard library modules: Pair, Pqueue, Repr, and Iarray
The standard library has been extended with four new modules:
Pair: functions for working on pairs
let ones = Pair.map_fst succ (0,1)
Pqueue: priority queues, generic or not
module Int_pqueue = Pqueue.MakeMin(Int)
let q = Int_pqueue.of_list [4;0;5;7]
let some_zero = Int_pqueue.pop_min q
Repr: physical and structural equality, comparison function, more generically all functions dependent on the memory representation of values.
let f = Repr.phys_equal (ref 0) (ref 0)
Iarray: functions on immutable arrays
let a = Iarray.init 10 Fun.id
let b = Iarray.map succ a
Restored "memory cleanup upon exit" mode
This mode allows to restart many time the OCaml runtime in C-driven programs that interact with OCaml libraries. It is also useful to reduce noise when tracking memory leaks in C code running the OCaml runtime. To get around cancellation issues, the restored mode currently assumes that all domains are joined before exiting the OCaml runtime.
A new section in the reference manual on profiling OCaml programs on Linux and macOS
A new section in the reference manual explains how to use OS specific profiling tools to profile native OCaml programs.
A lot of incremental changes:
Many runtime and code generation improvements
More than thirty new standard library functions
Nearly a dozen improved error messages
Around fifty bug fixes
Please report any unexpected behaviours on the OCaml issue tracker and post any questions or comments you might have on our discussion forums.
The full list of changes can be found in the full changelog. Editor note: please follow the archive link above for the installation instructions and the full changelog
Happy hacking, Florian Angeletti for the OCaml team.
OCaml compiler office hours
Archive: https://discuss.ocaml.org/t/ocaml-compiler-office-hours/17230/16
Continuing this thread, gasche announced
The meeting went well – see the collaborative pad for notes.
I propose to have another meeting about a month from now:
(I picked a different time slot from the current one, that also looks reasonable given previous poll results. If extra people would like to join, please feel free to participate to the time-slot poll in the first post so that I can tell when are good meeting times.)
@giltho thanks for noticing the language issue on the online-meeting service I proposed; this is a new issue that looks like it comes from a version upgrade, it of course had a fine English interface when I adopted the service. Let's keep jitsi.meet for now.
tutorial about compiling ocaml-5 on a ChromBook with Crostini
Archive: https://discuss.ocaml.org/t/ann-tutorial-about-compiling-ocaml-5-on-a-chrombook-with-crostini/17368/1
Florent Monnier announced
Hello dear list, I wrote another mini-tutorial to explain how to compile ocaml-5 on a chromebook with crostini: http://decapode314.free.fr/ocaml2/tut/tut-ocaml-5/tut-ocaml-5.html The trick to compile ocaml-5 in this environement was the same than to compile ocaml-4 in the same environement because ln -s doesn't seem to produce the expected result. At the beginning I edited the Makefile to replace the ln -s commands by cp commands, but an easier way is to use the make feature that permits you to change the value of one of the variable from the command line which invokes make, like this make LN=cp.
With this trick everything was producing the expected ocaml tools with ocaml-4, but with ocaml-5, I have only been able to get ocamlnat and ocamlopt tools (which is enough.)
ocamlopt was installed as expected by the make install command, but ocamlnat had to be copied by hand.
If the command ocaml produces an error (cannot execute), in scripts I can still replace:
#!/usr/bin/env ocaml
by:
#!/usr/bin/env ocamlnat
By defining the same environement variables than opam I can get two different ocaml version usable at the same time, one 4 version, and a 5 version, next to each other at the same time, without using opam because opam grew up a lot, and in crostini environement we quickly lack of space.
PS: If someone want to help finding how to get the ocaml and ocamlc commands functioning, the help will be wellcome, and I will update this mini-tutorial.
dune-release-action: Automate your opam package releases with GitHub Actions
Archive: https://discuss.ocaml.org/t/ann-dune-release-action-automate-your-opam-package-releases-with-github-actions/17380/1
David Sancho announced
Hi everyone 👋
I'm excited to share a new GitHub Action I've been working on: dune-release-action
If you maintain OCaml packages, you know the drill: every release involves a ritual of commands and manual steps. You need to:
Ensure your CHANGES.md is properly formatted
Tag your release
Run dune-release lint + distrib + submit
Create a GitHub release with the correct changelog section
Check the opam-repository's PR
Oh shit, github token is expired
Create new token without expiration (??)
Retry
For me, was following this guide https://gist.github.com/anmonteiro/abd9275456888740758aa9f772d1992a by @anmonteiro, but it typically took around an hour per release.
dune-release-action
dune-release-action automates the entire release workflow in GitHub Actions. Push a git tag, and the action runs dune-release for you with:
Handles all the dune-release orchestration
Validates your changelog format (right tag exists, etc)
Creates a GitHub release with proper description (from your changelog section (!!))
Submits a PR to opam-repository
name: Release
on:
push:
tags:
- '*'
permissions:
contents: write
pull-requests: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: ocaml/setup-ocaml@v3
with:
ocaml-compiler: 5.3.0
- run: opam install dune-release -y
- uses: davesnx/dune-release-action@v1
with:
package-name: 'your-package'
github-token: ${{ secrets.GH_TOKEN }}
This is very much a one-day half vibe-coded project and it's hard to test in many use cases, I'm sure there are edge cases and workflows I haven't considered.
Documentation: https://github.com/davesnx/dune-release-action/blob/main/README.md
Looking forward to hearing your thoughts!
dlvr.it
OCaml
@ocaml.org
· 1d
Backstage OCaml: ocaml.nvim - A Neovim Plugin for OCaml
Discuss this post on discuss!
We're excited to announce ocaml.nvim, a new Neovim plugin actively being developed by Tarides that brings advanced OCaml development features to Neovim users. Think of it as the Neovim sibling of ocaml-eglot, which we released earlier this year for Emacs users.
What is ocaml.nvim?
Modern code editors communicate with programming languages through the Language Server Protocol (LSP), which provides essential features like syntax checking, code navigation, and auto-completion. However, OCaml's language server exposes powerful custom commands beyond what generic LSP clients can access.
ocaml.nvim works alongside generic Neovim LSP plugins like nvim-lspconfig, providing direct access to advanced ocamllsp features without requiring complex editor-side logic. The plugin gives you access to all the advanced Merlin commands not supported by generic LSP clients.
Key Features
Typed Holes Navigation - Navigate between typed holes (_) and interactively substitute them with the Construct command.
Semantic Navigation - Move through your code semantically: jump between expressions, parent let bindings, modules, functions, and match expressions.
Phrase Navigation - Move between OCaml phrases (top-level definitions) in your buffer.
Many more features are in development, including alternating between .ml and .mli files, type enclosing, and pattern matching generation.
Getting Started
Installation is straightforward with lazy.nvim:
require("lazy").setup({
{ "tarides/ocaml.nvim",
config = function()
require("ocaml").setup()
end
}
})
The plugin complements your existing LSP setup—you'll continue to use Neovim's built-in LSP for standard features while ocaml.nvim adds OCaml-specific capabilities.
Project Status
The ocaml.nvim repository is now public on GitHub, with comprehensive documentation, a feature table, and screencast demonstrations. We're working towards a stable 1.0 release and welcome feedback from the community.
Try out ocaml.nvim and let us know what you think! For questions or feedback, reach out to Charlène Gros at [email protected], join the discussion on the OCaml Discuss forum, or post an issue on the ocaml.nvim GitHub repository.
dlvr.it
OCaml
@ocaml.org
· 1d
Gospel Ecosystem: Tools Ready to Try, Language Evolving
Gospel, the behavioral specification language for OCaml, is at an interesting inflection point. After years of development and research, some tools in the ecosystem—particularly Ortac/QCheck-STM—are ready for early adopters to try on real codebases. At the same time, Gospel itself is preparing a major release with breaking changes as the language design continues to evolve.
Making Formal Methods Accessible
Traditionally, formal verification delivers strong correctness guarantees but requires significant expertise and resources. Gospel's vision is different: one specification language that will eventually support multiple verification strategies, from lightweight runtime testing to full mathematical proofs. While the testing tools are available today, the proof tools are still under development.
This approach follows a successful pattern established in other language ecosystems. ACSL (ANSI/ISO C Specification Language) provides a behavioral specification language for C programs that supports multiple verification tools including Frama-C, while JML (Java Modeling Language) offers a unified specification language for Java that can be used for runtime assertion checking, static analysis, and theorem proving. Similarly, Eiffel pioneered the concept of design by contract with specifications embedded directly in the programming language. Gospel brings this proven strategy to OCaml.
Gospel provides a non-invasive syntax for annotating OCaml interfaces with formal contracts in special comments beginning with @, describing type invariants, mutability, pre-conditions, post-conditions, and exceptions. The specifications use logical models to represent abstract types—for example, modeling a queue as a mathematical sequence to specify how operations transform its contents.
Status of Gospel and its Toolkit
Gospel language (experimental, major changes coming) is preparing a release with significant breaking changes. Early adopters should expect the language to evolve and should not expect bug fixes in the current version.
Gospel's tool-agnostic design powers an ecosystem of verification tools at different maturity levels:
Ortac provides dynamic verification through runtime assertion checking and automated test generation:
* Ortac/QCheck-STM (released, battle-tested) generates black-box state-machine tests and has found real bugs including missing bounds checks in varray, integer overflows causing segfaults in bitv, inconsistent behavior with zero-length vectors in bitv, and unexpected behavior in the standard library's Hashtbl.create. Supports higher-order functions like map.
* Ortac/Wrapper (released, early stage) instruments functions with runtime assertions but hasn't been extensively tested in production yet.
* Ortac/Monolith (experimental) provides fuzzing integration with Monolith.
Cameleer (working toward first release) translates Gospel into Why3 for deductive verification using automated theorem provers.
Peter (ongoing research) explores separation logic verification through CFML integration with Coq for complex heap manipulation proofs.
Open Source Infrastructure Strategy
Gospel development is funded by ANR grant ANR-22-CE48-0013, executed through collaboration between Nomadic Labs, Tarides, Inria, and LMF (Laboratoire Méthodes Formelles) at Université Paris-Saclay. The project demonstrates how open source can transform formal verification economics: rather than each organization independently funding expensive verification efforts, shared open tooling and verified libraries benefit the entire ecosystem.
Current State and Integration
Ortac/QCheck-STM is released and has proven effective on real codebases, with test runs completing in hundreds of milliseconds. Gospel itself is experimental with major language changes planned, so early adopters should expect breaking changes.
The OCaml Platform roadmap through 2026 includes formal verification as a workflow goal. Currently, using Ortac requires writing Dune rules manually. Integration with Dune as a first-class feature requires further discussion and development.
Try Ortac/QCheck-STM Today
Install via opam:
opam install ortac-qcheck-stm
This installs the ortac command-line tool and everything needed to generate QCheck-STM tests from Gospel specifications. See the Ortac tutorial for a complete walkthrough, or check the QCheck-STM plugin README for details.
The project welcomes early adopters who want to:
* Try Ortac/QCheck-STM on production codebases and report bugs found
* Provide feedback on Gospel's evolving specification language
* Share use cases that could benefit from formal verification
The VOCaL (Verified OCaml Library) project demonstrates Gospel's potential with formally verified data structures.
What to Expect
The verification infrastructure is already useful for testing — bugs are being found, specifications provide value as documentation. Work on establishing the path from testing to formal proofs is ongoing, but the proof tools aren't ready for general use yet.
Learn More
The ecosystem is open source and actively developed. Explore the Gospel GitHub organization, or review research papers:
* GOSPEL — Providing OCaml with a Formal Specification Language (FM 2019)
* Static and Dynamic Verification of OCaml Programs: The Gospel Ecosystem (ISoLA 2024)
* Dynamic Verification of OCaml Software with Gospel and Ortac/QCheck-STM (TACAS 2025, Best Tool Paper award from ETAPS)
For teams interested in specification-driven testing, Ortac/QCheck-STM is ready to try. For those interested in formal proofs or stable Gospel language features, watch the project but expect it will be some time before these are production-ready.
Contact: @n-osborne | Get started: Ortac Tutorial | Documentation: Gospel docs
dlvr.it
OCaml
@ocaml.org
· 5d
Release of OCaml 5.4.0
We have the pleasure of celebrating the birthdays of Camille Saint-Saëns and
Karl Schwarzschild by announcing the release of OCaml version 5.4.0.
Some of the highlights of OCaml 5.4.0 are:
Labelled tuples
It is now possible to put labels on tuple fields
let ( * ) (x,~dx) (y,~dx:dy) = x*.y, ~dx:(x *. dy +. y *. dx )
Those labeled tuples are equivalent to SML records: they are an order-dependent and structurally-typed variants of records. They are mostly intended for local types.
Array literal syntax support for immutable arrays and floatarrays
The array literal syntax is now shared by array-like primitive datatypes,
like 'a array, floatarray and immutable array iarray.
For instance, this code
let x =
let x = Array.Flotarray.create 3 in
Array.Flotarray.set x 0 1.;
Array.Flotarray.set x 1 2.;
Array.Flotarray.set x 2 3.;
x
can now be written
let x : floatarray = [|0.; 1.; 2.|]
This also supported in patterns
let one = match x with
| [|_;y;_|] -> Some y
| _ -> None
However array indexing still needs to go through user-defined indexing operator
let (.$()) = Array.Floatarray.get
let (.$()
dlvr.it
OCaml
@ocaml.org
· 6d
opam-publish 2.7.0
Feedback on this post is welcomed on Discuss!
We are happy to announce the release of opam-publish 2.7.0 which brings the ability to more easily publish your releases automatically, thanks to @filipeom:
* SSH keys aren't used to push the branch to the user's fork anymore. Instead the token we already require is used.
* If undefined, the git config variables user.name and user.email are automatically filled with the github username and username@opam-publish as a backup
An example of the new automated setup can be found in this CI job.
Other minor changes include:
* The switch from lwt_ssl to tls-lwt which avoid one dependency and avoid depending on the system libssl
Happy publishing!
The opam team :camel:
dlvr.it
OCaml
@ocaml.org
· 6d
opam-publish 2.6.0
We are happy to announce the release of opam-publish 2.6.0, which brings opam-publish closer to the ability to more easily publish your releases automatically.
This release brings:
* A new OPAM_PUBLISH_GH_TOKEN environment variable and --token argument are now available to pass the GitHub token, thanks to @filipeom
* The addition of a message after the PR is open, to notify users that they can re-run opam-publish to update the PR, thanks to @punchagan
Happy publishing!
The opam team :camel:
dlvr.it
OCaml
@ocaml.org
· 6d
OCaml Weekly News
Simon Cruanes announced
Hello camels,
I’m happy to announce the release of moonpool 0.9 and moonpool-lwt 0.9. Moonpool is a concurrency and parallelism library that provides lightweight fibers and a concept of Runner.t that they can be dispatched on. Multiple runners can co-exist inside a program.
This release is a fairly large one. First, Moonpool now requires OCaml >= 5.0 (no more 4.xx compat), which removes the need for a preprocessor and makes await generally available on every Runner.t. Some sub-libraries are now deprecated (moonpool-io, moonpool.sync in favor of picos, etc.).
The biggest improvement is moonpool-lwt. It now wraps Lwt_main.run and turns it into a Moonpool.Runner.t, meaning that Lwt, Lwt_io, Lwt_unix, and all the libraries built on top can now directly be used from Moonpool. Lwt promises can be turned into moonpool futures and conversely; fibers can be spawned in the Lwt_engine loop from any thread (to perform IO and call lwt libraries) and be awaited from other threads, too.
Documentation: https://c-cube.github.io/moonpool/moonpool/index.html , https://c-cube.github.io/moonpool/moonpool-lwt/Moonpool_lwt/index.html
Example echo server
module M_lwt = Moonpool_lwt
let ( let@ ) = ( @@ )
let str_of_sockaddr = function
| Unix.ADDR_UNIX s -> s
| Unix.ADDR_INET (addr, port) ->
Printf.sprintf "%s:%d" (Unix.string_of_inet_addr addr) port
let main ~port () : unit =
(* never resolved *)
let lwt_fut, _lwt_prom = Lwt.wait () in
let handle_client client_addr (ic, oc) : _ Lwt.t =
(* spawn a new fiber in the lwt thread *)
let@ () = M_lwt.spawn_lwt in
Printf.printf "got new client on %s\n%!" (str_of_sockaddr client_addr);
let buf = Bytes.create 1024 in
let continue = ref true in
while !continue do
let n = Lwt_io.read_into ic buf 0 (Bytes.length buf) |> M_lwt.await_lwt in
if n = 0 then
continue := false
else (
Lwt_io.write_from_exactly oc buf 0 n |> M_lwt.await_lwt;
Lwt_io.flush oc |> M_lwt.await_lwt;
)
done;
Printf.printf "done with client on %s\n%!" (str_of_sockaddr client_addr);
in
Printf.printf "listening on port=%d\n%!" port;
let addr = Unix.ADDR_INET (Unix.inet_addr_any, port) in
let _server =
Lwt_io.establish_server_with_client_address addr handle_client
|> M_lwt.await_lwt
in
M_lwt.await_lwt lwt_fut (* never returns *)
let () =
let port = ref 1234 in
let opts =
[
"-p", Arg.Set_int port, " port";
]
|> Arg.align
in
Arg.parse opts ignore "echo server";
M_lwt.lwt_main @@ fun _ -> main ~port:!port ()
Run it as echo_server -p 1234 and use nc localhost 1234 to connect. It will echo lines sent to it.
We can reuse Lwt_io.establish_server_with_client_address just fine, and use direct style to implement the client handler inside a single Moonpool fiber (via Moonpool_lwt.spawn_lwt that runs its argument in the lwt event loop).
Small server with a thread pool for compute
a variation on the previous one, with a thread pool on which CPU bound tasks can be run:
module M_lwt = Moonpool_lwt
let ( let@ ) = ( @@ )
let str_of_sockaddr = function
| Unix.ADDR_UNIX s -> s
| Unix.ADDR_INET (addr, port) ->
Printf.sprintf "%s:%d" (Unix.string_of_inet_addr addr) port
(* don't do this at home *)
let rec fib n =
if n <= 2 then 1 else fib (n-1) + fib (n-2)
let main ~port ~tpool () : unit =
(* never resolved *)
let lwt_fut, _lwt_prom = Lwt.wait () in
let handle_client client_addr (ic, oc) : _ Lwt.t =
(* spawn a new fiber in the lwt thread *)
let@ () = M_lwt.spawn_lwt in
Printf.printf "got new client on %s\n%!" (str_of_sockaddr client_addr);
let continue = ref true in
while !continue do
match Lwt_io.read_line ic |> M_lwt.await_lwt with
| exception End_of_file -> continue := false
| line ->
let input = int_of_string @@ String.trim line in
(* run fib(input) in the thread pool and suspend until
it's done *)
let fib_input =
Moonpool.Fut.spawn ~on:tpool (fun () -> fib input)
|> Moonpool.Fut.await
in
Lwt_io.write oc (Printf.sprintf "%d\n" fib_input)
|> M_lwt.await_lwt;
Lwt_io.flush oc |> M_lwt.await_lwt;
done;
Printf.printf "done with client on %s\n%!" (str_of_sockaddr client_addr);
in
Printf.printf "listening on port=%d\n%!" port;
let addr = Unix.ADDR_INET (Unix.inet_addr_any, port) in
let _server =
Lwt_io.establish_server_with_client_address addr handle_client
|> M_lwt.await_lwt
in
M_lwt.await_lwt lwt_fut (* never returns *)
let () =
let port = ref 1234 in
let j = ref 8 in
let opts =
[
"-j", Arg.Set_int j, " thread pool size";
"-p", Arg.Set_int port, " port";
]
|> Arg.align
in
Arg.parse opts ignore "echo server";
let@ tpool = Moonpool.Ws_pool.with_ ~num_threads:!j () in
M_lwt.lwt_main @@ fun _ -> main ~port:!port ~tpool ()
Note how the computation is done by starting a task in the tpool argument (a moonpool Runner.t provided to the main, by default a work stealing pool of 8 threads that can be set via -j <number of threads>) and then await-ed from the lwt handler. While the computation is running, the lwt client handler is suspended and doesn’t prevent other clients from making progress.
To test this one, use nc localhost 1234 and write (small) integers to get fib(n) computed. To see it work in parallel, open top or htop and run:
for i in `seq 1 200`; do nc localhost 1234 <<< '35' & done
First release candidate for OCaml 5.4.0
Archive: https://discuss.ocaml.org/t/first-release-candidate-for-ocaml-5-4-0/17338/1
octachron announced
The release of OCaml 5.4.0 is imminent.
As a final step, we are publishing a release candidate to check that everything is in order before the release in the upcoming week.
If you find any bugs, please report them on the OCaml's issue tracker.
Compared to the second beta, this release candidate only contains a fix in the TSAN mode, and one metadata fix in the changelog itself. The full change log for OCaml 5.4.0 is available on GitHub.
Happy hacking, Florian Angeletti for the OCaml team.
Fine-tuned compiler configuration
If you want to tweak the configuration of the compiler, you can switch to the option variant with:
opam update
opam switch create <switch_name> ocaml-variants.5.4.0~rc1+options <option_list>
where <option_list> is a space-separated list of ocaml-option-* packages. For instance, for a flambda and no-flat-float-array switch:
opam switch create 5.4.0~rc1+flambda+nffa ocaml-variants.5.4.0~rc1+options ocaml-option-flambda ocaml-option-no-flat-float-array
All available options can be listed with opam search ocaml-option.
Announcing the OCaml Zulip at ocaml.zulipchat.com
Archive: https://discuss.ocaml.org/t/announcing-the-ocaml-zulip-at-ocaml-zulipchat-com/17339/1
ancolie announced
Dear OCaml community,
There has been a recent renewed interest in maintaining an open, organized and synchronous communication channel, and the OCaml Zulip has been revived. It is freely readable without an account at ocaml.zulipchat.org, and can be accessed through various means of authentication, including Github accounts.
On Zulip, we have full access to our data at all time, and should the company change its policy, the data can be retrieved and the current version of Zulip server is self-hostable. In the meantime, we have been graciously offered sponsorship as an open community and can enjoy all features of the platform for free, and we thank Zulip for that.
The platform can be accessed either on the web (one tab per server), or on the desktop and mobile client, which allow for managing multiple organizations.
Talking about multiple organizations, there are already many OCaml, programming languages and verification related Zulip servers, such as Rocq, Types, Why3, Catala, Bytecode alliance, Owi or Aeneas. Check-out the full list of open to the public communities for more.
Finally, we would like to emphasize that any governance team or project is welcome to host their discussions on the Zulip, where a channel can be created and admin rights granted.
Cheers!
PS: For anyone already on the Zulip, as part of this effort, the URL was migrated from caml.zulipchat.org to ocaml.zulipchat.org and you may have to remove the server and login again.
An impressive macrobenchmark for eio
Archive: https://discuss.ocaml.org/t/an-impressive-macrobenchmark-for-eio/17344/1
conroj said
While wandering around the web I came across a link to a slide deck by our own @kayceesrk. On slide #35 is a macrobenchmark showing an EIO-based network server, and its throughput is pretty favorable compared to the Rust implementation’s.
Taking this at face value, it seems like quite an achievement - not only because GC is (supposedly) a handicap for OCaml, but also because this seems like a major improvement over a similar benchmark from 2022. I couldn’t find links to deeper discussion of these results, so I thought I would ask some of the obvious follow-up questions:
Is OCaml’s tail latency on par with Rust’s in these scenarios?
Are both the “OCaml eio” and “Rust Hyper” results using similar kernel capabilities, e.g. io_uring? (The slide seems to suggest so, but just confirming.)
Do these results generalize to different levels of concurrency, request/response sizes, etc?
Either way, kudos for raising OCaml’s profile as a platform for scalable computing!
Anil Madhavapeddy replied
They both used io_uring, yes. The OCaml bindings are at https://github.com/ocaml-multicore/ocaml-uring ; but note that there are several levels of io_uring usage possible depending on your tolerance for ranges of Linux kernel support (I’m just adding zero-copy transmit support at the moment for a project involving a petabyte of data).
OCaml’s tail latency will be worse than Rust’s due to having a GC, but not terribly so. As for generalization, those tests were run on a pre-5.0 version of OCaml, so the whole test suite would have to be rebased against the released versions. A good and useful exercise if someone would like to have a go at it!
Thomas Leonard also replied
I think the benchmarks are from https://github.com/ocaml-multicore/retro-httpaf-bench
I don’t think the Rust ones are using uring, but I’m not sure. I suspect that all the non-OCaml ones could do with a fan of that language optimising them a bit.
In my experience, whether the Rust or Eio version gets better throughput depends on e.g. the number of connections, and tail latency was always better with Rust.
But the basic result is that OCaml is competitive with Rust here.
nim-ocaml
Archive: https://discuss.ocaml.org/t/ann-nim-ocaml/17346/1
Florent Monnier announced
I read a paper maybe not this one, but it seems it talks about the same thing https://arxiv.org/html/2506.04657v1. At the beginning I thought it's about the new programming language, but then chatgpt explained me that in fact it's a small game with stones. We put a given number of stones in the middle, and each player can take 1, 2 or 3 stones from the stack. There are two variants of the game, the one that only has one stone in front of him at the end wins or not.
So I tryed to make a nim-ocaml to play against its Random.state, here below:
let () =
Random.self_init () ;
let n = 13 + (Random.int 23) in
let _n = ref n in
let run = ref true in
while !run do
Printf.printf "%d\n" !_n;
if !_n <= 1 then run := false ;
let line = read_line () in
begin
try
let d = int_of_string line in
_n := !_n - d ;
with _ ->
Printf.printf "please input an integer number\n%!";
end;
let b = Random.int 2 + Random.int 3 in
Printf.printf "b played: %d\n" b;
_n := !_n - b ;
done;
Printf.printf "done!\n" ;
Or later:
$ wget http://decapode314.free.fr/ocaml2/nim/nim.ml
$ \ocaml nim.ml
23
3
b played: 3
17
7
b played: 0
10
3
b played: 2
5
2
b played: 2
1
0
b played: 0
done!
Another version to play against your collegue at the pause:
$ wget http://decapode314.free.fr/ocaml2/nim/.gil/nim.ml.0
Call for Contributions: BOB 2026 (Berlin, March 13 - Deadline Nov 17)
Archive: https://discuss.ocaml.org/t/call-for-contributions-bob-2026-berlin-march-13-deadline-nov-17/17348/1
Michael Sperber announced
OCaml contributions are spot-on for BOB - send us some!
BOB Conference 2026 - Call for Contributions
Looking for Speakers
You are actively engaged in advanced software engineering methods, solve ambitious problem with software and are open to cutting-edge innovation? Attend this conference, meet people that share your goals, and get to know the best software tools and technologies available today. We strive to offer a day full of new experiences and impressions that you can use to immediately improve your daily life as a software developer.
If you share our vision and want to contribute, submit a proposal for a talk or tutorial!
NOTE: The conference fee will be waived for presenters. Travel expenses will not be covered (for exceptions see “Speaker Grants”).
We are looking for talks about best-of-breed software technology, e.g.:
functional programming
persistent data structures and databases
event-based modelling and architecture
“fancy types” (dependent types, gradual typing, linear types, …)
formal methods for correctness and robustness
abstractions for concurrency and parallelism
metaprogramming
probabilistic programming
math and programming
controlled side effects
program synthesis
AI beyond vibecoding and chatbots
linked data
symbolic AI
next-generation IDEs
effective abstractions for data analytics
… everything really that isn’t mainstream, but you think should be
… including rough ideas that are worth discussing.
Presenters should provide the audience with information that is practically useful for software developers.
Challenges
Furthermore, we seek contributions on successful approaches for solving hard problems, for example:
bias in machine-learning systems
digital transformation in difficult settings
accessibility
systems with critical reliability requirements
ecologically sustainable software development
We’re especially interested in experience reports.
Other topics are also relevant, e.g.:
introductory talks on technical background
overviews of a given field
demos and how-tos
Organisation
Direct questions to konferenz at bobkonf dot de
Proposal deadline: November 17, 2025
Notification: December 5, 2025
Program: December 12, 2025
Speaker Grants
BOB has Speaker Grants available to support speakers from groups under-represented in technology. We specifically seek women speakers, speakers of color, and speakers who are not able to attend the conference for financial reasons.
ocp-indent 1.9.0
Archive: https://discuss.ocaml.org/t/ann-ocp-indent-1-9-0/17349/1
Nathan Rebours announced
Here at OCamlPro we’re happy to announce the (long awaited) release of ocp-indent.1.9.0.
The full release notes are available here if you want the detailed version.
1.9.0 contains mostly bug fixes, better and more consistent indentation of fun _ -> and |>, compatibility with cmdliner.1.3.0 and above (it works with 2.0.0) and a new utility tool: ocp-indent-gen-rules for those of you who would like to try ocp-indent in a dune fmt like workflow.
This last bit is documented here. This is a feature that some of us wanted internally at OCamlPro so we decided to ship it with the tool as an experiment. We’d really like to hear if this fits your ocp-indent usage so please don’t hesitate to try it out and give us some feedback.
We’re also interested in hearing how you use ocp-indent in general and what you expect from it. Reach out if you have any request!
We’ve also updated the repo to fit the more recent development standards. We migrated the test suite to dune cram tests and re-enabled them in opam. Hopefully this should make contributing to ocp-indent a smoother experience!
Also be aware that we’ll do our best to maintain ocp-indent more actively from now on.
We’d like to thank our external contributors for this release: @dbuenzli, @nojb, @bcc32 and @Julow.
Happy indenting!
Sketch.sh now supports OCaml 5.3.0
Archive: https://discuss.ocaml.org/t/ann-sketch-sh-now-supports-ocaml-5-3-0/17352/1
Javier Chávarri announced
The interactive OCaml sketchbook sketch.sh has added support for OCaml 5.3.0.
Support for 5.3.0
Storing and running sketches using the compiler version 5.3.0 is now possible, this functionality has been added to the already existing support for versions 4.06.1 and 4.13.1. This new version brings support for OCaml 5’s effect handlers and multicore capabilities. Since sketch.sh runs in the browser using JavaScript via js_of_ocaml, the multicore capabilities are simulated using continuation-passing style.
Here you can see a sketch showcasing effects: Effects Example - Sketch.sh.
While support for intermediate versions is technically possible, it will require adding a mechanism to support choosing the version of the compiler for the current sketch (see issue #375).
Existing sketches and forks
Previously existing sketches remain in their original compiler version, while newly created sketches will be on 5.3.0 by default. For now, the only way to "migrate" a sketch to a newer version of the compiler is by copying its content and pasting it in a new sketch.
Forked sketches inherit the compiler version of the upstream sketch.
Reporting features and issues
Please let us know in case you have a feature request, or if you encounter any issues or bugs. Also, don't hesitate to reach out via Reason Discord or Discuss DMs if you would like to contribute or participate in the project in some way. There are a lot of opportunities to do so, both on the frontend and backend sides.
OUPS meetup october 2025
Archive: https://discuss.ocaml.org/t/oups-meetup-october-2025/17353/1
ancolie announced
The next OUPS meetup will take place on Monday, 13th of October 2025. It will start at 6:30pm at the 4 place Jussieu in Paris. It will be in the in the Esclangon building (amphi Astier).
Please, register on meetup as soon as possible to let us know how many pizza we should order.
For more details, you may check the OUPS’ website .
Moreover, we'd like to announce that the organizing team moved to the OCaml Zulip. Feel free to contact us there if you'd like to suggest talks.
This time we’ll have the following talks:
What's the deal with modular implicits ? – Samuel Vivien
Modular implicits est une extension d'OCaml présentée en 2014 comme une solution à l'absence de type classe en OCaml. Cependant malgré l'ancienneté de cette proposition cette fonctionnalité n'est toujours pas disponible dans OCaml. Nous ferons un tour d'horizon de modular implicits pour rappeler comment cette fonctionnalité marche, ce qui as déjà été implémenté dans le compilateur mais aussi ce qu'il reste à faire ainsi que les problématiques liés au typage des implicites.
Flambda2: Abstractions without Cost – Guillaume Bury
Surprise.
After the talks there will be some pizzas offered by the OCaml Software Foundation and later on we’ll move to a pub nearby as usual.
New releases of Merlin (5.6) and OCaml-LSP (1.24.0)
Archive: https://discuss.ocaml.org/t/ann-new-releases-of-merlin-5-6-and-ocaml-lsp-1-24-0/17354/1
Xavier Van de Woestyne announced
We are pleased to announce new releases of Merlin (5.6-504 and 5.6-503) and OCaml-LSP (1.24.0, for 5.4, and 1.23.1)!
This release of Merlin offers, firstly, support for OCaml 5.4. It improves support for OpenBSD (for merlin-reader), improves typing recovery in the handling of mutual recursion, and adds a new feature to the protocol: locate-types. It works similarly to locate-type, except that it allows you to distinguish between several locatable types in an expression like this: (int, Foo.t) result enabling the location of: int, Foo.t and ('a, 'b) result. In addition, the Vim client has been fixed for the use of project-wide-occurrences.
The release of OCaml LSP also mainly concerns support for 5.4 and several bug fixes.
As with every version upgrade, we are eager to hear user feedback. Try out these new releases on your 5.4 switches and don't hesitate to report any issues you encounter (Merlin, OCaml LSP)!
Merlin Changelog
Merlin 5.6-504 (& 5.6-503)
merlin binary
Add locate-types command (#1951)
merlin library
Fix merlin_reader for OpenBSD (#1956)
Improve recovery of mutually recursive definitions (#1962, #1963, fixes #1953)
Support for OCaml 5.4 (#1974) (only for 5.6-504)
vim plugin
Fix error when :MerlinOccurrencesProjectWide fails to gather code previews (#1970)
test suite
Add more short-paths tests cases (#1904)
Other OCaml News
dlvr.it
OCaml
@ocaml.org
· 7d
OCaml.org: Introducing Backstage OCaml - Separate Feeds for Stable and Experimental Features
We're pleased to announce that OCaml.org now has dedicated RSS feeds and pages for stable and experimental announcements, introduced in PR #3278!
What's new:
* OCaml Changelog at ocaml.org/changelog — Official stable release announcements and updates from the OCaml compiler, OCaml infrastructure, and the OCaml Platform Tools
* Backstage OCaml at ocaml.org/backstage — Updates on experimental releases, work-in-progress, and opportunities to contribute to the development of the OCaml Platform and its infrastructure
This separation helps keep the main changelog focused on production-ready releases while providing a dedicated space for those interested in experimental work, early testing, and contributing to OCaml's development.
Both pages have their own RSS feeds, so you can subscribe to whichever matches your needs—or both!
We welcome your feedback as we continue improving OCaml.org.
dlvr.it
Reposted by OCaml
OCaml
@ocaml.org
· 7d
OCaml
@ocaml.org
· 7d
Backstage OCaml: You Can Try the Experimental Branch of Merlin That Uses Domains and Effects
The Merlin team is excited to share that you can now try out an experimental branch of Merlin that leverages OCaml 5's domains and effects! This is Merlin-domains, and we'd love for you to test it and share your feedback.
What is Merlin-domains?
Merlin-domains is an experimental branch that uses domains and effects to implement two optimisations to improve performance in large buffers: partial typing and cancellation.
As a reminder, Merlin is the editor service that powers OCaml's IDE features—if you're using the OCaml Platform extension with VS Code or ocaml-eglot with Emacs, you're already using Merlin under the hood through OCaml LSP Server.
Why This Matters
While Merlin has had relatively few performance complaints over the years, in some contexts like very large files, the parsing-typing-analysis mechanism could sometimes cause slowdowns. The experimental branch addresses this in a clever way.
When you run an analysis command on a very large file, the type-checker will progress up to the location that makes the analysis possible, run the analysis phase, return the result, and then continue typing the file. This separation is made possible through control flow management enabled by effects, with two domains interacting with each other.
The result? Analysis phases become much more efficient! This is a great example of migrating a regular OCaml application to take advantage of multicore.
Learn More at Lambda World
Want to understand the technical details? Sonja Heinze and Carine Morel will present their talk "When magic meets multicore - OCaml and its elegant era of parallelism" at Lambda World, where they'll dive into how this experimental branch works internally.
How to Test It
Currently, the branch is in its incubation phase. To test it, pin the branch in the switches where you want to experiment:
opam pin add https://github.com/ocaml/merlin#merlin-domains
Although this experimental branch passes the test suite, your feedback is very important to help collect potential bugs we may have missed. The team has added a Bug/Merlin-domains label to organize tickets related to this branch.
What's Next
The goal is for this branch to eventually become the main branch, so that all users can benefit from these improvements. The rest of the ecosystem depending on Merlin, including OCaml LSP Server, will be adapted to take full advantage of these new features.
We need you! Try out merlin-domains with your real-world OCaml projects and share your experience on the Discuss thread. Your testing and feedback will help shape the future of Merlin!
dlvr.it
OCaml
@ocaml.org
· 7d
Backstage OCaml: You Can Try the Experimental Branch of Merlin That Uses Domains and Effects
The Merlin team is excited to share that you can now try out an experimental branch of Merlin that leverages OCaml 5's domains and effects! This is Merlin-domains, and we'd love for you to test it and share your feedback.
What is Merlin-domains?
Merlin-domains is an experimental branch that uses domains and effects to implement two optimisations to improve performance in large buffers: partial typing and cancellation.
As a reminder, Merlin is the editor service that powers OCaml's IDE features—if you're using the OCaml Platform extension with VS Code or ocaml-eglot with Emacs, you're already using Merlin under the hood through OCaml LSP Server.
Why This Matters
While Merlin has had relatively few performance complaints over the years, in some contexts like very large files, the parsing-typing-analysis mechanism could sometimes cause slowdowns. The experimental branch addresses this in a clever way.
When you run an analysis command on a very large file, the type-checker will progress up to the location that makes the analysis possible, run the analysis phase, return the result, and then continue typing the file. This separation is made possible through control flow management enabled by effects, with two domains interacting with each other.
The result? Analysis phases become much more efficient! This is a great example of migrating a regular OCaml application to take advantage of multicore.
Learn More at Lambda World
Want to understand the technical details? Sonja Heinze and Carine Morel will present their talk "When magic meets multicore - OCaml and its elegant era of parallelism" at Lambda World, where they'll dive into how this experimental branch works internally.
How to Test It
Currently, the branch is in its incubation phase. To test it, pin the branch in the switches where you want to experiment:
opam pin add https://github.com/ocaml/merlin#merlin-domains
Although this experimental branch passes the test suite, your feedback is very important to help collect potential bugs we may have missed. The team has added a Bug/Merlin-domains label to organize tickets related to this branch.
What's Next
The goal is for this branch to eventually become the main branch, so that all users can benefit from these improvements. The rest of the ecosystem depending on Merlin, including OCaml LSP Server, will be adapted to take full advantage of these new features.
We need you! Try out merlin-domains with your real-world OCaml projects and share your experience on the Discuss thread. Your testing and feedback will help shape the future of Merlin!
dlvr.it
OCaml
@ocaml.org
· 8d
Attempting overlayfs with macFuse
It would be great if overlayFS or unionFS worked on macOS! Initially, I attempted to use DYLD_INTERPOSE, but I wasn’t able to intercept enough system calls to get it to work. However, macFuse provides a way to implement our own userspace file systems. Patrick previously wrote obuilder-fs, which implemented a per-user filesystem redirection. It would be interesting to extend this concept to provide an overlayfs-style implementation.
dlvr.it
OCaml
@ocaml.org
· 12d
File descriptors are not integers
There was a flurry of activity on ocaml-multicore/ocaml-uring this month leading to a release (ocaml/opam-repository#28604). ocaml-uring provides bindings to the Linux’s io_uring, which allows batching various syscalls to the kernel for it to execute out-of-order, and in parallel. Its principal use at the moment is for the high-performance Linux backend of Eio.
dlvr.it
OCaml
@ocaml.org
· 12d
OCaml Security Team Established
OCaml Security Response Team Established
There is now a dedicated Security Response Team (SRT) to handle vulnerability reports and coordinate security responses. If you discover a security issue in the OCaml compiler, runtime, standard library, or ecosystem tools, you can report it confidentially to the team.
* Report vulnerabilities: Email [email protected] or use a private GitHub issue for high-impact vulnerabilities
* Security page: ocaml.org/security provides full details on reporting and the team
* Security advisories: The OCaml Security Advisory Database documents known issues in OCaml libraries and tools
* Announcements: Subscribe to the ocsf-ocaml-security-announcements mailing list for notifications of new advisories
The SRT follows responsible disclosure practices, working with reporters to validate issues, develop fixes, and coordinate public disclosure timelines. This effort also helps OCaml developers and companies comply with emerging security regulations like the EU Cyber Resilience Act.
For more information, see the announcement on Discuss.
dlvr.it