OCaml Weekly News
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
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
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
Ppx_untype: An end to type errors in OCaml
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
Caqti 2.2.4 Release and Plans
"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:
- 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.
- The sqlite3 driver now supports the refined error causes (
- Fixes
- Fixed a memory leak in the fall-back implementation of the
populate
connection method which affects all except the postgresql drivers.
- Fixed a memory leak in the fall-back implementation of the
- 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).
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 (likeint
) under a parallelQ
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
, anddynamic
(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
, anddynamic_gen
which takes a function receiving a dialect descriptor and returns aCaqti_template.Query.t
instead of a string. The stable API used combinator operators for this. - There is now only a single
update for the magick-core-7
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.
gegl-0.4 _
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)
Dune 3.18
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.
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 callexecve
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)
- Support HaikuOS: don't call
- Added
- Add
(format-dune-file <src> <dst>)
action. It provides an alternative to thedune format-dune-file
command. (#11166, @nojb)- Allow the
--prefix
flag when configuring dune withocaml 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)
- Allow the
- Add
- 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
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
'smax_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
andQCheck{,2}.Gen.graft_corners
about internal state, and fix a range of documentation reference warnings - Reorganize and polish the
README
, rewrite it to useqcheck-core
, and add aQCheck2
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
.
Outreachy December 2024 Round
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:
OUPS meetup april 2025
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.
Other OCaml News
From the ocaml.org blog
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.