In some static languages, the inferred type for a and b could be Numeric, and foo's type could be:
(Numeric, Numeric) -> Numeric
Which seems good enough to me.
But what if + is also String concatenation? Or any other overloading of "+". Then maybe the type of a and b is Something_that_can_be_+ed. The user can then think "ok, I'll pass a couple of Ints to obtain an Int, or a couple of Strings to obtain a String!". This also seems useful to me.
var price = document.querySelector('input#price').value; // "10"
var tax = document.querySelector('input#tax').value; // "1"
var total = foo(price, tax); // "101"
This will concatenate two strings together, even though the author intended to add two numbers. If the foo function had been annotated as numeric the IDE could have provided a warning about the incorrect types and put a squigly line under foo.
I find this type of fast feedback improves programmer productivity. It means that you get warned straight away, and don't have to do a trip through the debugger to find the problem.
Just because the compiler can infer that a specific type could be passed to a function, that does not mean that the developer intended that function to be used with that type.
Oh, agreed. I assumed foo was meant to be generic, i.e. useful over more types than just Int. If it was just meant to be used for Int and nothing else, it should be annotated accordingly. Otherwise the compiler, quite correctly, determines that foo is more "generally useful", which may have unintended consequences.
What should an IDE tell the user about the types of a and b in the completion popup?
function foo(a, b) { return a + b; }