>Grain is strongly typed (with a typechecker from OCaml)
I tried working on a complex OCaml project where the author had written as little type annotations as possible. It was a horrendous experience because it was impossible to determine the type of most variables by reading the code. I had to use a language server to obtain type information and I had to consult it very often. I hope they don't proliferate this nonsense and instead require type annotations for top-level definitions like Haskell does.
Most OCaml users I know use emacs with tuareg-mode and merlin (or the equivalent in vim). Once you've got that set up (and it's a breeze these days with opam user-setup) it's super easy to navigate an OCaml code base and access type information on demand.
This is a feature, not a bug -- getting the type of an arbitrary expression is two keystrokes away, but there's no visual clutter from excessive type annotations. And the tooling goes well beyond this one feature.
Working in OCaml without merlin+tuareg feels like having a hand tied behind your back (to me), so I feel your pain. This certainly raises the barrier to entry slightly, but I think it's worth it for the convenience and ergonomics once you're past that initial barrier.
Why have it 2 strokes away when it can be 0 strokes away? I don't mean this for every definition, just for top-level definitions and class members and methods. I'm a fan of type inference and clean code too, but I also want the code to be documented and human-readable.
in many cases you're probably right that mandatory type annotations would improve readability. Taking the rhetorical question very literally, though, there are some times when having it two keystrokes away is very helpful. I often query the type of a large expression (e.g. a partially applied function to remember what argument comes next) or the signature of some module
After having worked many years with OCaml and a few years with Rust, I prefer the latter's approach of requiring types in function declarations (or equivalently requiring a .mli in OCaml). This makes browsing in code much faster and removes sources of incomprehension.
Good OCaml projects almost always have interface files with thorough type annotations and documentation. It's the best of both worlds–the implementation files are free of the clutter of types, and the interfaces are strongly specified.
+1 to this -- good point! It sounds like the legacy project that the parent comment mentioned probably wasn't a "good" project in this respect, though.
This has a number of advantages vs. the `export` syntax used in Grain, too. Being able to look at one `.mli` file for a well-documented public interface is much easier than looking through a source file for what's been exported and what hasn't.
I tried working on a complex OCaml project where the author had written as little type annotations as possible. It was a horrendous experience because it was impossible to determine the type of most variables by reading the code. I had to use a language server to obtain type information and I had to consult it very often. I hope they don't proliferate this nonsense and instead require type annotations for top-level definitions like Haskell does.