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

Alan Schmitt
2025-04-08T13:14:26Z

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

Hello

Here is the latest OCaml Weekly News, for the week of April 01 to 08,
2025.

Please note that some entries were posted on April 1st.

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

Ocsigen public meeting
Roguetype
Ppx_untype: An end to type errors in OCaml
Second of Two Lessons on Polymorphic Variants: Practical Usecases
Caqti 2.2.4 Release and Plans
update for the magick-core-7
gegl-0.4 _
Dune 3.18
QCheck 0.24
checked_oint v0.5.0: Safe integer arithmetic for OCaml
Outreachy December 2024 Round
OUPS meetup april 2025
Other OCaml News
Old CWN

Ocsigen public meeting
══════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-ocsigen-public-meeting/16408/1>

William Caldwell announced
──────────────────────────

Hi all!

The Ocsigen team is organising a public meeting in which we'll be
discussing the migration from Lwt to effect-based concurrency, updates
about work in progress (wasm_of_ocaml, Ocsigen-i18n, …).

We welcome user suggestions & questions, please join us Monday the
14th of April at 1pm (France/GMT+2) at the following link:
<https://meet.google.com/zdm-krfj-rcw>

Roguetype
═════════

Archive: <https://discuss.ocaml.org/t/ann-roguetype/16409/1>

octachron announced
───────────────────

Have you ever felt pained by the lack of GADTs and high-arity functors
when playing games? Have you ever wondered if you could play games
without being weighted by a runtime evaluation?

Then fear no longer, because in this day it is my pleasure to announce
the first release of [Roguetype], the first ever roguelike written in
the OCaml type system:

• Test your mettle against the OCaml typechecker and the 8 levels of
`roguetype'.
• Explore functors, mountains, and forests to discover hidden paths.
• Vanquish goblins and dragon(s), upgrade your equipment, while being
sure that your travel is well-typed by construction.
• And maybe, at the end of your adventure, you shall prove that the
victory type is inhabited

[Roguetype] <https://github.com/Octachron/roguetype.git>

Ppx_untype: An end to type errors in OCaml
══════════════════════════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-ppx-untype-an-end-to-type-errors-in-ocaml/16410/1>

Paul-Elliot announced
─────────────────────

Hello dear people reading this!

Today, I am overly excited to announce one of the greatest and
simplest tool, that will fix the biggest of all OCaml flaws.

Consider Javascript:

┌────
│ $ node
│ Welcome to Node.js v22.14.0.
│ Type ".help" for more information.
│ > 1 + 3.5
│ 4.5
└────

Simple and elegant, don't we all agree?

Now, the same with OCaml:

┌────
│ $ ocaml
│ OCaml version 5.3.0
│ Enter #help;; for help.
│ # 1 + 3.5 ;;
│ Error: The constant 3.5 has type float but an expression was expected of type
│ int
└────

What does this even mean?

The PPX that I lovingly share with you all is `ppx_untype'. It finally
fully removes the OCaml type system that has plagued it since its
inception.

The PPX can be used very simply. Add it to your opam switch:

┌────
│ $ opam pin add ppx_untype https://github.com/panglesd/ppx_untype.git\#main
└────

and then add it to your `dune' (or other build system) file:

┌────
│ (...
│ (preprocess (pps ppx_untype))
│ ...)
└────

And you can now enjoy OCaml!

┌────
│ $ cat bin.main.ml
│ let () = print_float (1 + 3.5)
│ $ dune exec bin/main.exe
│ 3.47922429887e-310
└────

Pros:
╌╌╌╌╌

• All programs that was working before, still works.
• Blazingly fast!
• Finally integers and floats can be added.
• All warnings are also removed.

Cons:
╌╌╌╌╌

• None (apart from some unexpected behaviour at runtime)

Second of Two Lessons on Polymorphic Variants: Practical Usecases
═════════════════════════════════════════════════════════════════

Archive:
<https://discuss.ocaml.org/t/second-of-two-lessons-on-polymorphic-variants-practical-usecases/16416/1>

Jakub Svec announced
────────────────────

This is the second of two lessons on polymorphic variants I've been
drafting for potential inclusion in the Lessons section of OCaml.org.

You can find the draft second lesson [here]. I appreciate any feedback
you may have.

The OCaml.org discussion of the first lesson can be found [here].

The goal of the first lesson was to introduce the foundational
knowledge for how polymorphic variants work (row polymorphism,
structural typing, upper bounds, lower bounds, …), their benefits and
drawbacks, how they relate to "ordinary" variants, their notation
(`\~', `>', `<', `#', …), and their behavior during type refinement.

