title: In the Julia language, how are function compilations reused?
body: <p>I'm toying around with Julia, and I have run into a question about the compiler/JIT compilation scheme that Julia uses.  If I write a function such as</p>
  <pre><code>function f(x) 
    return mapreduce(*,+,x,x)
  end
  </code></pre>
  <p>Then since this function works on abstract arrays, its shape can't be known until it's used, so it can't be compiled.  Then if use this in a function, <code>g</code>, whose inputs are arrays of arrays of floats like so:</p>
  <pre><code>function g(y) 
    return mapreduce(f,+,y)
  end
  </code></pre>
  <p>Or alternatively</p>
  <pre><code>function g2(y) 
    res = 0 
    for x in y 
      res = res + f(x)
    end
    return res 
  end 
  </code></pre>
  <p>Then, when we use <code>g</code>, say <code>g([[1,2],[3,4]])</code>, eventually <code>f</code> will be called.  Say it's called on <code>[1,2]</code> first.  Then it's compiled, and evaluated.  As far as I can tell, since <code>f([3,4])</code> is on the exact same type as <code>f([1,2])</code>, <code>f</code> will be reused (since the inputs are both 2 dimensional arrays of numbers).  However, when I type <code>@code_llvm(f([1,2]))</code> and <code>@code_llvm(f([3,4]))</code> I see that the names of the functions are different (they do have a common prefix, something like <code>julia_f_</code> and then its followed by a number).  Also, if I call <code>@code_llvm(f([1,2]))</code> again, I get yet another name.</p>
  <p>Does Julia indeed allow <code>g</code> to reuse the compiled version of <code>f</code> for each application?  Does this depend on the length of the arrays involved; i.e. in <code>g([w1,...,wn])</code> does each <code>wi</code> have to have the same length for <code>f</code> to be reused?</p>