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). 

Reply via email to