Article: "Systems Languages: An Experience Report"

While looking for something else, I found this: Systems Languages: An Experience Report. It’s about a 15 minute read. Here’s my summary: somebody tried to write the same little POSIX signal forwarding utility in various alternative programming languages, including OCaml, and wrote up their good and bad experiences with each one. The experience with OCaml seems to be generally okay, but complaints include: a) the build system tools are painful, b) surprises about the runtime interaction between the thread system and POSIX signal handling are buried in the documentation, and c) generalized grumbling about the multicore story, which is the source of the surprise about POSIX signaling handling in the runtime.

1 Like

It’s been discussed twice on lobsters:

I think it shows a lack of documentation and tooling ecosystem clarity for the ocaml part (our fault somewhat): better official entry points would have eased at least partially the entry barrier he has found. But overall it was a good effort to try and compare languages, at least it was done after some research and for nontrivial code

1 Like

The author’s comments about build systems are quite outdated. The situation isn’t perfect, but it’s no longer as dire as he describes now that dune is widely adopted. But it seems like the reputation for arcane and ineffective tools is still haunting the OCaml community. This is an issue that deserves some attention from us.

2 Likes

I agree.

What I was mostly surprised about, is that he did not find anything about jbuilder (that was already widely adopted at that time, and mentioned in different reason tutorials).

I think the big ongoig effort in improving docs, strenghtening the community and having better landing places, is going in the right direction. That post was anoher reminder that we need to work hard on it.

2 Likes

Some reader mentioned dune in a side note on the original article (asterisk). I clicked 50 times to give 50 claps (the maximum, I found out). I’m sure we can take it to 200+ -> https://blog.usejournal.com/systems-languages-an-experience-report-d008b2b12628

1 Like

I’m more surprised he managed to miss Lwt/Async. He doesn’t seem to need multicore, he needs concurrency, and we have really good solutions for that.
I’m pretty sure any OCaml programmer would have advised it, so he probably didn’t ask anywhere.

3 Likes

I suspect the author might share my preference for less opinionated build tools than jbuilder/dune, but it’s hard to know. They didn’t go into a lot of detail about what they found frustrating about ocamlbuild, oasis, and jenga— except to make a cryptic comment about how we should all go spoon with the Rust people until some new concept more to their liking emerges. I don’t know what to make of that, because I have no idea what the build tooling for Rust projects looks like.

They also didn’t say anything about OMake, which I suspect is an oversight and not a slight.

Rust’s side of the story is essentially you have a single tool(cargo) that handles package installation, project setup, project compilation, test invocation, everything basically.

It feels very close to jbuilder/dune, in that it essentially requires a fairly strict project directory structure, fairly opinionated primitives you can use in the project configuration (which is a TOML file).

Cargo has better support for addons than dune - you can install addons that adds a sub-command and is available everywhere you go, as opposed to declaring another alias in your specific project in dune.

I’d say dune has better support for code generators however, since you can specify code generator constructs in the jbuild/dune file directly, while Rust only allows a single “build script”(a single Rust source code file). Admittedly this isn’t that important since you can put all generators in a single file, but the segregation helps somewhat.

I have not heard too many complaints about cargo, but it’s a different situation there as Rust started with cargo as the official everything tool since day 0, but OCaml didn’t have that I think. So Rust people pretty much never have to think “Oh, do I like build system 1, build system 2, or build system 3 better?”, they just use cargo all the time and that’s it.

If opam supports building project, then it would be very close to cargo essentially.

1 Like

I have the vague impression that Cargo (and tools like it for other languages) are an integration of the functions provided for the OCaml toolchain by the combination of OPAM, Findlib and Dune/Oasis/Jenga/OMake/etc. It would have to be very opinionated for all those things to be glued together into one monolithic tool. My hunch is that will make it a snarlyball of cross-cutting aspects over time, and it will become very difficult to sustain.

I never take this kind of articles seriously, and I am heavily biased towards them, as they never felt like a genuine attempt at experimentation of languages, but an attempt to try myriad things quickly just for an article.

