Skip to content

Exploring alternative tori implementations

2025-04-12

Thanks to some free time during the university break, I started some work on porting tori to Void and Alpine Linux.

This process prompted some other changes, namely improving tori’s testability, crucial to be able to develop for three operating systems without breaking things on any other platform. But even when tests passed, I had this bad feeling because I knew they all relied on shell exit codes to pass.

So far, tori has been implemented using POSIX shell scripts. The rationale for this choice has been explained in the documentation and leans heavily on the fact that, because mostly any unix system is bound to have a POSIX shell available, this means you can run (and modify) tori without any extra requirements, not even a compiler or any libraries.

While I still believe this is an interesting reason to use shell scripting, going forward I will be doing something I already expected to do eventually: a tori implementation using a more robust programming language.

The main reason I decided to do this now is not really bound to what can be done with shell scripting. It is possible to keep writing new features using it. What really tipped the scale for me was how uncertain I felt when running tests in the form of shell scripts. It all depends on the underlying shell’s errexit and nounset options, which can be unpredictable depending on the shell implementation and the context you are evaluating in (e.g. inside a function, inside a subshell, inside an if condition etc).

Going forward, I’ll be working towards v0.8 as the first version in a different language. But which language? For now, I have created a separate repository for a sandbox project codenamed iganaq. The name is a reference to a location in the migration routes of puffin birds, the bird used as tori’s symbol.

My plan is to evaluate three candidate languages: OCaml, Haskell and Rust. They were chosen for their ability to compile to portable binaries and for their rich type systems that can support predictable and strict logic requirements. OCaml and Haskell, particularly, are interesting candidates for configuration parsing and execution of side-effects only in an outer layer of the application.

Each language will be used to implement a simple command-line interface that fulfills a so-called napkin specification. By “simple” I mean the goal is not to cover corner cases, but to prototype and experiment in order to make a decision based on language syntax, ergonomics, expressiveness, documentation, ecosystem, tooling and overall experience.

Obviously, being the sole author and maintainer of tori, my personal preferences for languages that I either enjoy working with or would like to learn more about also play a part here, as I’d have little to go on with in a language I am neither skilled nor interested in.

More updates will come in the future on how this experiment is going. Feel free to chime in with your thoughts on the new implementation language. You can reach out through IRC or Matrix rooms, Mastodon or privately via email. You can also follow development through the code repository and its mirrors on Codeberg and GitHub.