[BLOG] Frustrating Interactions with the OCaml Ecosystem while developing a Synthesizer Library

Last year I made a synthesizer library in OCaml and had some struggles using Dune and Opam, and also ran into several issues with libraries. I wrote a blog post about all the problems I encountered.

10 Likes

A lot of these issues seems like oversights of Dune (of which I have ran into) but Opam as well. I myself have wondered if some of the headache could have been avoided by going back to Make or similar, just invoking ocamlc / ocamlopt directly, & using something like Nix/Guix for package management.

On the plus side, at least ocaml-rs exists to get you over some of the hump in OCaml… unlike C libraries which are easily consumed by most other languages, many Rust libraries aren’t exposing the C bindings with extern "C" making language interop much more difficult than the C status quo.

2 Likes

The frustration is mostly in the interaction with Rust code and its integration. The title does not reflect that.

I myself have wondered if some of the headache could have been avoided by going back to Make or similar

I doubt that; Makefiles of realistic projects for OCaml tend to be very complex and this led to a string of build systems, culminating in dune.

4 Likes

The section about ppx_inline_test is an interesting problem. I agree with @gridbugs that it’s unreasonable to add all of those dependencies when the library consumer doesn’t need them.

It does seem like this could be solved with the dune package management integration, but some standardization of AST nodes that are only compiled under test should probably be introduced. It also might be preferable to add a compiler flag to ignore (with a warning) top-level structure items with extensions that haven’t been rewritten by a PPX. But, that could have unintended consequences, i.e. if a top-level binding is effectful:

let arr = [| 1; 2; 3 |]
          
let%does_not_compile () = arr.(0) <- 2
    
let () =
  print_int arr.(0) (* should print 2, prints 1 *)

Not sure what the right solution is for this.

2 Likes

The last comment in an oldish GitHub issue was talking about ideas for the ppx_inline_test dependency problem

Adding inline tests to a library requires adding over 20 (runtime) dependencies

This worries me too from time to time. I have a feeling that we should for JaneStreet’s PPXes to cut some dependecies. My current attempt could be browsed from here: GitHub - Kakadu/ppx_tests_demo: A demo. An attempt to minimize dependencies for ppx_inline_test and ppx_expect Not sure how many folks will be interested in that.

3 Likes

I did solve this (and other) problems by using neither Dune nor Jane Street PPXs - I did generally at least try to avoid anything Jane Street.

I did use Alcotest together with Inline Alcotest and Buck2

Btw. by using a Merlin configuration file Merlin and the LSP work with Buck 2 (without Dune in general, so Makefiles, … work too).

2 Likes

Inline Alcotest looks like a replacemnt for ppx_inline_test, not for ppx_expect, isn’t it?

Yes, exactly - the OP did not mention ppx_expect, just ppx_inline_test.

@Release-Candidate, Any chance you have a replacement for ppx_expect?

I most of the time “just” compare files, but as a 1-1 replacement I’d use pytest-matcher - or something comparable in a language you happen to have installed. I guess it’s even “better”, as ppx_expect doesn’t support regex for matching changing parts of the output AFAIK.