MWE below, it appears that rather than using a function in a preexisting world age, FunctionWrapper uses the first eval
ed method inside a function but not any after that; EDIT unless you redefine the function after a call even with identical code, or if the inner eval
ed function was called before. If someone has an explanation that would be great, but otherwise this could just be an FYI. EDIT: Just in case, you should never do this without invokelatest
because there’s no benefit to making a method invalidate its own compiled code on every call.
julia> function foo(n)
for i in n:n+1
@eval fooi() = $i
println(fooi())
end
end
julia> foo(1)
ERROR: MethodError: no method matching fooi()
The applicable method may be too new: running in world age 32434, while current world is 32435.
Closest candidates are:
fooi() at REPL[1]:3 (method too new to be called from this world context.)
...
julia> fooi() # foo(1) made fooi()=1 before error
1
julia> foo(2) # uses preexisting fooi()=1
1
1
julia> using FunctionWrappers: FunctionWrapper as Fw
julia> function bar(n)
for i in n:n+1
@eval bari() = $i
println(Fw{Int, Tuple{}}(bari)())
end
end
bar (generic function with 1 method)
julia> bar(1) # doesn't error, but only uses 1st bari()=1
1
1
julia> bari() # last run made final bari()=2
2
julia> bar(3) # uses 1st bari()=3, not preexisting bari()=2
3
3
julia> function bar(n)
for i in n:n+1
@eval bari() = $i
println(Fw{Int, Tuple{}}(bari)())
end
end
bar (generic function with 1 method)
julia> bari()
4
julia> bar(5) # now uses preexisting bari()=4
4
4
Now evading this effect to be more in line with world age issues:
julia> using FunctionWrappers: FunctionWrapper as Fw
julia> bari() = 0
bari (generic function with 1 method)
julia> function bar(n)
for i in n:n+1
@eval bari() = $i
println(Fw{Int, Tuple{}}(bari)())
end
end
bar (generic function with 1 method)
julia> bari() # this call is crucial to avoid the previous effect
0
julia> bar(1) # uses preexisting bari()=0
0
0