4 ms·
I don’t like type inference myself. Code is read more than written. You really should be optimizing for better intent understanding than for easy typing. Types
by szastamasta 4y ago
I don’t like type inference myself. Code is read more than written. You really should be optimizing for better intent understanding than for easy typing. Types can usually be auto completed if they can be inferred.
I especially love the Java case with Idea. You infer the types, than IDE puts them back in as type hints (taking exactly the same amount of space). You end up with the same amount of code.
Also the example in the post is pretty bad. Your functions have an interface. You create them with some specific input and output in mind. With inferred types they can fit in many unexpected places. And they will be used in cases you have not anticipated. This has ripple effect. You end up with very generic type inferred as input for your functions (because it worked) and then you’re blocked from changing internals of the function as you cannot narrow the type.
- porcoda 4y agoType inference isn't about reading or writing code. It's about proving that the code is correct with respect to the language semantics: type inference and checking are relatively lightweight forms of code verification. If you have code that works and passes the type checker, and upon modification fails the type checker, that often reveals issues about how that code composes with code that calls it. That isn't "blocking" you from modifying the internals of a function: if those modifications cause the type checker to fail, you've likely got a problem with how that function is used. It isn't trying to make your life difficult - it's telling you that assumptions you may have made about your code in isolation are not valid assumptions when considering how that code you're working on interacts with other code that you aren't focused on. Type inference isn't an IDE feature related to autocompletion. If that's how you perceive it, you might benefit from learning what type inference is about and what role it plays in the development process.
- dllthomas 4y ago> Type inference isn't an IDE feature related to autocompletion. Except... it sorta is? The benefits you describe are real, but they are derived from type checking. In principle you can get the same effect while making all the types explicit. Without basic type propagation this is horrifically verbose to the point that no language I'm aware of rolls that way. Without type inference, it's usually manageable. Type inference is a (very!) nice to have feature on top of that where the compiler is kind enough to fill in the details it can figure out, which doesn't happen to live in the IDE (usually? ever?) but is basically the same idea as IDE autocompletion except that the result is not typically visibly reified (... outside of an IDE or equivalent). What I disagree with from the grandparent is the notion that the type annotations (that inference allows us to remove) always or overwhelmingly improve readability. I think the verbosity they add - particularly when they get repetitive - means they often obscure far more than they enlighten. And when they do pay their way - which is not rare - you are still free to include the annotation!
- gjm11 4y agoIt is true that code is read more than written, and I agree that code should be optimized more for easy understandability than for minimal characters typed. But in some cases leaving types to be inferred helps with understandability, because sometimes the details of the type are cumbersome and almost always irrelevant, and leaving them in costs you more in readability than it gains you in explicitness. This happens particularly often in C++, for instance, because C++ has a lot of ugly cumbersome types. Here's an example from Meyers's "Effective Modern C++". You're writing a templated function that takes an iterator range and does something with the things within that range. At some point it needs a variable to hold one of the values. template<typename It> void f(Int first, Int limit) { while (first != limit) { auto v = *first; // ... } } That's not so bad. But what if you want to make the type of v explicit? You need to write something like typename std::iterator_traits<It>::value_type v = *first; instead. That isn't any more enlightening, it's extremely unlikely to make any bugs easier to track down, and it makes the code harder to read because there's this blob of useless type-nonsense getting in the way. Another example from the same source; this time the issue isn't readability exactly but the fact that doing this stuff by hand is needlessly error-prone. (Again, specifically in C++ which is admittedly more error-prone than most languages.) You want to iterate over a std::unordered_map from string to int, like this: for (const auto & p : theMap) { ... } On each iteration, p will be (a reference to) a pair whose first element is a string and whose second element is an int. But you want to make all your types explicit, so you write for (const std::pair<std::string,int> & p : theMap) { ... } except that now you have a bug (which in this case only hurts performance) because actually what's in the map is pairs of const std::string and int, and that's a different type, so what your code will end up doing is copying every entry in the map into a temporary object before using it. The tradeoffs probably favour explicit types more often in languages that are tidier than C++. But the tradeoffs are always there.
- rowanG077 4y agoI honestly can't grasp this mentality. Very often types are so incredibly trivial that it makes no sense to include. Just like it would make no sense to write `1 + 1` as `((1: Int) (+: Int -> Int -> Int) (1: Int)): Int`. As if types add anything but clutter here. And many cases writing down types is just as unreadable as that.