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: 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: Roguetype ═════════ Archive: 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] Ppx_untype: An end to type errors in OCaml ══════════════════════════════════════════ Archive: 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: 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] [here] [1998 paper] [This discussion] Caqti 2.2.4 Release and Plans ═════════════════════════════ Archive: "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] ◊ 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] ◊ 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] 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: 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-gen] gegl-0.4 _ ══════════ Archive: 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] [api-doc] Dune 3.18 ═════════ Archive: 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] 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] ◊ Added • Add `(format-dune-file )' 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: Jan Midtgaard announced ─────────────────────── FYI, QCheck 0.25 is now available from the opam repository :smiley: 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: 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'] [`S.of_generic'] [`S.of_generic_exn'] Outreachy December 2024 Round ═════════════════════════════ Archive: 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] [ocaml-api-watch] OUPS meetup april 2025 ══════════════════════ Archive: 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 ] [OUPS’ website ] [OCaml Software Foundation] 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] [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!] 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] [the archive] [RSS feed of the archives] [caml-list] [Alan Schmitt]