OCaml Weekly News

Previous Week Up Next Week

Hello

Here is the latest OCaml Weekly News, for the week of June 06 to 13, 2023.

Table of Contents

release of minisat 0.5

Simon Cruanes announced

OCaml-minisat 0.5 just landed on opam.

This library has bindings to the classic minisat SAT solver. It should have decently low overhead (no ctypes, runtime lock released, etc.) and be useful for general purpose SAT solving. Minisat is not really state of the art anymore, but it’s still pretty damn good for a lot of use cases.

Darius asked and Simon Cruanes replied

Just out of interest, what is the state of the art, and what are these use cases?

State of the art is, roughly, Cadical and Kissa (yes, both are from Armin Biere). They’re better on hard SAT instances, the ones that still take a while to solve.

These minisat bindings could be updated at least to Glucose (a known patch to minisat with better heuristics), maybe I’ll do that at some point.

The use cases: anything where you want to solve a NP-complete problem (register allocation for example; sudoku solving; also a lot of verification problems can benefit from a SAT encoding somewhere). Using an API instead of calling a process is useful because you can access more things and perform incremental solving easily: instead of solving a single SAT problem, you can solve a series of increasingly big problems without starting from scratch each time.

containers 3.12

Simon Cruanes announced

I’m happy to announce the release of containers 3.12.

Containers is a lightweight and modular extension of the standard library. It enriches existing modules and adds a few that are missing.

In this release, the highlights are:

  • more functions in Set and Array
  • a new containers.pp sublibrary, with Wadler-style pretty printing combinators
  • improvements to the parser combinators (CCParse)
  • a whole bucket of bugfixes

Recent tar releases (2.5.0, 2.4.0, …)

Reynir Björnsson announced

I’m pleased to announce the release of tar.2.5.0 earlier this week.

This release and the previous release improves PAX support, mirage key-value write support and bug fixes:

  • in 2.4.0 the pax global header is properly skipped when reading - previous releases did not skip the header properly which would result in a corrupt read. In a future release the global header will be read and used. More on that later.
  • in 2.5.0 the file name and link name are used from per-file pax headers, if present.
  • in 2.4.0 the ustar version is correctly encoded while writing. This did not seem to cause any issues with other implementations. Unfortunately, this is a breaking change, and may break reproducibility of archives written with prior versions of ocaml-tar.
  • earlier releases the past year have been focused on adding write support to the tar-backed mirage key-value store tar-mirage.

Future release

I am working on the next release which will support the global PAX header. This introduces additional global state in the reader, and will be a breaking change. Additionally, old and (mostly) unused modules and functions will be removed. If you use any of the bits being removed please feel free to chime in and comment on what you’d like to see kept. The work in progress can be viewed at: https://github.com/mirage/ocaml-tar/pull/127

mpp.0.3.6, which adds compatibility with OCaml 5, is now in opam

Philippe Wang announced

mpp.0.3.6, which adds compatibility with OCaml 5, is now in opam!

MPP is a preprocessor, and also a metapreprocessor.

As a preprocessor, it’s quite simple and maybe even minimalistic.

As a meta preprocessor, it’s very powerful, since it allows you to simply use OCaml (and almost any programming language) as your preprocessing language.

Have fun!

trace 0.1, tracy-client 0.1

Simon Cruanes announced

I’m quite giddy to announce the initial release of my library trace, and of tracy-client (sponsored by my employer, Imandra).

Trace is a lightweight library designed for instrumenting library and executable code with a low dependency cost. It provides abstractions for basic logging, traces (spans), and metrics, with a low footprint. The goal is that it’s ok to depend on it in libraries, and it costs almost nothing at runtime in the absence of a collector. The cost of a call in the absence of a collector is basically an atomic load and a comparison to None.

