julia
julia copied to clipboard
add a section in the performance tips about not overly specializing on functions
This is a WIP to document best practices for cases where one wants to use the equivalent of a function pointer in Julia (specializing on the argument types but not the function itself).
Some TODOs:
OpaqueClosureshould not be experimental if this is to be recomended.- It is not clear if there should be some higher level concept (like a
FunctionWrapperor a convenience functionwrapfunction(g::G, ::Type{AT}, ::Type{RT})) on top of OpaqueClosure that should be used instead of directly using theOpaqueClosure
AFAIU, OpaqueClosures does not respect function redefinitions which means you want to create them "as late as possible" (but not later than needed).
In the guide here, the MyProblem struct is changed to
struct MyProblem{Input, Output}
domain::Domain
boundary_condition::Core.OpaqueClosure{Input, Output}
end
but this would be problematic if one does:
function bc(x) x->x^2 end
myproblem = MyProblem(domain, bc)
function bc(x) x->x^3 end
solve(myproblem)
instead, one should perhaps do something like
mutable struct MyProblem{Input, Output}
const domain::Domain
const boundary_condition::Function
_boundary_condition::Core.OpaqueClosure{Input, Output}
end
function solve(x::MyProblem{Input, Output})
x._boundary_condition = Base.Experimental.@opaque Tuple{Float64} x -> x.bounday_condition(x)::Float64)
...
end
to manually redefine the OC before it will is used. That however forces the struct to be mutable and you might forget to redefine the OC in some code paths etc.