What I dislike about OCaml

This is a fair cop. But I would add that opam does an excellent job of managing package interactions and evolution. I had a bad experience with Rust early-on, where some Rust package C depended on B, which depended on A, in ways that made B break when A got a new release. This was pretty unpleasant, and what was more unpleasant is that there was no way to force the version of A selected, to be a backlevel one.f

The opam maintainers and their discipline (which they enforce on all of us) makes the opam repository the closest thing I’ve ever experienced, to a massive mono-repo.

That’s valuable, and I wouldn’t want to give that up. Having experienced Rust’s “crates”, I’m even more adamant on clinging to the stability of opam-repository.

3 Likes

I understand the approach they’re taking but it’s funny to praise this approach while also praising how scalable the tools are. The hand-curated opam approach will have a tough time scaling to even a moderately-sized project that needs to control its dependency graph. Right now the best advice on offer is to vendor the entire dependency subtree into the project directly if you need to customize anything.

Well, let me just point out that this isn’t actually as straightforward as it looks. Sure, I’m perfectly happy that the unwashed use dune. Great, great. But when I was writing my camlp5-based work-alikes for all the standard PPX rewriters, I found that it was well-nigh impossible to figure out from the documentation, how to invoke them directly. Sure, you could do it thru dune, but I wanted and needed to do it thru Makefiles. I had to reverse-engineer how to do it by inspecting the (ridiculously verbose) build log.

If I could ask one, only one thing of dune, it would be to map their libraries and other large-scale build-artifacts to findlib packages, so that those of us who don’t use dune could interact with dune-based builds. Instead of having to rip out dune and redo everything.

When starting to use OCaml I found https://ocamlverse.github.io/ really, really helpful. For example, like others have said I was distracted by having to choose Base or Containers or pure Stdlib, but Ocamlverse gave me a good overview and guidance on that. I’ve found the same on other things like web servers and database libraries. And the information was pretty up to date.

So I think it’s extremely worthwhile to maintain Ocamlverse and it seems like it should be more prominent. I can’t find a link to it from ocaml.org. Is there some reason it is separate, or it just happened that way and there hasn’t been time to integrate it?

The other complaint that resonated with me is the lack of library doc. It’s true the code is very readable, but I think everyone (beginners or not) would benefit greatly from good library doc, including at least a minimal example, for each function. Some Ocaml libraries are good in this respect but a lot are not. I suspect this is a cultural thing – once it becomes acceptable to leave out the doc, people will do it. The only way to change that is to make it unacceptable by example and peer pressure. Is that worth it?

7 Likes

I’ve said this before but I really think we can learn a lot from Go’s tooling and attention to supply chain security. I wouldn’t even mind a build system that forced me to declare my library dependencies at the top of each OCaml source code file.

I wouldn’t mind more explicitness either. Even having to declare, in one
file per library, the list of modules in a OCaml file, and having to
import them? That’d be quite neat and clean. Currently you just find
modules that are magically in the namespace :confused:

2 Likes

This “vendorizing” is precisely what got those Rust modules in trouble. The Rust approach is to “automatically vendorize” when deps can’t be met without it. So when package B exports types from package A, and package C needs a different version of package A directly, you can end up with types from both versions of A visible, and no way to prevent it.

I’m 100% OK with a package-writer deciding to vendorize. I am adamantly against a package-manager that automatically does so without the package-writer’s knowledge.

2 Likes

Yeah, and in fact many beginners don’t like how magical the implicit imports are, they prefer explicit imports! It would even solve 90% of the namespacing problem. E.g. imagine:

(* test.ml *)

#depend "decimal";;

let s = Decimal.of_string

I believe something like this will be possible with Bazel modules, which I hope to support in OBazl 3. The tricky bit is making it work with legacy libraries. I haven’t figured out how to do that yet.

2 Likes

I’m curious about this. A lot of OCaml beginner struggles are made easier with support from your organization, but here you are saying you’re forced to use it? Are you the first person in your org assigned to carve out a path here?

4 Likes