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

Alan Schmitt
2024-12-03T14:44:18Z

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

Hello

Here is the latest OCaml Weekly News, for the week of November 26 to
December 03, 2024.

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

Good example of handwritten Lexer + Recursive Descent Parser?
Boulder Dash in OCaml
Js_of_ocaml 5.9.0
Liquidsoap 2.3.0
Bytesrw 0.1.0 – Composable byte stream readers and writers
dream-html and pure-html 3.5.2
Second beta release of OCaml 5.3.0
New release of Monolith
Jsont 0.1.0 – Declarative JSON data manipulation for OCaml
Tiny educational concurrent I/O and promises library
Eliom 11.1: Towards Web Assembly support
Areas and Adversaries
MariaDB 1.2.0
Proposed Package Archiving Policy for the opam Repository
capnp-rpc 2.0
Other OCaml News
Old CWN

Good example of handwritten Lexer + Recursive Descent Parser?
═════════════════════════════════════════════════════════════

Archive:
<https://discuss.ocaml.org/t/good-example-of-handwritten-lexer-recursive-descent-parser/15672/1>

Axel Baudot asked
─────────────────

I am looking for an idiomatic implementation of a Lexer + Recursive
Descent Parser not making use of ocamllex, ocamlyacc or menhir. The
kind you would write during the first chapters of Crafting
Interpreters [0][1] in OCaml.

This Markdown parser [2] by @dbuenzli is a great example of what I am
looking for. I'd be happy if you can recommend similar resources.

There are many OCaml repos for Lox interpreters but it's hard to
assess quality. And the readme often says "I am doing this to learn
OCaml", which doesn't inspire confidence.

As a broader note, it would be nice to have (community vetted) OCaml
translations of well-known learning material using mainstream
languages. But I'll raise the topic in another thread later.

Thanks in advance.

• [0] <https://craftinginterpreters.com/scanning.html>
• [1] <https://craftinginterpreters.com/parsing-expressions.html>
• [2]
<https://github.com/dbuenzli/cmarkit/blob/af8930c307957a546ea833bbdabda94a2fa60b4b/src/cmarkit.ml#L879>

Mikhail replied
───────────────

You might be interested in the book [Compiling to Assembly from
Scratch]. There is a [port to OCaml]. It suggests the use of [parser
combinators].

Parser combinators is the same manual recursive descent method, but in
a functional way. You can either use [an existing library] or you
[can write your own].

[Compiling to Assembly from Scratch]
<https://keleshev.com/compiling-to-assembly-from-scratch/>

[port to OCaml]
<https://github.com/keleshev/compiling-to-assembly-from-scratch/tree/main/contrib/ocaml>

[parser combinators] <https://en.wikipedia.org/wiki/Parser_combinator>

[an existing library] <https://github.com/inhabitedtype/angstrom>

[can write your own] <https://www.youtube.com/watch?v=Y5IIXUBXvLs>

Anton Bachin also replied
─────────────────────────

odoc's parser is half of what you're asking for. It uses ocamllex for
the lexical scan, because it's very simple and convenient to do it
that way, but the syntax is then analyzed by a hand-written [recursive
descent parser], in large part because /that's/ easier for the doc
language.

An example of a non-ocamllex and non-ocamlyacc parser is Markup.ml
([tokenizer], [parser]). But this isn't a traditional recursive
descent parser. Rather, it's a pretty huge hand-written state machine
in continuation-passing style, almost completely implementing the
corresponding huge state machine specified in HTML5. But it's the kind
of code that fits well the topics of an impure FP class, especially
since it has mutable cells for its continuations, that it uses to
mimic effects.

[recursive descent parser]
<https://github.com/ocaml/odoc/blob/822d266232fccdffbd4922434c81c45ab6d583f4/src/parser/syntax.ml>

[tokenizer]
<https://github.com/aantron/markup.ml/blob/d686cce6bac6ff46a49b28ed0d957ffa1e37fda5/src/html_tokenizer.ml#L390>

[parser]
<https://github.com/aantron/markup.ml/blob/d686cce6bac6ff46a49b28ed0d957ffa1e37fda5/src/html_parser.ml#L1386>

Boulder Dash in OCaml
═════════════════════

Archive:
<https://sympa.inria.fr/sympa/arc/caml-list/2024-11/msg00023.html>

Continuing this thread, Andreas Rossberg announced
──────────────────────────────────────────────────

Couldn’t let it rest, so I’m (already) announcing version 2 of it —
now a much improved, practically feature-complete reimplementation of
both Boulder Dash 1 & 2.

