4 ms·
It 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. Bu
by gjm11 4y ago
It 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.