def add(a, b):
return a + b
add(1, 2) # Works
add('a', 'b') # Works
add(1, 'b') # Type error!
So changing one line should never break things outside its "light cone" (call stack + reachable data structures).This only gets harder with more type inference, as the actual issue may be far away from where the type error occurs.
This is why in haskell it is considered best practice to add type annotations to all top level definitions, at the very least.
But in practice it's quite handy to annotate module interfaces and even individual functions.
> But in practice it's quite handy to annotate module interfaces and even individual functions.
Yes, but it also limits what information the types can represent because of syntax and human patience limitations. A fully inferred language could associate numbers with possible value ranges, lists with their sizes, enumeration of fixed string values, etc.
Global type inference is literally this. Inferring types leaves gaps in the typing information, being global means the gaps can be arbitrarily large, and so a type conflict could theoretically span every line of a large program.