But using it as reference of what obstacles beginners might face, I do think it would be constructive to have a more visible list of useful utilities/tools on ocaml.org

Similar to awesome-ocaml, but just for very essential tools like build tools, test frameworks, etc.

I have also always found it curious that jbuilder/dune is not listed here: http://ocaml.org/learn/tutorials/compiling_ocaml_projects.html

2 Likes

It is unfortunate that our documentation is not really good enough, which means that people do indeed have to learn such things by asking around. In other language communities, it isn’t nearly so necessary to ask experienced people because the docs would have very naturally pointed people at the natural solutions.

2 Likes

Just wanted to plug OCamlverse. Not only can anyone contribute via PR, anyone can have commit rights as well.

We already have a quickstart page for setting up Dune and such. I’d love to have more content there for getting OCaml concepts like concurrent programming up and running quickly.

4 Likes

My experience with the OCaml tooling situation leaves with an opposite impression. In theory, the flavour of the Unix philosophy that you suggest here would work if all the tools were carefully designed to handle their own concerns with an eye towards compatibility and harmony between the different tools. In practice, the tools that you mention were all created in a way that is either oblivious to one another or simply had to work around each other’s limitations. Here’s a very non exhaustive list of all the (some comical) consequences of the old tooling situation:

  • ocamlfind interface was created in a way that would make it easy to replace calls to ocamlc/ocamlopt/ocamldep with it - this is the easiest way for it make its database of libraries available. Now let’s consider the number of times ocamlfind must read and parse the META files in its database during a single build.

  • The reason why oasis was so dreadfully slow is that it was built around targeting a non parallelizing build system (ocamlbuild). Another issue with oasis was that it spent quite a bit of effort generating a build system that wouldn’t depend on itself. This led to quite a bit of effort being wasted on solving the non issue of installing a single dependency.

  • Since opam had to be build system agnostic, it could not even control the artifacts that every package had to install. This led to the recent camlp5 uninstallation bug, where a hand written uninstall script accidentally $ rm -rf / on OSX.

  • Consider why we have 3 layers of naming for an opam package. Opam package names, findlib names, and module names.

All of the above are casualties of the Unix philosophy as applied to solving the OCaml tooling situation. In my opinion, the costs have outweighed the benefits of having all of these simple and orthogonal tools.

6 Likes

I disagree. I don’t think it has much to do with the Unix philosophy. It was just a series of short-term focused designs. (The native Unix tooling situation is not even vaguely so bad.)

However, there’s no way to actually answer a question like this — there’s no test that will resolve the dispute and say what “the” problem is, so we may have to just agree to disagree.

I didn’t say it wasn’t possible to create a scalable and flexible ocaml build process by composing small, self contained binaries. I just stated that it hasn’t been done yet. Those who are supporting this design philosophy are welcome to propose a solution. But for now, I will remain skeptical.

I think those criticisms are well formed and valid. While my preferences are solidly in favor of a system of tools that separately manage different aspects of development work as opposed to a single tool with multiple attachments for each aspect, I can absolutely agree that the current tooling for OCaml has a lot of room for improvement. I’ve struggled to cope with some of them in Conjury, my alternative library for OMake.

In my view, probably the most glaring issue that complicates the tooling situation for OCaml newcomers is the way Findlib is completely agnostic of OPAM, and how OPAM and the compilers don’t cooperate to make Findlib into a redundancy. I wonder what others think.

1 Like

I think small units can be good when you don’t know what the ideal solution will be and are trying to search a space of possibilities. At this point, we have a sufficient number of examples from other languages of what a good package manager is. Splitting it up into multiple projects makes advancing one coherent design difficult, and it wastes community resources. On the other hand, had we had a complete solution early on, it’s very likely that this solution would have been antiquated and opinionated in an unintuitive way, given OCaml’s age and history, similar to ocamlbuild’s eccentricities.

1 Like