A collector is a backend that is typically registered at program startup. Only applications should ever specify a backend. There is a simple trace-tef library that provides a backend that writes into a .json file in the Catapult/TEF format (compatible with chrome://tracing in chrome, and with perfetto).

Which brings me to tracy-client. It is a library that provides direct bindings to the excellent Tracy project. It also comes with [tracy-client.trace], which provides a Trace backend that forwards events to Tracy over the network (while the program is running). It can be quite useful for interactive programs such as games, but also for CPU-oriented programs in general. The bindings work, but they don’t cover the full extent of Tracy yet (which notably include frames for graphic programs).

So far these are the two released backends for Trace, but I have a Opentelemetry backend in the works; it won’t cover the depth of options of OTEL but it will make it possible to reuse trace-based instrumentation with any OTEL collector. Another exciting possibility with OCaml 5.1 is to use the upcoming Runtime_events (and custom user events) to forward trace events to an external logger with low overhead.

Docs for Trace can be found here. Trace is licensed under the MIT license, and tracy-client under BSD-3.

A short review of fmlib_browser (web frontend library)

Richard Huxton announced

This is probably better as a blog article, but I’m guessing anyone who is interested is quite likely to find it here. It’s just some short notes on my first impressions (as an ocaml beginner) of the fmlib_browser web-app library.

Summary

  • Port of Elm to ocaml + js_of_ocaml
  • Available on opam with source on https://github.com/hbr/fmlib
  • Seems like an accurate port - covers all the basics
  • Good documentation
  • Easy to start using
  • Don’t forget to build with --profile=release

Elm and the basics of the port

Elm is perhaps the best known of the functional compile-to-javascript languages and is particularly attractive to functional beginners. It has a focus on good error messages and simplicity. It’s overall architecture (global model, no side effects, update messages) has been copied many times.

The fmlib_browser package is part of a family of functional/managed-effect libraries from the same author. It has basically the same structure as Elm, just translated into ocaml which is then compiled to javascript with js_of_ocaml.

I’ll not repeat the excellent documentation and in any case for a general overview you can probably rely on the Elm introductory material too.

In use

Boring in the best way. Does what it says on the tin. There are some docs on hooking it up to dune and it works with ocaml 5.0.

Compilation seems pretty fast, but be aware that by default you will get a javascript file that starts at about 5MB. If you run dune build --profile=release then the output will be stripped and minimised and you will be closer to 100KB. When gzipped for transfer this will come down to about 33KB as a starting point.

That sounds large, but it increases fairly slowly from that point as you add actual code.

Who is this for?

If you like the idea of Elm, are already working in OCaml and don’t need a large ecosystem this might do what you want. It’s not suited to small plugins but for a dashboard or other application you would leave open for a long time should work fine.

moonpool 0.1

Simon Cruanes announced

I’m happy to announce the release of moonpool 0.1. Moonpool, so far, is mostly an experiment, but is in a usable state already.

So what is moonpool? It’s my go at starting to leverage OCaml 5 for multicore computations. Unlike other approaches, it relies heavily on classic Thread.t, because unlike domains it’s ok to create many of them and have some block on IO or long running C calls. A pool provides a run: (unit -> unit) -> unit function that runs the task (its argument) onto one of the pool’s workers at a later date.

Moonpool works by allocating, at startup, a fixed pool of domains, of the recommended size.[^1] From there, the user can create a number of regular thread pools, each of which will be distributed over the pool of domains so that the threads can run in parallel. It’s perfectly possible to have, on a 16 core machine, a pool of 50 IO threads for some server, along with a pool of 16 compute threads.

Moonpool also provides a Future abstraction. These futures are thread safe; the combinators such as map, bind, etc. can themselves run on pools. Futures are quite lightweight and use an Atomic.t variable for storage, no lock needed.[^2]

Lastly: moonpool also works on OCaml >= 4.08, by simply reducing to regular thread pools running on a single domain. This should allow users to use moonpool on 4.xx, before migrating to 5.xx on their own time.

Documentation is here. It’s released under the MIT license.

Contributions or discussions are very welcome. This is very early days for this project, and I have lots to learn. The task scheduler is quite simple and will probably not compete with domainslib on super-fine grained tasks; but for use cases where tasks are not that tiny I think it works perfectly fine already.

[^1]: basically Domain.recommended_domain_count()-1 on OCaml 5.

[^2]: except for Fut.wait_block, which is like an entrypoint and should be called “from the outside”. More in the documentation.

Other OCaml News

From the ocaml.org blog

Here are links from many OCaml blogs aggregated at 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 online.