Some reasons in favor of explicit typing (I am not talking about static vs dynamic here, just about the possibility annotate the expected type of a certain thing):
1. It can serve as code documentation. In some cases, with some kinds of programmers, the only documentation that you have is code itself (although this would require compulsory explicit typing which doesn’t happen always – groovy, caml and scala are examples of exceptions – in many cases saying the type is optional)
2. It helps IDEs help you. There is some discussion that IDEs for non-explicit (actually dynamic) languages can be as helpful as static languages. Well, if the information is there, then surely the IDE case use it and help you.
3. Bugs. Maybe your function is working and should not be working. Maybe the object, which should never be passed to that function is responding just because there is a signature that matches. I find this pattern somewhat common: a) There is a function parameter (without the explicit type) on a buggy function call. b) I put the type in on the called function. c) It immediately becomes clear that somewhere I am passing something that shouldn’t be going in in that form, a pseudo-code example:
myFunction(a, b) {
String x = a + b
print x.toUpperCase()
a should be a String (+ is a concatenation), but for some reason myFunction gets called with a as an integer and kaboom (+ is interpreted as addition).
This can be quite insidious with type inference (CAML for sure, probably Scala also) where you can get a bug on a chain of say, myFunction3 calling myFunction2 where the bug is somewhere else (say another myFunction1 which also calls myFunction2): When the compiler reads myFunction1 it does a wrong type inference about myFunction2. Afterwards, when the compiler passes on myFunction3 it complains, but the bug was caused elsewhere (so the information from the compiler is useless). If you put the type on myFunction2, the compiler will whine on the correct place (on the myFunction1 call). These bugs can be a pain to detect because sometimes the chains can be long. I had the “pleasure” of spending countless nights with caml tracking these bugs. 15 years ago, but I still remember.
Anyway, non-compulsory explicit typing (a la Groovy, Scala, CAML) is a good compromise (use it if you like it). In fact, in some cases it is good to be lazy anyways
PS – As far as I remember in Groovy and Scala there are cases where explict typing is compulsory anyways (correct me if I am wrong). I would suppose that comes as a need as those languages and JVM and Java friendly by design and the compiled code will require that info.