julia icon indicating copy to clipboard operation
julia copied to clipboard

add a section in the performance tips about not overly specializing on functions

Open KristofferC opened this issue 1 year ago • 1 comments

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:

  • OpaqueClosure should not be experimental if this is to be recomended.
  • It is not clear if there should be some higher level concept (like a FunctionWrapper or a convenience function wrapfunction(g::G, ::Type{AT}, ::Type{RT})) on top of OpaqueClosure that should be used instead of directly using the OpaqueClosure

KristofferC avatar May 06 '24 12:05 KristofferC

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.

KristofferC avatar May 13 '24 10:05 KristofferC