What are the biggest reasons newcomers give up on OCaml?

I’m not so sure the examples you cite are so impossible in OCaml.

  1. one could pack the files in a dir into a module (the only trick would be picking a name, but gosh, that doesn’t sound insurmountable).

  2. some simple PPX rewriter could do the #[cfg(...)] stuff you describe

I actually think that if what we wanted was something like cargo, it wouldn’t be that tough to build. Maybe I’m missing something, and would love to be disabused of this notion.

I personally use Makefiles, and don’t see why they’re not perfectly cromulent. They don’t seem to be any more complicated than for your typical significant C/C++ project, either. But hey, to each their own.

Markus Mottl’s OCamlMakefile used to do this: a header comment of the form

(**pp arg1 arg2 arg3 *)

that got added to the ocamlc -c invocation. This didn’t help for the link-step, but was already quite effective in reducing Makefile size and complexity. I adopted it for my own Makefiles via camlp5-buildscripts/ya_wrap_ocamlfind.ml at main · camlp5/camlp5-buildscripts · GitHub

1 Like

Relevant RFC: Unit headers for OCaml source files.


In general I recommend people spend more time with Rust to understand the hype and why people enjoy cargo. It’s hard to describe how perfect the tooling is without experiencing it yourself.

1 Like

It’s possible I haven’t spent enough time with Rust. I worked with it for 5mos, in a moderate-sized project ( GitHub - chetmurthy/qrusty: Rust Quantum Computing Library ) that use Rust, Python, and a bunch of sparse-matrix libraries, and heavy multi-thread parallelization. Sure, it’s quite nice. But I don’t quite see where the obstacle is, to building something very much like that for OCaml. Maybe I’m just not seeing a key problem or two.

I would second the recommendation to spend some time with other ecosystems. Unfortunately, the problem with this recommendation is that, IME, you don’t really get the experience unless you spend enough time actually working on real production projects. Even then, if you are a priori familiar with the OCaml tooling, you’ll probably experience things differently.

I first used OCaml in anger way back (more than 20 years ago) when none of the current tooling existed. Recently I got back to using OCaml. I initially found the “new” OCaml tooling (opam and dune, in particular) more confusing than most others I’ve used. It is difficult to say what exactly is the reason for this. Now I’ve gotten more used to them and Stockholm syndrome kicks in.

Perhaps one thing is the mindset inherited from past times that many of the relatively newer languages don’t have. For example, do you, by default, install dependencies globally or locally to each project. Many newer tool chains install packages locally by default (sometimes even including the compiler). Disk space is relatively cheap and it is nice that you can then have multiple projects working without having to think about switching between them (aside from which project you happen to open in your editor).


Dependencies. opam+dune. I’ve given up on ocaml multiple times in the past because I can’t figure out how to work with opam. I thought I’d gotten it down, but the new flow I decided should work does not: add package with a version to dune-project, run dune build to generate the opam file, run opam install . --deps-only --working-dir to install the new dependency. Nope - opam doesn’t install anything. And the documentation does not help me figure it out. It’s also not clear to me why opam cares about source control, i.e. why --working-dir. I just want to update my project dependencies in a declarative manner and code! I really don’t understand what the intended flow is here.


Did you commit the changes you made to the .opam file? opam install ignores uncommitted changes to the project.

1 Like

silently? (twentychars)

Am I understanding this correctly? opam ignores the file on the file system, looks up the current git branch, … and uses that file ?


I’m guessing it’s related to opam pin dismisses uncommitted changes when local path is a git repo · Issue #4652 · ocaml/opam · GitHub which I agree is backward

1 Like

Perhaps creating local switches should become the new default in opam 4.0. But i’m sure this gets tricky for those that knows the inner workings well.

We don’t want to give up the pros of compatibility b/t all libraries for a given switch, but it’d be nice not having to install the same libraries over and over for every project. Maybe that’s not such a bad idea though.

Also opam install . --deps-only works for the most part, but it doesn’t always automatically install missing deps. So then I have to install them manually. A new project can be missing 5-8 from the last time I tried to install - annoying to do.

Not silently, but yes the pinning step that comes before install is git conscious.


You mean it doesn’t install with-test or with-doc deps? See opam is not installing 'with-test' dependencies unless invoked with '--with-test' flag · Issue #5517 · ocaml/opam · GitHub

You may be right. But I recently cloned the dream repo to add some stuff.

I had to manually install tyxml. Can’t exactly recall if I used the tests and docs flag. I can try to reproduce later and report.

I’ve settled on the following workflow:

  1. opam remove .
  2. opam pin remove .
  3. opam install -t --working-dir .

That seems to make opam forget whatever it knew about this project I’m working on, and then relearn about it, with the working-dir. It’s a little cumbersome, so when I’m working with a lot of projects that depend on each other, I use a Makefile. :rofl: :rofl:

I think we’ve officially identified “the biggest reason newcomers give up on OCaml”!

I can even understand why opam defaults to parsing your git repo, but that information needs to be front-and-center in even the most basic of READMEs/tutorials/Hello Worlds, because it is confusing. Even with the warning in the CLI, it is confusing to the newest newcomers.

My personal solution is issuing a pair of redundant dune install XXX && opam install XXX. Looks dumb, but it never goes wrong.


This PR got merged recently that will enable dune to fetch packages. Excited to see it polished over time. But it still relies on opam APIs underneath from what I can garner. So if you still have issues, best to make a GitHub issue.

I … use a global opam … so I was not even aware of this “git aware” opam issue until now. However, if I was using opam local switches, this would have been utterly confusing (at the level of questioning my hardware / own sanity) to debug.

1 Like

Heh, I’ve never been able to get opam “local switches” to work. I got weird errors doing stuff that worked with global switches, and since global switches are sufficient for all my needs I never bothered to dig further.