for (Map.Entry<SomeLongType, AnotherLongType> x : someMap) {
final SomeLongType key = x.getKey();
final AnotherLongType value = x.getValue();
...
}
In the above code snippet, `var x` would have been very useful because the actual type just repeats information that can be found in the next two lines. Also, usually, I'll use more speaking names instead of `key` and `value`.But if the body of the loop just refers to `x.getKey()` and `x.getValue()`, without extracting them into local variables, then it makes sense to put the exact `Map.Entry` type into the loop header.
for (Map.Entry<SomeLongType, AnotherLongType> x : someMap) {
final var key = x.getKey();
final var value = x.getValue();
...
}
Is valid. for (var x : someMap) {
final SomeLongType key = x.getKey();
final AnotherLongType value = x.getValue();
...
}It's 2020. Why couldn't things work like this, where one can open a window for a concrete type using templates, and it shows the code?
If I say "A good CPU has more than two cores in 2020." then I'm just saying it's a requirement, not sufficient all by itself. I'm not calling a twelve-year-old phenom X3 a good CPU. The "in 2020" is just to emphasize that anyone failing this standard is falling behind the times.
https://devblogs.microsoft.com/cppblog/template-intellisense...
Now try that on vim.
MyClass myVar = new MyClass()
is not DRY. It also makes it practical to use complicated structures out of generics/templates without killing the developer With<Deeply<Nested,Template>, Declarations>. MyClass myVar = something ? SomeFunction() || somethingThatMightBeASubClassOfMyClass var myClass = ...
(or some other descriptive name of the variable)?Like, in C#
List<Account> accountsToDelete = accountService.GetAccountsToDelete();
repository.Delete(accountsToDelete);
becomes var accountsToDelete = accountService.GetAccountsToDelete();
deleterService.Delete(accountsToDelete);
So as much type information is already encoded into names so that all references to this object are clear in what we're handling, and so the type declarations at the point where the variable is declared is just redundant noise.If your variables aren't informative when I'm reading the code, I'll be confused 5 lines later anyways. So make them informative at the start. And given that, doesn't that mean the List<Account> is a bit redundant?
Of course good tooling is still a big requirement, but I still think it's the best decision in the long-term: it's way easier to improve and change tools like IDEs (especially with LSP?), rather than the language itself.
Regarding explicit types in functions, you also don't always need them in languages such as OCaml. I feel that the answer to your criticism could be to just have "auto" also for function arguments, especially when you're just prototyping.
There are many cases where the type is clear however or irrelevant or in generic code is hard to express (thus depending on documentation/comments unless obvious) which would also be hard to read.
Most people will tell you, "oh just use auto, it makes the code more generic". That's sweet, except as soon as I want to pass it to another function, I need to have the concrete type. Like you, I usually just copy-paste the full type from the error message and move on.