I always held automatic type inference as one of Julia’s distinguishing features. Why are packages full of type qualifications? Is it the performance improvement, error handling or just the coolness factor?
P.S.
I hope Julia programs do not start looking like C++ in terms of readability.
mostly not (there are only specific situations where type annotations - in functions - may improve performance). Types in declarations of structs are important, though.
This is probably the most common use. Sometimes the code gets clearer to use and debug with type annotations. Also for dispatch, when the type annotations define to which type of variable each method works (actually this is the most important use).
But to actually understand your question, maybe you would like to post some example, so a more precise answer of why annotations were used in some specific case.
Just guessing, but I think it constrains to Real and Int because other types (complex and non-integer correspondingly) may technically work, but are unlikely to yield correct results.
A simpler example would be abs(x) = sqrt(x^2): this function “works” when passed complex numbers, but the result is nonsensical.
Yes, it seems to be a form of error handling. The error for complex input (above) does not say complex values are nonsensical; it says that the method signature does not match. There is a difference here i think.