Version 2 was an excuse for me to mess around with the OCaml bindings
to popular graphics engines, and as a result, it now comes with 3
backends to choose from:

1. the homely bare OCaml Graphics library
(<https://github.com/ocaml/graphics>),
2. the TSDL binding to the SDL2 API
(<https://github.com/dbuenzli/tsdl>),
3. the binding to the Raylib engine
(<https://github.com/tjammer/raylib-ocaml>).

The list is in order of increasingly better user experience, for the
price of a potentially harder build experience. In theory, all
versions should run on Windows, Mac, and Linux, though I was too lazy
to test all combinations, and I (or my opam) had trouble installing
some of the dependencies on some of the systems.

Features:

• Faithful original physics, graphics, animations, sound, and music
• Authentic scrolling mechanics combined with dynamic resizing
• All 40 levels and 5 difficulties of Boulder Dash 1 & 2
• Pause-and-go mode for relaxed playing

Relative to the previous release, version 2 adds the following
niceties:

• Support for SDL and Raylib engines, which allow all of the following
• Original sound effects and music
• Original level color schemes
• Full screen mode
• Faster graphics
• Dynamic graphics scaling adjustment
• Gamepad/joystick support as well as more precise keyboard controls
• Boulder Dash 2 levels and decoder

Almost looks like a real game now. One from the 80s anyways. :)

Js_of_ocaml 5.9.0
═════════════════

Archive: <https://discuss.ocaml.org/t/ann-js-of-ocaml-5-9-0/15674/1>

Hhugo announced
───────────────

I’m pleased to announce the release of js_of_ocaml 5.9.0. It should
soon be available in opam.

Js_of_ocaml is a compiler from OCaml bytecode to JavaScript. It makes
it possible to run pure OCaml programs in JavaScript environment like
browsers and Node.js.

Most significant changes:

• Support for OCaml 5.3
• Speedup sourcemap generation and improve sourcemap accuracy.
• Prepare the merge of the wasm_of_ocaml fork back into the
js_of_ocaml repo.
• JS backtraces are really expansive. They now need to be explicitly
requested with `OCAMLRUNPARM=b=1'. This speeds up programs linked
with libraries enabling backtraces programmatically using
`Printexc.record_backtrace true'.

See the [Changelog ] for other changes.

[Changelog ]
<https://github.com/ocsigen/js_of_ocaml/blob/master/CHANGES.md>

Liquidsoap 2.3.0
════════════════

Archive: <https://discuss.ocaml.org/t/ann-liquidsoap-2-3-0/15677/1>

Romain Beauxis announced
────────────────────────

We are stoked to announce the `2.3.0' release of liquidsoap, a
general-purpose scripting language written in OCaml with specialized
operators to build media streams.

The release is available on github:
<https://github.com/savonet/liquidsoap/releases/tag/v2.3.0>

During this release cycle, we have rewritten huge chunk of the
application's internal, including a new media streaming abstraction
and clock system.

As an OCaml application, liquidsoap's scope and complexity has greatly
expanded in the next years.

Some of the most challenging areas for us at this point are memory
usage (and, incidentally, CPU usage).

Although OCaml's garbage collection is a very powerful tool, in the
context of very short lived streaming cycles (typically `0.02s') with
potentially quite large memory allocations (typically video images),
controlling the timing of memory allocations and release is becoming
more and more critical.

We are also aware of the work done by Jane St on adding a `local' call
stack. This could be an avenue to explore as well but:
1. Some of our content has to be stored in the long-term heap
2. We want to work with an official OCaml compiler for obvious
long-term maintenance concerns.

Nonetheless, we are thrilled to be part of a community whose array of
tools (building, packaging, debugging, etc) and libraries has expanded
so well along with a vibrant compiler development team.

In the future, we wish to explore more of the new OCaml concurrency
features. This might require that we revisit the way we handle
short-term memory first.

Bytesrw 0.1.0 – Composable byte stream readers and writers
══════════════════════════════════════════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-bytesrw-0-1-0-composable-byte-stream-readers-and-writers/15696/1>

Daniel Bünzli announced
───────────────────────

It's my pleasure to announce the first release of the `bytesrw'
library:

Bytesrw extends the OCaml `Bytes' module with composable,
memory efficient, byte stream readers and writers
compatible with effect-based concurrency.

Except for byte slice life-times, these abstractions
intentionally separate away ressource management and the
specifics of reading and writing bytes.

Bytesrw distributed under the ISC license. It has no
dependencies.

Optional support for compressed and hashed bytes depend,
at your wish, on the C [`zlib'], [`libzstd'], [`blake3'],
[`libmd'], [`xxhash'] and libraries.

The only reason I was longing for OCaml algebraic effects was so that
I could avoid using them: when you write codecs on byte streams it
should not be a concern where your bytes are coming from or headed
to. The `bytesrw' library provides structures to abstract
this. Additionally it establishes a buffer ownership discipline that
enables byte streams to (de)compose while remaining memory efficient.

I do not expect the library to change much and it has been used. But
it's new and practice may call for adjustments. Do not hesitate to get
in touch if you run into problems or see obvious defects or
improvements. I do expect the library will add more convenience
(e.g. for processing lines and UTF) and more optional stream formats
over time.

• Homepage: <https://erratique.ch/software/bytesrw>
• Docs: <https://erratique.ch/software/bytesrw/doc> or `odig doc
bytesrw'
• Install: `opam install bytesrw conf-zlib conf-zstd conf-libblake3
conf-libmd conf-xxhash' ([opam PR])

This first release was made possible thanks to a grant from the [OCaml
Software Foundation]. I also thank my [donors] for their support.

[`zlib'] <https://zlib.net>

[`libzstd'] <http://zstd.net>

[`blake3'] <https://blake3.io>

[`libmd'] <https://www.hadrons.org/software/libmd/>

[`xxhash'] <https://xxhash.com/>

[opam PR] <https://github.com/ocaml/opam-repository/pull/26990>

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

[donors] <https://github.com/sponsors/dbuenzli>

dream-html and pure-html 3.5.2
══════════════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-dream-html-pure-html-3-5-2/14808/5>

Yawar Amin announced
────────────────────

[ANN] dream-html 3.7.0

Happy to announce the addition of a helper module for typed form
decoding functionality. See the docs here:
<https://yawaramin.github.io/dream-html/dream-html/Dream_html/Form/index.html>

An example:

┌────
│ type user = { name : string; age : int option }
│
│ open Dream_html.Form
│
│ let user_form =
│ let+ name = required string "name"
│ and+ age = optional int "age" in
│ { name; age }
│
│ let dream_form = ["age", "42"; "name", "Bob"]
│ let user_result = validate user_form dream_form
│ (* => Ok { name = "Bob"; age = Some 42 } *)
│
│ let error_result = validate user_form ["age", "none"]
│ (* => Error [("age", "error.expected.int"); ("name", "error.required")] *)
└────

Astute readers may observe that this provides some convenience
functionality beyond what Dream itself offers; to validate the above
form and get a _complete_ set of field validation errors using only
Dream you would do something like:

┌────
│ let user_result = match dream_form with
│ | ["age", age; "name", name] ->
│ (match int_of_string age with
│ | age -> Ok { name; age = Some age }
│ | exception Failure _ -> Error ["age", "error.expected.int"])
│ | ["name", name] -> Ok { name; age = None }
│ | ["age", age] ->
│ (match int_of_string age with
│ | age -> Error ["name", "error.required"]
│ | exception Failure _ -> Error ["age", "error.expected.int"; "name", "error.required"])
│ | _ -> Error ["name", "error.required"]
└────

And this is a form with only two fields. You can imagine how
convoluted the logic would be for more complex forms. Of course, you
might just decide to use `List.assoc_opt' and build up the validation
errors, but even that can get tricky. So if you are making heavy use
of HTML forms, a helper module that takes care of all these validation
details can be very useful. Enjoy!

Second beta release of OCaml 5.3.0
══════════════════════════════════

Archive:
<https://discuss.ocaml.org/t/second-beta-release-of-ocaml-5-3-0/15700/1>

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

One month after the release of the first beta for OCaml 5.3.0, we are
releasing a second and hopefully last beta release for OCaml 5.3.0 .

The most notable changes for this second beta are probably a handful
of type system bugfixes. In particular, those fixes revert a change of
behaviour in the first beta when pattern matching GADTs with
non-injective type parameters.

We also have a C++ header compatibility fix and the restoration of
some configuration variable in Makefiles for the sake of backward
compatibility.

Overall, the release is converging and we are expecting to have a
first release candidate around the middle of December. The progresses
on stabilising the ecosystem are tracked on the [opam readiness for
5.3.0 meta-issue].

Meanwhile, the second beta release of OCaml 5.3.0 is here to help you
update your software and libraries ahead of the release (see below for
the installation instructions).

The full release is expected before the end of December.

If you find any bugs, please report them on [OCaml's issue tracker].

If you are interested in full list of features and bug fixes of the
new OCaml version, the updated change log for OCaml 5.3.0 is available
[on GitHub].

Happy hacking, Florian Angeletti for the OCaml team.

[opam readiness for 5.3.0 meta-issue]
<https://github.com/ocaml/opam-repository/issues/26596>

[OCaml's issue tracker] <https://github.com/ocaml/ocaml/issues>

[on GitHub] <https://github.com/ocaml/ocaml/blob/5.3/Changes>

Installation Instructions
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

The base compiler can be installed as an opam switch with the
following commands on opam 2.1 and later:

┌────
│ opam update
│ opam switch create 5.3.0~beta2
└────

The source code for the beta is also available at these addresses:

• [GitHub]
• [OCaml archives at Inria]

[GitHub] <https://github.com/ocaml/ocaml/archive/5.3.0-beta2.tar.gz>

[OCaml archives at Inria]
<https://caml.inria.fr/pub/distrib/ocaml-5.3/ocaml-5.3.0~beta2.tar.gz>

◊ 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.3.0~beta2+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.3.0~beta2+flambda+nffa ocaml-variants.5.3.0~beta2+options ocaml-option-flambda ocaml-option-no-flat-float-array
└────

All available options can be listed with `opam search ocaml-option'.

Changes Since The First Beta
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

◊ Type system fixes

• [#13501]: Regression on mutually recursive types caused by [#12180].
Resuscitate Typedecl.update_type. (Jacques Garrigue and Takafumi
Saikawa, review by Florian Angeletti, Richard Eisenberg and Gabriel
Scherer)

• [#13495], [#13514]: Fix typechecker crash while typing objects
(Jacques Garrigue, report by Nicolás Ojeda Bär, review by Nicolas
Ojeda Bär, Gabriel Scherer, Stephen Dolan, Florian Angeletti)

• [#13598]: Falsely triggered warning 56 [unreachable-case] This was
caused by unproper protection of the retyping function. (Jacques
Garrigue, report by Tõivo Leedjärv, review by Florian Angeletti)

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

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

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

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

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

◊ Configuration fixes

• (*breaking change*) [#12578], [#12589], [#13322], +[#13519]: Use
configured CFLAGS and CPPFLAGS /only/ during the build of the
compiler itself. Do not use them when compiling third-party C
sources through the compiler. Flags for compiling third-party C
sources can still be specified at configure time in the
COMPILER_{BYTECODE,NATIVE}_{CFLAGS,CPPFLAGS} configuration
variables. (Sébastien Hinderer, report by William Hu, review by
David Allsopp)

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

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

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

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

◊ C++ header compatibility

• [#13541], [#13591]: Fix headers for C++ inclusion. (Antonin Décimo,
review by Nick Barnes, report by Kate Deplaix)

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

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

◊ Compiler library bug fix

• [#13603], [#13604]: fix source printing in the presence of the
escaped raw identifier `\#mod'. (Florian Angeletti, report by Chris
Casinghino, review by Gabriel Scherer)

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

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

New release of Monolith
═══════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-new-release-of-monolith/15701/1>

François Pottier announced
──────────────────────────

I am pleased to announce a new release of [Monolith], a library that
helps perform strong automated testing of OCaml libraries.
┌────
│ opam update
│ opam install monolith.20241126
└────

The changes are as follows:

• The documentation of the specification combinators has been
re-organized in sections and subsections. Finding the desired
combinator should now be easier.

• The new combinator `naive_array' offers limited support for arrays.

• The new combinator `naive_seq' offers limited support for sequences
(that is, for the type constructor `Seq.t').

• The new combinator `pair' is a synonym for `( *** )'.

• The new combinator `triple' offers support for triples.

• The new combinator `either' offers support for the type constructor
`Either.t'.

• The new combinators `iter', `foldr', `foldl', `iteri', `foldri',
`foldli' offer support for iteration functions.

• An unintentional and undocumented limitation has been fixed: so far,
uses of the combinator `map_into' would work only at the root of the
specification or in the right-hand side of an arrow `^>'. It should
now be possible to use `map_into' under other combinators that
expect a deconstructible specification, such as `^!>' (in the
right-hand side), `( *** )', `option', `result', `list', etc. This
improvement affects not only `map_into', but also a number of other
combinators that are defined in terms of `map_into'.

• Monolith now requires OCaml 4.12 or later.

• In `Makefile.monolith',
⁃ the default switch is changed from 4.11.1 to 4.14.2; this can be
overridden by defining `SWITCH';
⁃ `make test' automatically disables the MacOS crash reporter;
⁃ the use of `ulimit -s' is abandoned.

[Monolith]
<https://cambium.inria.fr/~fpottier/monolith/doc/monolith/Monolith/>

Jsont 0.1.0 – Declarative JSON data manipulation for OCaml
══════════════════════════════════════════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-jsont-0-1-0-declarative-json-data-manipulation-for-ocaml/15702/1>

Daniel Bünzli announced
───────────────────────

It's my pleasure to announce the first release of the jsont libary:

Jsont is an OCaml library for declarative JSON data
manipulation. It provides:

• Combinators for describing JSON data using the OCaml
values of your choice. The descriptions can be used by
generic functions to decode, encode, query and update
JSON data without having to construct a generic JSON
representation.
• A JSON codec with optional text location tracking and
layout preservation. The codec is compatible with
effect-based concurrency.

The descriptions are independent from the codec and can be
used by third-party processors or codecs.

Jsont is distributed under the ISC license. It has no
dependencies. The codec is optional and depends on the
[`bytesrw'] library. The JavaScript support is optional
and depends on the [`brr'] library.

The library has been used in practice but it's new so a few
adjustments may be needed and more convenience combinators added.

The library also enables quite a few things that I did not have the
time to explore like schema description generation from descriptions,
quasi-streaming JSON transformations, description generation from
dynamic type representations, etc. Lots of this can be done outside
the core library, do not hesitate to get in touch if you use the
library and find interesting applications or pesking limitations.

• Homepage: <https://erratique.ch/software/jsont>
• Docs: <https://erratique.ch/software/jsont/doc> (or `odig doc
jsont')
• Install: `opam install jsont bytesrw'

This first release was made possible thanks to a grant from the [OCaml
Software Foundation]. I also thank my [donors] for their support.

Best,

Daniel

P.S. I think that the technique used by the library, which I dubbed
/finally tagged/ is interesting in itself. You can read a paper about
it [here] along with a smaller, self-contained, implementation of what
the library does.

[`bytesrw'] <https://erratique.ch/software/bytesrw>

[`brr'] <https://erratique.ch/software/brr>

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

[donors] <https://github.com/sponsors/dbuenzli>

[here] <https://github.com/dbuenzli/jsont/tree/main/paper>

Tiny educational concurrent I/O and promises library
════════════════════════════════════════════════════

Archive:
<https://discuss.ocaml.org/t/tiny-educational-concurrent-i-o-and-promises-library/15703/1>

Mikhail announced
─────────────────

I like [Lwt]. It's a fantastic library, but how does it work? I spent
a few days studying its source code.

Finally, inspired by the implementation of [Lwt] and [the CS3110
chapter, 8.7. Promises]. I wrote a maximally stupid [*tiny-async-lib*]
library.

Maybe you may be interested in this naive implementation.

[Lwt] <https://github.com/ocsigen/lwt>

[the CS3110 chapter, 8.7. Promises]
<https://cs3110.github.io/textbook/chapters/ds/promises.html>

[*tiny-async-lib*] <https://github.com/dx3mod/tiny-async-lib>

Examples of use
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

┌────
│ let () =
│ Engine.run main begin
│ let* () = Io.(write_all stdout) "Hi! What's your name? " in
│ let* name = Io.(read_line stdin) in
│ Io.(write_all stdout) ("Hello, " ^ name ^ "!\n")
│ end
└────

┌────
│ let read_and_print_file filename =
│ Io.(read_file filename >>= write_all stdout)
│
│ let _ =
│ Engine.run begin
│ let filenames = [ (* ... *) ] in
│
│ filenames
│ |> List.map read_and_print_file
│ |> Promise.join
│ end
└────

Implementation details
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

The first key abstraction of the whole library is, of course,
Promise. [Promise] is an abstraction for synchronizing program
execution in concurrent evaluations. In simple terms, it's an
abstraction over callbacks. Promises allows us to build (monadic)
sequence evaluations inside of non-sequence evaluations.

┌────
│ (* promise.ml *)
│
│ type 'a t = { mutable state: 'a state }
│
│ and 'a state =
│ | Fulfilled of 'a
│ | Rejected of exn
│ | Pending of 'a callback list
│
│ and 'a callback = 'a state -> unit
└────

Promises are represented as a mutable record with three possible
states: fulfilled (contains a value), rejected (contains an
exception), and pending (contains callbacks).

Callbacks are functions that are called when a promise is resolved.
So when we `bind', if the promise is in pending state, we add a
callback that calls the following monadic sequence when the promise is
resolved.

┌────
│ (* io.ml *)
│
│ let sleep delay =
│ let p, r = Promise.make () in
│
│ Engine.(on_timer instance) delay (fun handler ->
│ Engine.stop_handler handler;
│ Promise.fulfill r ());
│
│ p
└────

The second key abstraction is an [asynchronous I/O] engine that polls
I/O events and dispatches them to handlers. Original Lwt has few
engines (like based libev, select, poll), but I hardcoded a
[select](<https://en.wikipedia.org/wiki/Select_(Unix)>)-based engine
inspired by `Lwt_engine.select_based'.

The typical async engine in internals has an event loop. At each
iteration of the event loop, the engine polls for new events and calls
handlers to handle them.

┌────
│ (* engine.ml *)
│
│ let iter engine =
│ (* ... *)
│
│ let readable_fds, writable_fds, _ =
│ Unix.select readable_fds writable_fds [] timeout
│ in
│
│ engine.sleepers <- restart_sleepers now engine.sleepers;
│
│ invoke_io_handlers engine.wait_readable readable_fds;
│ invoke_io_handlers engine.wait_writable writable_fds
└────

How to execute I/O promise? It's not a big deal.
┌────
│ (* engine.ml *)
│
│ let rec run promise =
│ match Promise.state promise with
│ | Fulfilled value -> value
│ | Rejected exc -> raise exc
│ | Pending _ ->
│ iter instance;
│ run promise
└────

We just need to loop the event loop until the promis is resolved.

It's just a toy! I'm not an expert in such things, so the library is
very naive and tries to mimic Lwt. But I think it's a good
demonstration.

Repository <https://github.com/dx3mod/tiny-async-lib>

Thank you for your attention!

[Promise] <https://en.wikipedia.org/wiki/Futures_and_promises>

[asynchronous I/O] <https://en.wikipedia.org/wiki/Asynchronous_I/O>

Eliom 11.1: Towards Web Assembly support
════════════════════════════════════════

Archive:
<https://discuss.ocaml.org/t/eliom-11-1-towards-web-assembly-support/15704/1>

Vincent Balat announced
───────────────────────

Eliom 11.1 has been released recently. This minor release brings
compatibility with Web Assembly and the upcoming version of
js_of_ocaml. Ocsigen Toolkit and Ocsigen Start have been updated as
well.

Stay tuned for further announcements concerning client-server Web and
mobile apps in Ocaml with Web Assembly!

Links:

• [Ocsigen]
• [Eliom]
• [Documentation]
• [Github]

[Ocsigen] <https://ocsigen.org>

[Eliom] <https://ocsigen.org/eliom>

[Documentation] <https://ocsigen.org/tuto/latest/manual/basics>

[Github] <https://github.com/ocsigen/eliom>

Areas and Adversaries
═════════════════════

Archive:
<https://discuss.ocaml.org/t/ann-areas-and-adversaries/15706/1>

Raphaël Proust announced
────────────────────────

I figured people might be bored of [British pub names] by now so I did
another thing: [a generator for titles of table-top role-playing
games].

┌────
│ $ opam install areas-and-adversaries
│ ...
│ $ areas-and-adversaries
│ Woods & Wizards
└────

The code is on Gitlab:
<https://gitlab.com/raphael-proust/areas-and-adversaries>

It was a good excuse to experiment with non-dune build systems (to
scope things out). I went for a plain Makefile in the end which works
well.

I also wanted to figure out a better way to embed data in an
executable. I ended up wondering about moving as much of the
processing as possible into the build phase. What I ended up with is a
small program which prints a compilation unit (`.ml') which has mostly
array literals. Still have some open questions on that, any input
welcome:
• Should I have used meta-ocaml to print the code? The `data/munch.ml'
would probably be more readable, but the build probably less.
• How could I generate this kind of processed-data code for
data-structures which don't have a literal (maps, sets, hash tables,
etc.)? How can I minimise the initialisation cost of the program for
such situations?

[British pub names]
<https://discuss.ocaml.org/t/ann-queenshead-a-british-pub-name-generator/13124>

[a generator for titles of table-top role-playing games]
<https://raphael-proust.gitlab.io/code/areas-and-adversaries.html>

MariaDB 1.2.0
═════════════

Archive: <https://discuss.ocaml.org/t/ann-mariadb-1-2-0/15709/1>

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

I'm please to announce a new release of the [mariadb] package, which
provides client bindings for MariaDB and MySQL. See the full release
notes below.

This is also to announce that I have taken over maintenance of the
project. Currently I am the sole maintainer (and I usually use
PostgreSQL for my own deployments), so if someone has the time en
interest to contribute, let me know. The main focus from my side is
to keep the project up to date and stable, rather than making major
changes.

Release notes:

• Added `Stmt.start_txn' (#59 by Corentin Leruth).
• Added `Res.insert_id' as binding for `mysql_stmt_insert_id' (#58 by
Corentin Leruth).
• Updated to support recent OCaml versions (#45 by @kit-ty-kate).
• Fixed too-early retrieval of statement metadata (#41 by Albert
Peschar).
• Fixed decoding bug for the integer type (#54 by Raman Varabets,
tested by #61 by Corentin Leruth).
• Fixed a memory leaks related to result metadata (#39 by Albert
Peschar).
• The build system is now dune and dune-configurator (#52 by Petter A.
Urkedal) and some of the examples have been converted to a test
suite (#60 by Petter A. Urkedal).
• The project has been transferred to ocaml-community with Petter A.
Urkedal as the new maintainer.

[mariadb] <https://github.com/ocaml-community/ocaml-mariadb>

Proposed Package Archiving Policy for the opam Repository
═════════════════════════════════════════════════════════

Archive:
<https://discuss.ocaml.org/t/proposed-package-archiving-policy-for-the-opam-repository/15713/1>

Hannes Mehnert announced
────────────────────────

It is my please to announce the proposed package archiving policy in
the name of the opam-repository maintainers.

Context
╌╌╌╌╌╌╌

The opam repository differs from nearly all other
programming-language-centric package repositories in that it is
manually curated by volunteer maintainers and protected by a robust
continuous integration system that (generally) ensures published
packages work as expected across a [large matrix of supported
platforms].

Over the past few years the repository has kept growing steadily, when
not accelerating, and this has started raising questions about the
size, weight and sustainability of the repository and its
processes. Last year, [Hannes Mehnert] requested comments on a
[proposed initiative] to improve the sustainability and quality of the
opam package repository on the long term.

[large matrix of supported platforms]
<https://github.com/ocurrent/opam-repo-ci/blob/master/doc/platforms.md>

[Hannes Mehnert] <https://github.com/hannesm>

[proposed initiative]
<https://github.com/ocaml/opam-repository/issues/23789>

Problem
╌╌╌╌╌╌╌

The problem, in a nutshell, is that the `opam-repository' will keep
steadily growing, using an increasing and substantial amount of space
and inodes. Every opam user needs to invest a large amount of
computational resources for the solver, every time they want to
install or update a package. Additionally, a large amount of
computational resources are spent in the continuous integration
process and yet a lot of the packages have become stale or
uninstallable.

Solution
╌╌╌╌╌╌╌╌

[After much deliberation], the discussion converged on a solution:
introduce a package archiving policy and supporting processes, to
periodically identify and prune unmaintained and broken packages from
the repository. This will improve the performance of the opam solvers,
of the opam-repo CI, and most importantly improve the quality of the
package repository, while keeping a sort of immutability of the
repository content and preserving the usability of historical packages
for the users that want or need them.

The opam repository maintainers propose a [policy].

The currently empty [repository archive] has been created, waiting for
packages to be moved.

[After much deliberation]
<https://github.com/ocaml/opam-repository/issues/23789>

[policy]
<https://github.com/ocaml/opam-repository/blob/master/governance/policies/archiving.md>

[repository archive] <https://github.com/ocaml/opam-repository-archive>

Call to action
╌╌╌╌╌╌╌╌╌╌╌╌╌╌

If you maintain packages in the opam-repository, you can help by
defining your maintanence intent: add a new field
`x-maintenance-intent' to your opam file(s) (the most recent release
of your package is sufficient - please also put this field in your git
repository so it will be part of future releases). The value is
defined in [the policy].

[the policy]
<https://github.com/ocaml/opam-repository/blob/master/governance/policies/archiving.md#specification-of-the-x--fields-used-in-the-archiving-process>

Roadmap
╌╌╌╌╌╌╌

All announcements will be on discuss.ocaml.org with the
opam-repository tag. If you like to follow these announcements, keep
your eyes at [the opam-repository tag].

• December 1st 2024: announcement of this proposal
• December 15th 2024: announcement of the packages affected by Phase 1
(uninstallable packages ("available: false", "flags: avoid-version"
or "deprecated", "opam admin check –installable", does not compile –
opam health check <https://check.ci.ocaml.org/>)
• January 1st 2025: Phase 1 cutting point: packages are moved to
opam-repository-archive
• January 15th 2025: announcement of the packages affected by Phase 2
(OCaml lower bound 4.08)
• February 1st 2025: Phase 2 cutting point: packages are moved to
opam-repository-archive
• February 15th 2025: initial spring cleaning, announcement of
packages (based on maintenance-intent)
• March 1st 2025: spring cleaning cutting point: packages are moved to
opam-repository-archive
• Every quarter: repeat Phase 3
• Every year: reconsider Phase 2 with an increased OCaml lower bound

We now invite members of the OCaml community who may not follow the
ocaml-repository issues to review our plans and submit comments,
questions, or suggestions.

Thank you in advance for your support!

[the opam-repository tag]
<https://discuss.ocaml.org/tag/opam-repository>

References
╌╌╌╌╌╌╌╌╌╌

• [Opam repository archive]
• [Proposed policy]
• [Plan of action]
• [Issue and discussion]
• [Previous announcement]

[Opam repository archive]
<https://github.com/ocaml/opam-repository-archive>

[Proposed policy]
<https://github.com/ocaml/opam-repository/blob/master/governance/policies/archiving.md>

[Plan of action]
<https://github.com/ocaml/opam-repository/wiki/Package-Archiving:-Plan>

[Issue and discussion]
<https://github.com/ocaml/opam-repository/issues/23789>

[Previous announcement]
<https://discuss.ocaml.org/t/discussions-on-the-future-of-the-opam-repository/13898>

Acknowledgment
╌╌╌╌╌╌╌╌╌╌╌╌╌╌

Thanks to the following individuals for valuable input and
contributions to the planning process (sorry in case we forgot you):

• Marcello Seri
• Shon Feder
• Thomas Gazagnaire
• kit-ty-kate
• Weng Shiwei 翁士伟
• Marcus Rohrmoser
• Reynir Björnsson
• Stephen Sherratt
• Simon Cruanes
• Marek Kubica
• Raphaël Proust
• Romain Beauxis
• Yawar Amin
• Anil Madhavapeddy
• Boning D.
• Mathieu Barbin
• Hannes Mehnert

capnp-rpc 2.0
═════════════

Archive: <https://discuss.ocaml.org/t/ann-capnp-rpc-2-0/15739/1>

Thomas Leonard announced
────────────────────────

I'm pleased to announce the release of [capnp-rpc 2.0], an OCaml
implementation of the Cap'n Proto RPC specification.

If you haven't used the library before, please see the [documentation
and tutorial]. Cap'n Proto RPC aims to provide secure, efficient,
typed communications between multiple parties.

The main change in this version is the switch from Lwt to Eio for
concurrency. The echo benchmark is about 40% faster than before. This
isn't because Eio is actually that much faster than Lwt, but more
because it has better profiling support so spotting problems was
easier. See <https://roscidus.com/blog/blog/2024/07/22/performance/>
for an example:

<https://roscidus.com/blog/images/perf/capnp-eio-slow-zoom1-debug.png>

There is a `capnp-rpc-lwt' compatibility package that provides the old
Lwt API using the new Eio version, allowing libraries using the old
API to be used in applications using the new code, without having to
update everything at once.

To migrate to the new version (checking everything still works after
each step):

1. First, update to capnp-rpc 1.2.4 (this ensures you are using the
newer mirage-crypto API, to get that migration out of the way
first).
2. Switch your application (that sets up the networking) to
capnp-rpc-unix 2.0.
3. Migrate client and server code away from capnp-rpc-lwt when
convenient.

For more detailed instructions, see [the changelog].

Here's an example of the changes needed in the solver-service project:
• [Update to capnp-rpc-unix 2.0]
• [Remove Capnp_rpc_lwt]

[capnp-rpc 2.0] <https://github.com/mirage/capnp-rpc/releases/tag/v2.0>

[documentation and tutorial]
<https://github.com/mirage/capnp-rpc/blob/master/README.md>

[the changelog]
<https://github.com/mirage/capnp-rpc/blob/master/CHANGES.md#v20>

[Update to capnp-rpc-unix 2.0]
<https://github.com/talex5/solver-service/commit/a4af17b5ea44e94579fc0ca01fd0c618a5182df4>

[Remove Capnp_rpc_lwt]
<https://github.com/talex5/solver-service/commit/74431efd36f4474236401f0556fad80de22b1b42>

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

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

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

• [Irmin on MirageOS: Introducing the Notafs File System]

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

[Irmin on MirageOS: Introducing the Notafs File System]
<https://tarides.com/blog/2024-11-27-irmin-on-mirageos-introducing-the-notafs-file-system>

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: 68222 bytes --]