I am grateful to everyone that provided feedback on the first
lesson. I incorporated most of the feedback into the lesson already,
but it is not yet complete. I've held off finalizing the first lesson
until this second lesson receives feedback, since there may be
significant structural changes to the first lesson depending on the
feedback received on this second part.

The objective of this second lesson is to demonstrate practical
usecases for polymorphic variants. Presently, it demonstrates seven
practical usecases of polymorphic variants, along with "ordinary"
variant equivalents for comparison.

The seven usecases were sourced from:

• Jacques Garrigue's [1998 paper]
• [This discussion] board on OCaml.org

Please consider this a rough draft. It does not include an
indroduction and conclusion, and every example has minimal narrative
supporting it.

The goal is to solicit feedback on the *selected examples*, the
*structure of the examples*, and to solicit *additional examples* if
these are insufficient.

If you have experience with specific usecases for polymorphic variants
that you feel would do a better job demonstrating specific usecases or
that demonstrate features not presented here, please let me know. If
you can supply a concise example with a quick overview I would be
grateful. If that does not work with your schedule, I can formulate an
example from a description and perhaps a github link if available.

For example, none of the usecases demonstrate explicit coercions. That
may be a useful example to include, however this was not mentioned in
the source material and am unsure how commonly it is employed by OCaml
developers.

Once this document's examples are locked down, I will consider the
following:

• Which lesson should be introduced first (demonstrations or
foundations)?
• Should the examples in this lesson be extracted into .ml files for
readers to clone like in some other lessons on the site?
• Should the two lessons be merged?
• Is the length excessive?
• Can any content be removed or extracted into a standalone lesson?

Once that is resolved, I will do a final pass on the lesson(s) and
make another request for feedback.

Once again, I want to express my gratitude to everyone willing to work
through these draft lessons, as well to those willing to provide
feedback.

Example Usecases:

• Monomorphic Usecases
• Overloaded Tags
• Compose with Result
• Transitioning from Ordinary to Polymorphic Variants in an API
• Polymorphic Variants with Phantom Types
• Functional Reactive Programming with Polymorphic Variants
• Encoding HTML in Hierarchical Structures

[here] <https://hackmd.io/@wqo57Le0RIyZVlb8qdJ8PA/ryPD_7961x>

[here]
<https://discuss.ocaml.org/t/new-lesson-on-polymorphic-variants/16390/11>

[1998 paper]
<https://caml.inria.fr/pub/papers/garrigue-polymorphic_variants-ml98.pdf>

[This discussion]
<https://discuss.ocaml.org/t/is-there-any-kind-of-guidline-about-when-to-use-polymorphic-variants/11006/14>

Caqti 2.2.4 Release and Plans
═════════════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-caqti-2-2-4-release-and-plans/16419/1>

"Petter A. Urkedal announced
────────────────────────────

The Release
╌╌╌╌╌╌╌╌╌╌╌

I am pleased to announce the release of [Caqti] 2.2.4, after stumbling
through a few minor releases starting at 2.2.0. These are the
combined release notes since the previous OPAM release, omitting
intermediate regressions:

[Caqti] <https://github.com/paurkedal/ocaml-caqti>

◊ Improvements

