What are the biggest reasons newcomers give up on OCaml?

It is not that obscure, anyone who’s edited an Emacs configuration file (whether they use it as their main editor or not) can recognize some similarities.
One advantage of dune is that you don’t need to write a lot of build rules, and once you’ve set up a project it requires little maintenance over time, in particular not having to list all files (as long as you follow some conventions on where to place them) is a big advantage.
And more importantly dune builds OCaml correctly and quickly, and has one place to go and read the documentation about the build system. That is an improvement over oasis, where often you had to dive into custom ocamlbuild, etc., and certainly an improvement over custom Makefiles (where I’ve seen inconsistent assumptions errors far too often, or workarounds like forcing -j1 to avoid issues due to an incomplete dependency specification). Having said that I very much appreciate that ‘oasis’ existed at the time, even if it wasn’t ideal.

If syntax really is the problem and a DSL would improve things I don’t think the existence of ‘dune’ prevents that, in fact a well documented syntax for ‘dune’ files should make it possible to write an OCaml DSL to generate ‘dune’ files, and as long as the mapping between ‘dune’ rules and the OCaml DSL is kept 1:1 (so the documentation can apply as is) it might be doable — e.g. ‘dune’ could ship a dune_rules.mli
(A DSL that hides the internals or uses different conventions/naming than the underlying dune file would just make it more confusing when you inevitably have to debug an issue with the build system or want to introduce a new rule: you’d have to understand both the DSL, the implementation details of the DSL and dune)
The danger with a DSL (or using a full OCaml program) is that you can end up with custom logic in your build system (and different projects will end up with their own custom logic), which would make understanding and contributing to existing projects harder. Also that custom logic may become a maintenance burden, e.g. when ‘dune’ didn’t support coverage we had to add custom logic with Jbuild_plugin.V1.send, but when migrating from jbuilder to newer versions of dune all that custom logic had to be deleted and removed (at least if we wanted to use the automatic upgrader).
OTOH if the DSL is OCaml itself then you wouldn’t have to learn a new language to use it, and whatever skills you have in debugging and understanding OCaml you can apply to (or learn to) the build system as well. But it is very important that the OCaml DSL be fully typed (and not e.g. output arbitrary strings to be used as dune snippets, which is what jbuilder/dune’s plugin system did…), and complete (so you wouldn’t have to fall back to write something in the dune syntax).

What is a little bit awkward to explain to newcomers though is why the ‘library names’ you use in dune dependencies (the ‘ocamlfind/findlib’ name) is sometimes different from the ‘opam’ package name (if I’m linking library ‘foo’ why do I need to install ‘opam install bar’ to get ‘foo’?), and why when adding a new library as a dependency you have to update the opam file (or dune-project file) to specify that dependency yet again.

Some linux distributions have this problem too, I want to run the binary named ‘foo’ and I have to guess what package name the distro I happen to use has picked for it (they’re not always consistent), however RPM has a clever solution here: you can specify your dependency on the thing you actually use: if you require /usr/bin/bar, then you can specify that in BuildRequires/Requires and let RPM find it based on the (often automatic) Provides of a package.
If ‘opam’ had the ability to specify ‘library(foo)’ or ‘bin(foo)’, and ‘ppx(foo)’ as a dependency that might simplify this situation (and be fully backwards compatible, you could fall back and specify the opam name to disambiguate if needed), and alleviate the need to declare dependencies in multiple places (you could declare it when declaring the library/executable dependency, including a versioned dependency and have dune generate the right opamfile).

8 Likes