What are the biggest reasons newcomers give up on OCaml?

I’d argue that in a real-world project running in production this is actually quite bad to have a compiler error here instead of a warning. The reason is that you’re either going to mute it with _ as you indicated, or worse by ignoring the error with a flag. Then you won’t know that your system is messed up in production and potentially runs a bug. On the other hand if it was a warning (which is what cargo does), then you can clean it up at the end once you’re done (and usually CI won’t let you merge code that has warnings)

It would be a useful feature if we could turn errors into warnings during the development.

1 Like

If you’re referring to “unused variable not prefixed with ‘_’” as the error, I thought that that was Dune’s default configuration: certainly when I invoke ocamlc directly, such usage produces warnings, not errors. I’m sure there’s a way to stop Dune from treating them as errors.


You can modify the compiler flags in the dune file via a ‘flags’ field in the relevant executable or library stanza. Unused variables generate warning 26, so you could include a field (flags :standard -warn-error -26) to prevent the warning being treated as an error, or suppress the warning entirely with (flags :standard -w -26). In recent versions of ocaml I believe you can also use predefined names, namely (flags :standard -w -unused-var).

To do this in a more discriminating way you can use attributes.I do not find the attributes manual page particularly helpful (it comprises grammar without a great deal of explanation) but it seems that to suppress a warning about an unused variable x you could define the variable with the built-in warning attribute in the form let [@warning "-26"] x = "test" in, or with a block attribute let x = "test" [@@warning "-26"] in. You can also have module-level attributes such as [@@@warning "-26"]. The warning attribute is in the ocaml namespace so [@@@ocaml.warning "-26"] would do fine also.

There is also a built-in warnerror attribute which works in a similar way as a means of preventing a warning being treated as an error. I don’t know if it stops dune treating warnings as errors (I haven’t tried) but in principle it ought to do so.


It was not.

I got it working so I can use bisect_ppx, and that was worth the hassle on balance, but the hassle was entirely unnecessary and due entirely to the messy state of dune’s documentation.

I still do not understand why I need both a dune-workspace and a dune-project nor do I understand the purpose of this distinction. Some parts of the documentation recommend not checking the workspace file into source control unless some mysterious condition applies, which I think I have because generate-opam won’t pick up the dependency on bisect_ppx unless the workspace mentions it.

Speaking of generate-opam, it always generates a dev-repo line that won’t pass lint because the URL it finds makes OPAM mad. That seems suboptimal. Turns out this was my stupidity. A dumb typo.

These sorts of problems aren’t easy to correct when they arise because the logic that implements them is totally integrated into the dune tool, so fixing them entails trying to move a patch upstream. I think that’s my largest beef right now.


I encourage people to check out the free-form answers in the user survey for answers to the question that opens the thread.

My subjective summary would be that the most commonly-cited pain points are documentation, and the tools (with some people complaining in particular about the documentation of the tools). Other things people mention less frequently include the syntax and the lack of libraries.

I think this thread currently on the front page is also a good illustration of the sort of problems people have with the tools.


I would even like full ocaml scripts instead of a yet another language such as stanza.


I dabbled in OCaml for a bit, I love the type system and the fast compiler. For me the biggest hurdles were:

  • Tooling (Dune / Opam). They are quite confusing and different for someone coming from npm or cargo. Specially the part of pinning dependecies and reinstalling them. Why do I need to learn about switches, why can’t I just have a lockfile.

  • Structuring a project and the lack of namespacing. Figuring out how to structure a project in sub directories in a way that everything works. You need dune files everywhere. You need to learn too much about how dune works in order to structure a project using subdirectories. I had to look at many examples in github to figure out how to reference depencies. Some kind of automatic namespacing based on the file system would be much clearer.

  • Libraries documentation - Most documentation is very poor, the documentation is mostly the function signatures. It is very hard to figure out how to use something just by looking at a bunch of function signatures. Providing examples for each function makes a huge difference.


Or even, providing task-based examples in a ‘tutorial’ or ‘quick reference’ section. With many libraries it’s not obvious which functions are supposed to be the entry point, or how to integrate them into my system, so it’s good to know what the library author intended. As others have said here, some people are using the workaround of looking at the test code.


I totally agree, and it sounds like this should finally be fixed in the next version of dune.

