OCaml Weekly News
Hello
Here is the latest OCaml Weekly News, for the week of November 12 to 19, 2024.
Table of Contents
Boulder Dash in OCaml
Andreas Rossberg announced
Boulder Dash(*) was my favourite computer game in the 8-bit era, first released on the Atari 400/800 in 1984. Though I never owned an 8-bit machine myself, I had friends that I annoyed enough to let me play it on theirs.
As a homage to its 40th anniversary, I put together a fairly faithful clone of the original game, implemented in just a few 100 lines of bare OCaml, with nothing but the homely Graphics library. It should run on Windows, Mac, and Linux, though I was too lazy to test the latter.
Features:
- Faithful original physics, graphics, and animations
- Authentic scrolling mechanics combined with dynamic window resizing
- All 20 levels, including intermissions, and 5 difficulties
- Pause-and-go mode for relaxed playing
It is open-source here:
https://github.com/rossberg/boulder-dash
Enjoy!
/Andreas
(*) https://en.wikipedia.org/wiki/Boulder_Dash_(video_game) "Boulder Dash" is a trademark of BBG Entertainment
Jane Street OCaml extensions – now with developer tooling!
Archive: https://discuss.ocaml.org/t/ann-jane-street-ocaml-extensions-now-with-developer-tooling/15597/1
Diana Kalinichenko announced
Hi everyone! We've just released a new version of our compiler extensions, complete with all our packages and support for developer tooling, including ocamlformat, merlin and ocaml-lsp-server. Get the install instructions at our GitHub, and enjoy the experience in your favorite editor like VSCode, Emacs or Vim.
More documentation coming soon :slight_smile:. Stay tuned for future releases!
opam 2.3.0 is out!
Kate announced
Hi everyone,
As mentioned in our talk at the OCaml Workshop 2024, we decided to switch to a time-based release cycle (every 6 months), starting with opam 2.3.
As promised, we are happy to announce the final release of opam 2.3.0.
What’s new?
- When loading a repository, opam now ignores files in packages’ files/ directories which aren’t listed in the extra-files field of the opam file. :warning: If you maintain an opam repository, please read our blog post to make sure your repository stays compatible.
- Packages requiring an unsupported version of opam are now marked unavailable, instead of causing a repository error. This means an opam repository can now allow smoother upgrade in the future
- opam list –latests-only: a new option to list only the latest versions of packages
- –verbose-on: a new option to enable verbose output for specified package names.
- opam switch import –deps-only: a new option to install only the dependencies of the root packages listed in the opam switch export file
- opam switch list-available no longer displays compilers flagged with
avoid-version~/~deprecated
unless--all
is given, meaning that pre-release or unreleased OCaml packages no longer appear to be the latest version - The builtin-0install solver was improved and should now be capable of being your default solver instead of
builtin-mccs+glpk
. If you wish to give it a try, simply callingopam option solver=builtin-0install
(callopam option solver=
restores the default) - Most of the unhelpful conflict messages were fixed :flashlight:
- Fix the internal cache of installed packages, which was storing the wrong version of the opam file after a build failure. (#6213)
Various performance and other improvements were made and bugs were fixed.
:open_book: You can read our blog post for more information about these changes and more, and for even more details you can take a look at the release note or the changelog.
Try it!
The upgrade instructions are unchanged:
For Unix systems
bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh)"
or from PowerShell for Windows systems
Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) }"
Please report any issues to the bug-tracker.
Installing Developer Tools with Dune
Steve Sherratt announced
Dune can install and run developer tools in the context of a project. This feature is available in the Dune Developer Preview and in the upcoming release of Dune 3.17. As with all of Dune's package management features, consider this feature to be unstable as its UI and semantics may change without notice.
The currently supported tools are ocamllsp
and ocamlformat
. Dune has a new command dune tools exec <TOOL> -- [ARGS]...
which downloads and installs the given tool, and then runs it with the given arguments (note the --
which separates arguments to dune
from arguments to the tool). Tools are installed locally to the project, in its _build
directory, which makes it easy to use different versions of a tool in different projects. An unfortunate consequence of installing tools into _build
is that for the time being all tools are uninstalled whenever dune clean
is run.
Let's see it in action:
$ dune tools exec ocamlformat -- --version Solution for dev-tools.locks/ocamlformat: - ocamlformat.0.26.2+binary-ocaml-5.2.0-built-2024-11-07.0-x86_64-unknown-linux-musl Building ocamlformat.0.26.2+binary-ocaml-5.2.0-built-2024-11-07.0-x86_64-unknown-linux-musl Running 'ocamlformat --version' 0.26.2
Precompiled Binaries
Note that in the example above, Dune's package solver chose to install version 0.26.2+binary-ocaml-5.2.0-built-2024-11-07.0-x86_64-unknown-linux-musl
of ocamlformat
. This packages comes from a new repository of binary packages containing pre-built executables for a select few Opam packages. Dune will search this repository in addition to the default repositories when solving packages for tools only (if a project has ocamlformat
in its dependencies, the binary repository won't be searched while solving the project's dependencies).
The goal of the binary repository is to reduce the time it takes to get started working on a new project. Without it, Dune would need to build ocamlformat
from source along with all of its dependencies, which can take several minutes.
For now only a small number of package versions are contained in the binary repository. To demonstrate, here's what happens if we run dune tools exec ocamlformat
in a project with version=0.26.1
in its .ocamlformat
file:
$ dune tools exec ocamlformat -- --version Solution for dev-tools.locks/ocamlformat: - astring.0.8.5 - base.v0.17.1 - base-bytes.base - base-unix.base - camlp-streams.5.0.1 - cmdliner.1.3.0 ... - ocamlformat.0.26.1 ... Building base-unix.base Building ocaml-base-compiler.5.1.1 Building ocaml-config.3 Building ocaml.5.1.1 Building seq.base Building cmdliner.1.3.0 ... Building ocamlformat.0.26.1 Running 'ocamlformat --version' 0.26.1
Dune parses .ocamlformat
to determine which version of ocamlformat
to install, and 0.26.1
is not in the binary repo so it needed to be built from source.
If your project requires a version of a package not available in the binary repository, or you're on an operating system or architecture for which no binary version of a package exists, the package will be built from source instead. Currently the binary repository contains binaries of ocamlformat.0.26.2
, ocaml-lsp-server.1.18.0
and ocaml-lsp-server.1.19.0
for x86_64-unknown-linux-musl
, x86_64-apple-darwin
and aarch64-apple-darwin
.
Note that Linux binaries are statically linked with muslc so they should work on all distros regardless of dynamic linker.
Running ocamllsp
The program ocamllsp
from the package ocaml-lsp-server
analyzes OCaml code and sends information to text editors using the Language Server Protocol. The tool is crucial to OCaml's editor integration and it has a couple of quirks that are worth mentioning here.
TL;DR: Install Dune with the install script on the Developer Preview page and you'll get an ocamllsp
shell script that will install and run the correct version of ocamllsp
for your project.
Firstly the ocamllsp
executable can only analyze code that has been compiled with the same version of the OCaml compiler as was used to compile the ocamllsp
executable itself. Different versions of the ocaml-lsp-server
package are incompatible with some versions of the OCaml compiler (e.g. ocaml-lsp-server.1.19.0
must be built with at least 5.2.0
of the compiler). This means that when Dune is choosing which version of ocaml-lsp-server
to install it needs to know which version of the compiler your project is using. This is only known after the project has been locked (by running dune pkg lock
), so Dune will refuse to install ocamllsp
in a project that doesn't have a lock directory or for a project that doesn't depend on the OCaml compiler.
$ dune tools exec ocamllsp Error: Unable to load the lockdir for the default build context. Hint: Try running 'dune pkg lock'
The ocaml-lsp-server
packages in the binary repository contain metadata to ensure that the ocamllsp
executable that gets installed was built with the same version of the compiler as your project. For example the ocaml-lsp-server
package built with ocaml.5.2.0
contains this line:
conflicts: "ocaml" {!= "5.2.0"}
This prevents it from being chosen if the project depends on any version of the compiler other than 5.2.0
.
Another quirk is that ocamllsp
will try to invoke the binaries ocamlformat
and ocamlformat-rpc
, both found in the ocamlformat
package. The ocaml-lsp-server
package doesn't depend on ocamlformat
as the specific version of ocamlformat
needed by a project is implied by the project's .ocamlformat
file, which package managers don't consider when solving dependencies. This means that in general (whether using Dune or Opam for package management) it's up to the user to make sure that the correct version of ocamlformat
is installed in order to use the formatting features of ocamllsp
.
Otherwise expect this error in your editor:
Unable to find 'ocamlformat-rpc' binary. Types on hover may not be well-formatted. You need to install either 'ocamlformat' of version > 0.21.0 or, otherwise, 'ocamlformat-rpc' package.
Even if ocamllsp
and ocamlformat
are both installed by Dune, if you run dune tools exec ocamllsp
you will find that ocamllsp
still can't find the ocamlformat
or ocamlformat-rpc
executables. This is because unlike Opam, Dune does not install tools into your $PATH
, and for the sake of simplicity, the dune tools exec <TOOL>
command does not modify the environment of the tool it launches. This can be fixed by adding _build/_private/default/.dev-tool/ocamlformat/ocamlformat/target/bin
(the directory containing ocamlformat
and ocamlformat-rpc
when ocamlformat
is installed by dune) to the start of your $PATH
variable before running dune tools exec ocamllsp
. For example starting ocamllsp
with the following shell script:
OCAMLFORMAT_TARGET="_build/_private/default/.dev-tool/ocamlformat/ocamlformat/target" if [ ! -f $OCAMLFORMAT_TARGET/cookie ]; then # Make sure that the ocamlformat dev tool is installed as it's needed by # ocamllsp. There's currently no command that just installs ocamlformat so # we need to run it and ignore the result. dune tools exec ocamlformat -- --help > /dev/null fi # Add ocamlformat to the environment in which ocamllsp runs so ocamllsp can invoke ocamlformat. export PATH="$PWD/$OCAMLFORMAT_TARGET/bin:$PATH" # Build and run ocamllsp. dune tools exec ocamllsp -- "$@"
Of course, it's rare to manually start ocamllsp
directly from your terminal. It's normally launched by text editors. It would be impractical to configure your text editor to modify $PATH
and run a custom command to start ocamllsp
via Dune, and doing so would make it impossible to edit any project that doesn't use Dune for package management. Instead, the Dune Developer Preview ships with a shell script which installs ocamlformat
and adds its bin
directory to $PATH
before launching dune tools exec ocamllsp
. The script is simply named ocamllsp
, and the Dune Developer Preview install script adds it to ~/.dune/bin
which should already be in your $PATH
if you're using the Developer Preview. The ocamllsp
script also attempts to fall back to an Opam-managed installation of ocamllsp
if it doesn't detect a Dune lockdir so the same script should work for non-Dune projects. Because the script is named the same as the ocamllsp
executable, most editors don't require special configuration to run it. See the "Editor Configuration" section of the Dune Developer Preview page for more information about setting up your editor.
Some parts of the ocamllsp
shell script may eventually make their way into Dune itself, but for the time being the shell script is the recommended way to launch ocamllsp
for users of the Dune Developer Preview. The net result is that as long as your project has a lockfile, the first time you edit some OCaml code in the project Dune will download and run the appropriate version of ocamllsp
.
Dune Developer Preview Updates
Steve Sherratt announced
A new version of the vscode-ocaml-platform was just released which fixes a few issues with ocamllsp. You'll probably have to update your install of the Dune Developer Preview (just rerun the command on this page). You'll need to configure a custom sandbox for vscode by putting this in your settings.json
file as otherwise the plugin assumes you're using opam
to launch ocamllsp
:
{ "ocaml.sandbox": { "kind": "custom", "template": "$prog $args" } }
First release of cmdlang
Mathieu Barbin announced
Hi everyone!
A little while ago, I posted about cmdlang, a library for creating command-line parsers in OCaml.
Today, I am happy to give you an update on this project with the announcement of an initial release of cmdlang packages to the opam-repository.
These are very early days for this project. I have started using the cmdlang+cmdliner
combination in personal projects, and plan to experiment with climate
in the near future. Please feel free to engage in issues/discussions, etc.
The most recent addition on the project is the development of an evaluation engine based on stdlib/arg
.
I'd also like to highlight some examples from the project's tests. Developing these characterization tests was a fun way to learn more about the different CLI libraries and their differences:
- Short, long and prefix flag names.
- Various syntaxes for named arguments (
-pVALUE
,-p=VALUE
,-p VALUE
). - Handling of negative integers as named arguments.
If you have ideas for more cases to add (entertaining or otherwise), I'd love to integrate them into the test suite. Thanks!
Below, you'll find details of the released packages. Happy command parsing!
cmdlang the user facing library to build the commands. It has no dependencies
cmdlang-to-cmdliner translate cmdlang commands to cmdliner
cmdlang-to-climate translate cmdlang commands to the newly released climate (compatibility checked with 0.1.0 & 0.2.0)
cmdlang-stdlib-runner an execution engine implemented on top of stdlib.arg
Thank you to @mseri and the opam-repository maintainers for their help.
findlib-1.9.8
Gerd Stolpmann announced
Hi list,
findlib-1.9.8 is out, fixing a few issues that slipped into 1.9.7.
For manual, download, manuals, etc. see here:
http://projects.camlcity.org/projects/findlib.html
An updated OPAM package will follow soon.
Testo 0.1.0 - a new testing framework for OCaml
Martin Jambon announced
On this 86th anniversary of the first synthesis of LSD by Albert Hofmann, it is my pleasure to announce Testo, a new testing library for OCaml.
It borrows a lot of ideas from Alcotest and is similar in spirit but adds a few key features that seemed too difficult to incorporate into Alcotest. For a gentle introduction, check out our tutorial. Important features include:
- support for many options when creating a test of type
Testo.t
; - capturing stdout or stderr output for comparison against the expected output aka snapshots;
- reviewing and approving tests without re-running them;
- support for nested categories while keeping the test suite as a flat list;
- parallel execution using multiprocessing.
This is the first official release of Testo and its interface is likely to change in minor ways until we release version 1.0.0. We've been using it internally at Semgrep for about a year and it's been working well for us.
Happy testing!
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 to the caml-list.