4 ms·
> Type Inference is Bad > So when you make a mistake, you’re still giving constraints to the inference engine. Erroneous type inferences propagate in every dir
by Georgelemental 4y ago
> Type Inference is Bad
> So when you make a mistake, you’re still giving constraints to the inference engine. Erroneous type inferences propagate in every direction. Error messages appear hundreds of lines of code away from their origin.
Rust gets this right: it has type inference, but only within the function body. Most of your code is free of annotation cruft, but interfaces are strongly specified and errors can only propagate a certain distance.
- deleted 4y ago[deleted]
- yawaramin 4y agoThat's why it's idiomatic in OCaml to write interface files which contain type annotations for the modules. In practice many or most modules (over time) are given interface files which strongly contain the area of effect of type inference.
- IshKebab 4y agoIs it? I've only done a bit of OCaml (working on Sail) but that doesn't have any type interface files.
- rwmj 4y agoIn virt-v2v we eventually enforced that every module file also has a corresponding interface file: https://github.com/libguestfs/virt-v2v/blob/master/check-mli.sh https://github.com/libguestfs/virt-v2v/blob/master/check-mli...
- IshKebab 4y agoProbably if you need to do that it should just be enforced by the compiler. It's pretty clear to me (and the author of this post) that Rust got this right - small scale type inference is fine (in function bodies) but you really want explicit types for functions and up. Without that, you lose out massively on readability and error message quality. In Sail, I have IDE type inlays working but it barely helps with reachability because half the types are inferred as generic.
- rwmj 4y agoAs a user of OCaml I have to disagree. Rust requires far too many type annotations and they are mostly unnecessary and clutter everything up (particularly with it's very heavy syntax). In OCaml my editor shows me types if I mouse over a variable, and if I need to document the code I can add annotations, but that is rarely needed.
- IshKebab 4y agoMy point is it isn't very useful if half the types are 'a
- alasdair_a 4y agoWe do have type interface files for almost every .ml file
- deredede 4y agoI know this is an unpopular position in the OCaml ecosystem, but I find .mli files to be in all ways inferior to the "inline" approach Rust (amongst others) take. OCaml requires perpetual context switches between .ml and .mli files, which can be alleviated with proper IDE tools but is still annoying, but most annoyingly requires writing every type definition and module signature twice. On the other hand the OCaml/interface files approach is superior when you want to read documentation w/o implementation, but in practice using odoc is superior because you get hyperlinks. In 10 years of using OCaml, I think everytime I interacted with mli I'd rather the author annotated types at the definition site.
- yawaramin 4y agoThat's funny because I feel the opposite. An interface file saves me from having to wade through the implementation details and lets me focus on the exact parts that are relevant to me as a reader of the code. And yes odoc is nice too but the source of its usefulness usually comes from the fact that it's generated from a carefully curated interface file.
- eviks 4y agoWould type "dehints" be the best of both worlds: you IDE could hide all the types (just like with type hints it adds them) and you could toggle them to eg hide when reading the code? But then also you could toggle them back when needed instead of having to open an interface file?
- rwmj 4y agoOCaml IDEs including emacs can do that already, and yes it's a good thing.
- deredede 4y agoIn my opinion the best of both worlds would just be to have Rust-style inline annotations and an "interface mode" that hides implementations (most modern IDEs can already do that) and non-public function. BTW I am not sure why you would want to hide the types, I find them always useful.
- pharmakom 4y agoI disagree with the article here (and it’s a good article overall!) The compiler simply needs to be armed to detect this pattern and give better error messages. Vast majority of cases the user simply forgot an argument.
- dllthomas 4y agoI think Haskell gets this close to right, actually. If always adding the type to every function is always better, I can do that. But as it turns out, occasionally during development looser error locations if I hit a relevant error is a reasonable price to pay for not having to update a signature or two while I iterate. Haskell community norms say you should annotate top level functions before you share the code, and any particular team can make that stricter. I don't think there's actually a good reason to require it on every single build regardless of the purpose of that build.