So afaik, it is accepted function pointers are not needed in Julia since we can pass functions, into other functions, causing the appropriate method to be compiled just in time, so that there shouldn’t be any performance hit.
However, and I might be missing somewhere here, this doesn’t really seem to work well if functions have an indefinite runtime, like in some indefinitely running simulation or a game, where the user might want to change the algorithm during runtime.
Let’s say I have some simulation that runs continuously on the data of some struct
mutable struct SomeStruct
algorithm::Function
data::...
end
function loop(s::SomeStruct)
while true
s.algorithm(s)
if quitsim(s)
return
end
end
Now I’m not super well versed in C++, but I’m a bit familiar with it, and as far as my understanding goes, I could make s.algorithm a function pointer with a fixed signature, and just swap them out during runtime, without any performance hit.
Right now in julia, since functions are of a singleton type, my code is type instable and thus slow. The compiler doesn’t know anything (?) about the type of function that could be found in the field algorithm
so I get generic code which is slow. I could pass the function to the loop function as an argument, but then I have the problem that I have to quit out of the loop and recompile it during the runtime of the simulation. I could also add the function type to the struct, but then I cannot swap it out anymore during the lifetime of the loop.
Another similar usecase is where I’m running something on a continuous loop or timer, but I want to a number of functions with the same signature that can be changed during runtime. As an example I have an interface with update functions that update their respective elements in the interface. I might want to open or close windows and add these update functions to an async loop run from a timer (such that they’re called e.g. 60 times per second) or some async loop. In julia this is again type instable since you’re only telling the compiler that it will find some functions it can call during runtime, and not what type of arguments they expect and what type they will return.
Now again, I’m just kind of familiar with C++, so maybe these designs are to be avoided in the first place. I’d be very interested to know how one could deal with these situations in a Julian way.
Also, could it make sense to expand the type system in julia to allow for precompiled methods with fixed signature? I.e. such that we can have vectors or fields that allow for any method of the given type, allowing for fast execution methods that are of unknown type (but known signature) during compile time.