I get
julia> model(2.2; settings=[1,1,1.0])
ERROR: UndefKeywordError: keyword argument pars not assigned
when running your code.
Edit: With updated code I get that both of these infer to Any
.
Edit 2: I think this has something to do with inference state dependence: For example:
julia> @code_warntype M(2.2) # still Body::Any
Variables
#self#::Core.Const(M)
x::Float64
Body::Any
1 β %1 = (:pars,)::Core.Const((:pars,))
β %2 = Core.apply_type(Core.NamedTuple, %1)::Core.Const(NamedTuple{(:pars,), T} where T<:Tuple)
β %3 = Base.vect(1, 1, 1.0)::Vector{Float64}
β %4 = Core.tuple(%3)::Tuple{Vector{Float64}}
β %5 = (%2)(%4)::NamedTuple{(:pars,), Tuple{Vector{Float64}}}
β %6 = Core.kwfunc(Main.model)::Core.Const(Main.MyTest2.var"#model#3##kw"())
β %7 = (%6)(%5, Main.model, x)::Any
βββ return %7
julia> @eval Base begin
sum(f, a; kw...) = mapreduce(f, add_sum, a; kw...)
end
sum (generic function with 14 methods)
julia> @code_warntype M(2.2) # still Body::Any
Variables
#self#::Core.Const(M)
x::Float64
Body::ComplexF64
1 β %1 = (:pars,)::Core.Const((:pars,))
β %2 = Core.apply_type(Core.NamedTuple, %1)::Core.Const(NamedTuple{(:pars,), T} where T<:Tuple)
β %3 = Base.vect(1, 1, 1.0)::Vector{Float64}
β %4 = Core.tuple(%3)::Tuple{Vector{Float64}}
β %5 = (%2)(%4)::NamedTuple{(:pars,), Tuple{Vector{Float64}}}
β %6 = Core.kwfunc(Main.model)::Core.Const(Main.MyTest2.var"#model#3##kw"())
β %7 = (%6)(%5, Main.model, x)::ComplexF64
βββ return %7
The function I evalled is indentical to the earlier one and only serves to re-compile functions.
Before the eval we had:
β @ reduce.jl:501 within `sum'
β β %3 = invoke Base.:(var"#sum#216")($(QuoteNode(Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}()))::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, %1::typeof(sum), %2::Function, _4::Base.Generator{Base.Iterators.Zip{Tuple{Vector{Float64}, Vector{NamedTuple{(:N, :k, :p), Tuple{Int64, Float64, Float64}}}}}, Main.MyTest2.var"#2#5"{Float64}})::Any
after it changes to (look at return type in the end)
β β @ REPL[9]:2 within `sum'
β β %3 = invoke Base.:(var"#sum#865")($(QuoteNode(Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}()))::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, %1::typeof(sum), %2::Function, _4::Base.Generator{Base.Iterators.Zip{Tuple{Vector{Float64}, Vector{NamedTuple{(:N, :k, :p), Tuple{Int64, Float64, Float64}}}}}, Main.MyTest2.var"#2#5"{Float64}})::ComplexF64
Also, see the allocation difference:
julia> @btime M(2.2)
521.423 ns (13 allocations: 480 bytes)
-1.7454668760152625 + 4.251554706912252im
julia> @eval Base begin
sum(f, a; kw...)= mapreduce(f, add_sum, a; kw...)
end
sum (generic function with 14 methods)
julia> @btime M(2.2)
440.561 ns (6 allocations: 256 bytes)
-1.7454668760152625 + 4.251554706912252im