That's apologist talk pure and simple. The language, silently, does something that's almost certainly wrong. The language has enough information to provide you with a helpful warning or error message that you probably don't want to do this, but instead, it violates the principle of least surprise by just doing the wrong thing instead.
The correct error is something along the lines of:
let numbers = input.iter().map(parseInt).collect::<Vec<_>>();
--> src/main.rs:10:32
|
4 | fn parseInt<T>(input: T, radix: u32) -> Option<i32> where T: AsRef<str> {
| ----------------------------------------------------------------------- takes 2 arguments
...
10 | let numbers = input.iter().map(parseInt).collect::<Vec<_>>();
| ^^^ expected function that takes 1 argument
This isn't rocket science, it's basic language design. From time immemorial engineers have been making mistakes as they write software, so compilers evolved not to pretend otherwise and hope for the best, but to help engineers catch them. Except for one.
The map function fully expects a function with two arguments, as per documentation. Why would passing a function that takes two arguments to map be an error?
The map function has a bad API surface that interacts poorly with the way people expect it to work. In a better designed API, if you needed the index of each yielded value other languages have some kind of enumerate method that will allow people opt-in to getting the index. Then if you needed the replicate the presented situation you would have something like
I understand that this pattern of having extra "helper" arguments is pervasive in JS and might seem less exotic to the community, but I feel it is a problematic approach, as it is foot-gun prone.
The example given is taken from Rust. Rust does not allow overloading (even in terms of optional parameters, I believe). Well, Rust allows overloading by implementing different traits but then forces you to disambiguate where necessary.
Nah, there's better solutions; you can create a window/stride method that converts a sequence into a sequence of sequences and then passes that into a map function that takes a single argument.
If Rust had ergonomic support to pass multiple arguments to a functions you would still not be protected from this bug. Even the type system wouldn't help you there because the index would be of type usize and so would be the radix argument in parseInt (although in reality this would probably be an enum or u8). But this is caused by the interaction of two bad APIs. Even if we have the restriction that it confirms to the over two decades old signature, map should only yield each element of the input and yield back the result of the closure. If you need the index you could chain a call to enumerate before the map and get tuples of value and index. This is what you'd have to do in Rust and Python, for example.
Surprise! You need to know the basics of how your language works.