What are the biggest reasons newcomers give up on OCaml?

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.


Same here. Local switch on mac wouldn’t work for my project so had to revert back to global switches.

From these comments, and my experience as a relative ocaml newcomer, it does seem that there is an intended usage of opam that is not at all obvious to newcomers (or, at least, to me). My assumptions were that except in odd circumstances, you’d always want to use a local switch to provide an isolated environment, and that you’d always want the contents of the switch driven from a file. That’s how every other package system works, even python’s now. However, that opam doesn’t seem to cache things, recompiling everything in each new switch (I think that’s what it’s doing), makes me wonder if that’s actually the intended use, or if the intended use is that you work off a global switch, and just put versions into the dune-project and opam files once you’re ready to publish it so others can work with a declarative dependency set. Since it might be a week before I have time to tinker with my project next (or if I were working on a team), I can’t rely on my machine being in the right state or my remembering how I had things set up to use a global switch.

I’ve arrived at the following, which so far seems to work:

$ opam switch create . <compiler version> --deps-only
$ opam install dune
$ opam install merlin 
$ opam exec -- dune build

and then to add a dependency

$ opam install <package name>
--- see from the output what version it installed
--- add dependency with its version to dune-project
$ opam exec -- dune build   # (generate_opam_files true)
--- add the dependency to the relevant dune files

But that’s a pretty fiddly process, so I wonder if that’s what seasoned ocaml devs do.

esy does work the way I’d like things to - isolated project environments with cacheing - but depending on npm and a package.json seems unnecessary, and I couldn’t quite figure out my Dockerfile when I used esy, so I decided that it was better to use plain opam and dune and just find a workflow that works and write a couple scripts around it. But it requires quite a bit of dedication to using ocaml to get this far. I really like ocaml!


I’m not sure where the assumption this has to do with local switches crept in, the pinning committed changes only behaviour applies whether the activated switch is global or local. As noted, it does tell you about it when changes are ignored, and the linked discussion in the issue posted goes into the (imo sensible) reason why they went this way, so these reactions seem a touch melodramatic.

1 Like

To add a piece of anecdata: I always develop and build projects in local switches myself.

The git-sensitive aspect of opam is a bit of a pain, as is the lack of support for declaring dev-deps.

I use this little tool I’ve hacked together to script some of the more tedious bits for myself: GitHub - shonfeder/nomad: OCaml project situation tools: wander freely to find fertile ground

I’m looking forward to more robust solutions to smoothing out these bumps emerging in the course of time :slight_smile:

1 Like

Aren’t dev-deps handled by opam’s with-dev criterion?

That’d be great! I couldn’t find docs on that string, but could you mean with-dev-setup opam - Manual ?

I can’t find any docs on that page, or via --help or man opam install for how/when this variable takes effect. Any pointers short of the source code?

1 Like

Wait, sorry, I misremembered :sweat_smile:

The filters are indeed the ones you found on that page.

1 Like