BTW I’m very happy this thread exists. Hopefully we’ll keep updating it.


If documentation seems to be missing then check the .mli, in some cases the examples and documentation you are looking for are present there.
There is a bug in odoc currently which causes the module level documentation to vanish in some cases, and module level documentation is what would contain the examples, e.g. for Re.Posix it gives the impression that there is no documentation, or no examples, which isn’t the case.


I’m really excited about the potential for the new package documentation feature on ocaml.org to change the documentation story for the better. Just having documentation in one centralized place is an enormous improvement on the status quo. I think library authors will be more motivated to write docs when their docs are automatically generated, hosted, and easy for users to find.


That reminds be of other nasty (and quite old) bug (which I’m sure was reported but I don’t remember where), it seems that preambles are often discarded in the automatically generated doc: compare for instance: Tsdl · tsdl 0.9.9 · OCaml Packages and Tsdl (tsdl.Tsdl)
( the whole first paragraph " Consult the binding convention… etc" that can be found in the latter link has disappeared in the former.)

There are many other instances of this bug. The preambles of all modules of the Bogue doc have similarly disappeared.


Indeed you would expect such a bug to be high-priority. Another sad thing about Tsdl’s doc is that sections headers have links into the original SDL docs but odoc drops them, see this Cross-references and links are not allowed in headers · Issue #342 · ocaml/odoc · GitHub.

How can we motivate programmers to write docs if the tooling does not respect your work ?


If I might pour some petrol on this fire: every other language I see does at the very least color syntax highlighting of code in documentation and other type inferred languages provide tooltips in the browser so you can see the inferred types as if you were using an IDE.

No need to increase your carbon footprint on that one. odoc does syntax highlighting in code samples (random example). Inferring and showing the tooltips would be a more complicated business, since you’d need to compile the samples.


Yes ocaml.org’s doc inclusion has been really helpful. It’s one step more towards becoming npmjs and crates.io-like. I think adding autocomplete on the home page’s nav search bar is another nice incremental add.

1 Like

Yes! Although I’d personally prefer using the full power of font faces rather than colors, think Algol (bold keywords, highlight, italics, dim, etc…). The usual way to approach compiler output for examples is to hook the docs to a playground. A great example of executable examples is rust docs, and for tooltips is koka’s docs.

1 Like

I can consider myself as a newcomer. I have just rewriten a “real” program made to patch a bunch of MIDI files. It was written in Python, and I rewrote it in Ocaml.

I was guided toward the Janestreet’s Base and Stdio libraries by Real World OCaml… but it is quite hard to figure out what does the different functions. For example In_channel (stdio.Stdio.In_channel) doesn’t describe the semantic of all functions. I have picked input thinking it would read the whole file and return the read length. Only 65536 chars where read ! I should have written really_input_exn. Then I am puzzled… Should I use the StdLib which is better documented, or Base which I have read is better (and the reference library of the book I have purchased) ? (Python users don’t ask these type of question). (The Base libraries also lack Bytes.get_int32_be and comparable functions… then I have to deal with both documentations).

Some constructions are not friendly. Just compare

buffer[pos] += transposition


Caml.Bytes.set_uint8 buffer !pos ((Caml.Bytes.get_uint8 buffer !pos) + !ref_transposition)

But I have to admit that having a reference to a variable (the current position in a buffer) and pass it to a function is quite handy (In Python, I can only pass the value… and get in return the new value).

Then, I am puzzled… I have found Ocaml less surpising by moment (just forget a global keyword in Python…). Quite surprizing sometimes (if I forget some parenthesis). Since I am using Windows and didn’t manage to make lablgtk, lablgtk3, labltk work with Diskuv, I guess I should wait Ocaml5 + Opam2.2 (tier 1). Or try opam-repository-mingw. I have to admit that with Python, it is more straightforward (the Windows installer install Tkinter).

I know that most of this post doesn’t deal with the core language, but the choice of a language is also the choice of an ecosystem. And this is important.


This reminds me that I am still planning to work on improving the documentation for the new {In,Out}_channel of the standard library, but didn’t get the time to do it yet. If anyone around here is interested in submitting a contribution to the OCaml compiler codebase, I think it would be a fairly nice change that would benefit a lot of users in the future:

1 Like