Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Julia have `Base.invokelatest`?

Tags:

julia

It seems like it just calls the function. When is it needed? It seems much slower than calling the function directly.

like image 397
Lyndon White Avatar asked Sep 01 '19 20:09

Lyndon White


1 Answers

Consider the following example, Where a function bar uses @eval to redefine foo before calling it

julia> foo() = 1
foo (generic function with 2 methods)

julia> function bar()
           @eval foo() = 2  # remember @eval runs at global scope
           foo()
       end
bar (generic function with 1 method)

julia> bar()
1   # Got old version

julia> function bar2()
           @eval foo() = 3  # remember @eval runs at global scope
           Base.invokelatest(foo,)
       end
bar2 (generic function with 1 method)

julia> bar2()
3

Because by the time bar calls foo bar has by its nature already been compiled, and so foo has been optimized as a static call. (probably inlined even in this case).

So bar can’t see the newly overwritten foo that was created via @eval

It is slower because it prevents the call compiling down to a static dispatch.

Generally you should never need this This kinda code is not good. Try and avoid using @eval inside functions. It is hard to reason about.

like image 88
Lyndon White Avatar answered Oct 07 '22 10:10

Lyndon White