it’s because const
is missing, see here
so, here’s the solution for calling scope evaluation, despite the fact that only relatively simple expression could be handled:
function expr2fun(ex)
vars = getvars(ex)
return eval(:($Expr(:meta, :inline); $vars -> $ex) ) # is it the correct way to inline???
end
getvars(ex) = Expr(:tuple, _getvars(ex)...)
_getvars(ex::Symbol) = [ex]
function _getvars(ex::Expr)
vars = Symbol[]
if ex.head == :call
for arg in ex.args[2:end]
append!(vars, _getvars(arg) )
end
end
return unique(vars)
end
_getvars(ex) = Symbol[] # fallback
ex = :(x * (y - x) - (x * y - 2) )
const fun = expr2fun(ex) # const is needed to avoid warntype !
@inline f1(x, y) = x * (y - x) - (x * y - 2)
@inline f2(x ,y) = fun(x, y) # calling slope evaluation
julia> f1(1, 2) == f2(1, 2)
true
julia> @btime f1(1, 2);
0.022 ns (0 allocations: 0 bytes)
julia> @btime f2(1, 2);
0.022 ns (0 allocations: 0 bytes)
julia> @btime fun(1, 2);
0.022 ns (0 allocations: 0 bytes)
hope it helps.