Trying to understand optimization via multiple dispatch and type stability

method is what you define. Specialization is what the compiler generates. You can have a function f with a single method f(a, b) = a + b but when you call it with f(1, 2) and f(1.0, 2.0) the compiler will likely generate two specializations for it. Whenever you said “method” above, you were almost always talking about specialization and not method in “generic function with 163 methods”.

It looks at the code of the function and infer the type, that’s what type inference is doing. You can look at the result using code_typed, check the doc for it for more details/tools.

Well, julia cannot know the concrete answer all the time. Knowing the output type of a function in all cases is undecidable. However, it is still possible to compute an upper bound of the type. If julia cannot find the definition of a function and it believes it can be supplied later, it can just assume the return type can be anything. There’s no case where inference have to throw an error so you can never expect the absense of an error to tell you anything about inference (other than you didn’t hit a bug).
Also, inference is run after the input types are known. Simply defining a function without using it anywhere usually gives no hint to the compiler what to infer from. Of course if you defined a function that can only accept one set of concrete type input then the compiler could infer that method and generate specialization for it. However, the compiler usually don’t do extra work unless it has to so this is not done except when it makes sense to be aggressive about compilation (e.g. when precompiling packages/generating system image).

1 Like