On Thursday, July 24, 2014 6:58:33 PM UTC-4, [email protected] wrote: > > Regarding Steven Johnson's suggestion, I am unclear about a certain point. > Suppose, following Steven's suggestion, I define > > isless_eq(x,y) = !isless(x,y) && !isless(y,x) > > First question: this is equivalent to: > > isless_eq(x::Any,y::Any) = !isless(x,y) && !isless(y,x) > > correct? > > Now suppose I have another function in which there is an invocation > isless_eq(a,b) where a and b are both Int, and the compiler knows that they > are both Int. > > Does the compiler generate a specialized version of isless_eq with the > comparison for Int hard-coded? Or does the above definition of isless_eq > generate a single function called isless_eq that decides at run-time using > some kind of dispatch table which version of isless should be invoked? >
The former. When a function is called for the first time, a specialized version is compiled for the types of its arguments. This compiled version is then cached and re-used for function calls of the same types. So, when you call isless_eq(3,4), it compiles a specialized version for Int arguments, which calls the specialized version of isless for Int arguments, with no runtime overhead. When you call isless_eq(3.0,4.0), Julia compiles *another* version specialized for Float64 arguments. And then if you call isless(4,5), it calls the precompiled Int version. This process repeats recursively. e.g. if you have a sorting function that calls isless_eq, it will dispatch to the correctly typed, precompiled version of isless_eq at compile-time, not runtime (assuming it can infer the types at compile time).
