Of course I'm writing invalid code: that's why I'm getting error messages. The problem is that I'm having trouble understanding why it's invalid. Error messages are supposed to help me here, but quite often they didn't.. they just led to more confusion... especially in complex code, where I needed help and clarity most.
That's reasonable if the error message were "This expression is of type X but an expression was expected of type Y". But the worst error message in the OCaml interactive toplevel is when they're the same. This happened when you defined a new type named X (which, incidentally, must be lowercase), but there were still references to things of the old type X.
I think this has been fixed in recent versions of OCaml.
The problem is that it would happen often in the interpreter when you were interactively trying stuff out, because when you're trying stuff out, you change the definitions of things.
Python actually sort of has the same problem not only when you use an interactive interpreter but even when you reload a module: the new class definitions don't modify the old one, they just get bound to the same name. So it's easy to end up with two alglayout.Vbox classes or two diff.Formula classes in the same interactive interpreter at the same time. But it's much less of a problem in Python because Python usually doesn't care what class things are, just what methods they define, so objects belonging to both classes can coexist peacefully. The usual exception is when you have an isinstance check somewhere.
The type checker and the type inference parts of the compiler are one and the same. If the type checker can’t infer what you mean you are most likely writing invalid code.
> Error messages like "This expression is of type X but an expression was expected of type X" were not uncommon, and super frustrating.
Ocaml is a strongly typed static language. As such your code has to respect type constraints. It’s very much a feature not a bug.
Still to be less defensive I too sometimes wish the error messages were more clear in highlighting why a certain type was expected but at least Ocaml provides tooling to live check the inferred type of any sub-expression while you edit your code.