• The sqlite3 driver now supports the refined error causes
(`Caqti_error.cause') for integrity constraint violations.
• There is now experimental support for Miou ([#117] by Calascibetta
Romain).
• Make the pool implementation shared-memory safe.
• The new library `caqti.template' provides a preview of a interface
for creating and working with request templates, with a few new
features and, I think, a tidier design. This is not yet suitable
for production code, since it will change before the final version.
Feedback is welcome.

[#117] <https://github.com/paurkedal/ocaml-caqti/pull/117>

◊ Fixes

• Fixed a memory leak in the fall-back implementation of the
`populate' connection method which affects all except the postgresql
drivers.

◊ Deprecations

• `Caqti_request.query_id' is deprecated and will be removed.
• Constructors of `Caqti_type.t' are now fully private and will be
moved away and likely defined differently in the next major release.

◊ Dependency Updates

• Prepare for upcoming mirage ([#124] by Hannes Mehnert).

[#124] <https://github.com/paurkedal/ocaml-caqti/pull/124>

Upcoming Work on `caqti.template'
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

As mentioned, this library is experimental for now, yet it contains
the real implementation of request templates, while the stable API is
a backwards compatible wrapper. I already have plans for revising the
new API both due to hard requirements and feedback about usability and
preferences, esp. for the most commonly used part of the API.

◊ Dynamic Prepare Policy and Parametric Types

One thing I am excited about with the `caqti.template' library is the
support for prepared queries for dynamically generated request
templates.

To motivate this, note that each prepared query retains resources on
both the server side and locally, both associated with an open
database connection, which can be long-lived. So, if the application
generates queries based on e.g. search expressions like `(author:Plato
or author:Socrates) and topic:epistemology', which cannot be prepared
statically due to the boolean algebra over search terms, then users of
the current API must use one-shot (non-prepared) queries to avoid
unbounded retention of resources over time. The new API provides a
so-called dynamic prepare policy, which uses an LRU cache of prepared
queries internally to limit the resource usage while providing a
heuristic for re-using common prepared queries.

There is, however, a missing piece in order for this to be practically
efficient. Type descriptors like `Caqti_type.t2', `Caqti_type.t3',
etc. which represent parametrically polymorphic types, are currently
generative with respect to the equality used by the LRU cache, meaning
that the type expression would need to be lifted out of the function
which generates the request template in order to avoid consistent
cache-misses.

My plan is first to make a major release which moves the concrete type
representation away from the public modules, and then revise it to
properly encode parametric types. Apart from changing the
constructors, this involves adding an extra phantom type parameter,
but the parameter will be universally qualified in the type exposed to
the public API, so I expect to retain backwards compatibility for
typical usage.

◊ The Main Request Template API and Bring-Your-Own-Paint

For most use cases, it is sufficient to be able to construct request
templates, which consists of type descriptors and a possibly
dialect-dependent query template. Everything needed for this is
bundled into the module `Caqti_template.Create'. I may have developed
a bit colourblindness after walking around this bikeshed, so let me
show you how the current stable API looks like, how the current
iteration of the new API looks like.

Here is a request template using the stable API:
┌────
│ let select_owner =
│ let open Caqti_request.Infix in
│ let open Caqti_type.Std in
│ (string ->? string)
│ "SELECT owner FROM bikereg WHERE frameno = ?"
└────

In the current iteration of the new API, this looks like:
┌────
│ let select_owner =
│ let open Caqti_template.Create in
│ static T.(string -->? string)
│ "SELECT owner FROM bikereg WHERE frameno = ?"
└────

What changed?

• There is now only a single `open'. That can only be good.
• The type descriptors have been moved under a `T' sub-module. This
isn't strictly necessary, but I though it was tidier, esp. since
there are clashing names (like `int') under a parallel `Q'
sub-module which is used for dynamically generated query templates.
• The arrow was previously the main function, while in the new API it
only constructs the type and multiplicity representation
(`Caqti_template.Request_type.t').
• Instead, the main function now indicates the policy for whether to
use a prepared query and, if so, the life-time of the request
template. The options are `direct', `static', and `dynamic' (as
explained above).

The latter adds verbosity, but I think it is good to be explicit about
static life-time, since using it for generated request templates would
typically lead to a resource leakage.

It's getting late, so I will not write about dynamic and
dialect-dependent request templates, but in the current revision, they
are constructed with a "general" version of the above functions,
`direct_gen', `static_gen', and `dynamic_gen' which takes a function
receiving a dialect descriptor and returns a `Caqti_template.Query.t'
instead of a string. The stable API used combinator operators for
this.

update for the magick-core-7
════════════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-update-for-the-magick-core-7/16422/1>

Florent Monnier announced
─────────────────────────

An update to use the magick-core-7 is available there:
[https://github.com/fccm2/mgk-gen2]

If you still want to use the magick-core-6, the previous head is kept
here: [https://github.com/fccm2/mgk-gen]

The updated version was tested with the magick-core version
`7.1.1-44', if you want to compile it, you need about `256M' space
left on device.

[https://github.com/fccm2/mgk-gen2] <https://github.com/fccm2/mgk-gen2>

[https://github.com/fccm2/mgk-gen] <https://github.com/fccm2/mgk-gen>

gegl-0.4 _
══════════

Archive: <https://discuss.ocaml.org/t/ann-gegl-0-4/16424/1>

Florent Monnier announced
─────────────────────────

You can now access `gegl-0.4', from your favorite scripting language,
and play with its nodes, with: [https://github.com/fccm2/gegl-ocaml] /
([api-doc])

[https://github.com/fccm2/gegl-ocaml]
<https://github.com/fccm2/gegl-ocaml>

[api-doc] <http://decapode314.free.fr/ocaml/gegl/docs/0.01/Gegl.html>

Dune 3.18
═════════

Archive: <https://discuss.ocaml.org/t/ann-dune-3-18/16428/1>

Etienne Marais announced
────────────────────────

On the behalf of the dune team, I'm glad to announce the release of
dune `3.18.0' :partying_face:

This release contains changes to support the new
`x-maintenance-intent' field by default. It also contains some changes
regarding the cache, about how it handles file permissions. It
introduces a new `(format-dune-file ...)' stanza with the intention to
formalize the `dune format-dune-file' command as an inside
rule. Finally, it includes various bug fixes for Dune.

If you encounter a problem with this release, you can report it on the
[ocaml/dune] repository.

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

Changelog
╌╌╌╌╌╌╌╌╌

◊ Fixed

• Support HaikuOS: don't call `execve' since it's not allowed if other
pthreads have been created. The fact that Haiku can't call `execve'
from other threads than the principal thread of a process (a team in
haiku jargon), is a discrepancy to POSIX and hence there is a [bug
about it]. (@Sylvain78, #10953)

• Fix flag ordering in generated Merlin configurations (#11503,
@voodoos, fixes ocaml/merlin#1900, reported by @vouillon)

[bug about it] <https://dev.haiku-os.org/ticket/18665>

◊ Added

• Add `(format-dune-file <src> <dst>)' action. It provides an
alternative to the `dune format-dune-file' command. (#11166, @nojb)

• Allow the `--prefix' flag when configuring dune with `ocaml
configure.ml'. This allows to set the prefix just like `$ dune
install --prefix'. (#11172, @rgrinberg)

• Allow arguments starting with `+' in preprocessing definitions
(starting with `(lang dune 3.18)'). (@amonteiro, #11234)

• Support for opam `(maintenance_intent ...)' in dune-project
(#11274, @art-w)

• Validate opam `maintenance_intent' (#11308, @art-w)

• Support `not' in package dependencies constraints (#11404, @art-w,
reported by @hannesm)

◊ Changed

• Warn when failing to discover root due to reads failing. The
previous behavior was to abort. (@KoviRobi, #11173)

• Use shorter path for inline-tests artifacts. (@hhugo, #11307)

• Allow dash in `dune init' project name (#11402, @art-w, reported by
@saroupille)

• On Windows, under heavy load, file delete operations can sometimes
fail due to AV programs, etc. Guard against it by retrying the
operation up to 30x with a 1s waiting gap (#11437, fixes #11425,
@MSoegtropIMC)

• Cache: we now only store the executable permission bit for files
(#11541, fixes #11533, @ElectreAAS)

• Display negative error codes on Windows in hex which is the more
customary way to display `NTSTATUS' codes (#11504, @MisterDA)

QCheck 0.24
═══════════

Archive: <https://discuss.ocaml.org/t/ann-qcheck-0-24/16198/2>

Jan Midtgaard announced
───────────────────────

FYI, QCheck 0.25 is now available from the opam repository :smiley:

<https://github.com/c-cube/qcheck/releases/>

The 0.25 release contains a combination of all-round fixes,
documentation, and polishing:

• Restore `Test.make''s `max_fail' parameter which was accidentally
broken in 0.18
• Adjust `stats' computation of average and standard deviation to
limit precision loss, print both using scientific notation, and
workaround MinGW float printing to also pass expect tests
• Fix dune snippets missing a language specifier in README.adoc
causing `asciidoc' to error
• Add a note to `QCheck{,2.Gen}.small_int_corners' and
`QCheck{,2}.Gen.graft_corners' about internal state, and fix a range
of documentation reference warnings
• Reorganize and polish the `README', rewrite it to use `qcheck-core',
and add a `QCheck2' integrated shrinking example
• Document `QCHECK_MSG_INTERVAL' introduced in 0.20
• Add `QCheck{,2}.Gen.map{4,5}' combinators

The accompanying `ppx_deriving_qcheck.0.7' release offers:

• Support `ppxlib.0.36.0' based on the OCaml 5.2 AST

Thanks to @Pat-Lafon and @patricoferris for contributing PRs! 🎉

Happy testing! :smiley: :keyboard:

checked_oint v0.5.0: Safe integer arithmetic for OCaml
══════════════════════════════════════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-checked-oint-v0-5-0-safe-integer-arithmetic-for-ocaml/16450/1>

hirrolot announced
──────────────────

I would like to announce [`checked_oint'] v0.5.0, which provides
checked integer arithmetic for OCaml. We support both signed and
unsigned integers of 8, 16, 32, 64, and 128 bits. Unlike other
libraries, `checked_oint' either returns an option or raises an
exception when the result of an arithmetic operation cannot be
represented in a desired integer type.

In addition, it contains abstractions for manipulating arbitrary
integers and integer types in a generic and type-safe manner, which I
find tremendously useful for compiler/interpreter implementations.

Usage example:

┌────
│ open Checked_oint
│
│ let () =
│ let x = U8.of_int_exn 50 in
│ let y = U8.of_int_exn 70 in
│ assert (U8.equal (U8.add_exn x y) (U8.of_int_exn 120));
│ assert (Option.is_none (U8.mul x y))
└────

The release v0.5.0 introduced crucial functionality for converting
between any two integer types in a safe manner – see [`S.of_generic']
and [`S.of_generic_exn'].

[`checked_oint'] <https://github.com/hirrolot/checked_oint>

[`S.of_generic']
<https://hirrolot.github.io/checked_oint/checked_oint/Checked_oint/module-type-S/index.html#val-of_generic>

[`S.of_generic_exn']
<https://hirrolot.github.io/checked_oint/checked_oint/Checked_oint/module-type-S/index.html#val-of_generic_exn>

Outreachy December 2024 Round
═════════════════════════════

Archive:
<https://discuss.ocaml.org/t/outreachy-december-2024-round/15223/3>

Patrick Ferris announced
────────────────────────

With the [June 2025 round] about to begin, it is time to celebrate the
awesome work @abdulaziz.alkurd has been doing on [ocaml-api-watch]
mentored by @NathanReb and @panglesd!

Please join us on [date=2025-04-15 time=10:00:00 timezone="UTC"] for
the community zoom call where we will get to hear about all of the
progress that has been made.

Hope to see you there. I'll post a link to the video call closer to
the time. For those that can't make it, the meeting will be recorded
and uploaded to watch.ocaml.org :two_hump_camel:

[June 2025 round]
<https://discuss.ocaml.org/t/outreachy-june-2025/16154>

[ocaml-api-watch] <https://github.com/ocaml-semver/ocaml-api-watch>

OUPS meetup april 2025
══════════════════════

Archive: <https://discuss.ocaml.org/t/oups-meetup-april-2025/16453/1>

zapashcanon announced
─────────────────────

CAUTION: the time has been changed from 7pm to 6:30pm and it will be
at ENS Ulm instead of Jussieu

The next OUPS meetup will take place on *Thursday, 24th of April*
2025. It will start at *6:30pm* at the *45 rue d'Ulm* in Paris. It
will be in the in the *Salle des résistants* (first floor in the
"couloir du carré").

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

This time we’ll have the following talks:

*A translation of OCaml programs from Gospel to Viper – Charlène Gros*

Presentation of a translation of OCaml programs specified
in Gospel into Viper, an intermediate verification
language supporting separation logic.

The practical goal is to add a new backend to Cameleer to
verify OCaml programs that manipulate the heap. The
logical specification of such OCaml programs is described
in the Gospel language, and we detail the extensions made
to support separation logic in Viper.

*Posca: an experimental social network based on Matrix, written in
OCaml with melange – Pierre de Lacroix*

TBA

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.

[register on meetup ]
<https://www.meetup.com/fr-FR/ocaml-paris/events/307176170>

[OUPS’ website ] <https://oups.frama.io>

[OCaml Software Foundation] <https://ocaml-sf.org>

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

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

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

• [What's new with Mollymawk?]
• [Learning OCaml: Module Aliases]
• [Learning OCaml: Parsing Data with Scanf]
• [Learning OCaml: Regular Expressions]
• [Making OCaml Safe for Performance Engineering]
• [OCaml in Space: SpaceOS is on a Satellite!]

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

[What's new with Mollymawk?]
<https://blog.robur.coop/articles/mollymawk-first-milestone.html>

[Learning OCaml: Module Aliases]
<https://batsov.com/articles/2025/04/06/learning-ocaml-module-aliases/>

[Learning OCaml: Parsing Data with Scanf]
<https://batsov.com/articles/2025/04/06/learning-ocaml-parsing-data-with-scanf/>

[Learning OCaml: Regular Expressions]
<https://batsov.com/articles/2025/04/04/learning-ocaml-regular-expressions/>

[Making OCaml Safe for Performance Engineering]
<https://www.youtube.com/watch/g3qd4zpm1LA?version=3>

[OCaml in Space: SpaceOS is on a Satellite!]
<https://tarides.com/blog/2025-04-03-ocaml-in-space-spaceos-is-on-a-satellite>

Old CWN
═══════

If you happen to miss a CWN, you can [send me a message] and I'll mail
it to you, or go take a look at [the archive] or the [RSS feed of the
archives].

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

[Alan Schmitt]

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

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

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

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

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

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