How to keep the value of function pointer?

How to keep the value of function pointer?

This is roughly how the code looks like:

gCallBackFunc = Ref{Function}(func1)
...
callBack::Function = gCallBackFunc[]
...
gCallBackFunc[] = func2
...
callBack(params)

I want func1 (i.e. previously referenced function) to be called, after another value was assigned to gCallBackFunc.
Whatever I do, func2 is always called.

I tried to assign callBack several different ways, nothing helps:

callBack::Function = gCallBackFunc[]
callBack::Function = deepcopy(gCallBackFunc[])
callBack::Function = deepcopy(gCallBackFunc)[]
callBack::Ref{Function} = Ref{Function}(gCallBackFunc[])

Thank you,

The code you showed here works fine:

julia> begin
         x = Ref{Function}(sin)
         @show x[](0)
         s = x[]
         x[] = cos
         @show s(0)
         @show x[](0)
         nothing
       end
(x[])(0) = 0.0
s(0) = 0.0
(x[])(0) = 1.0

So clearly there’s some difference between your actual code and the MWE you posted here.

2 Likes

I apologize. I had a typo elsewhere and it caused as if I am not getting the proper function value…

On a separate note, this kind of type annotation is generally not needed — the Julia compiler is perfectly capable of inferring types. Adding a lot of superfluous type declarations clutters up your code and can make your code less flexible, for no performance benefit.

(See also argument-type declarations in the manual for a related discussion, but the case for declaring types of local variables is even weaker. The main case where I’ve seen it used is to force certain type promotions in numerical code, but even there one wants to be careful not to lose genericity.)

1 Like

I came from C++ world, thus I naturally feel much more comfortable having variable type. Regardless of that, and excepting Function type in this example, I find 2 main advantages of having the type declared:

  1. Code is more readable. Variable has a type and it is easy to understand what is going on.
  2. If assignment to typed variable fails (throws an exception) it is easy to trace it down immediately and fix it. Without a type declared on variable, bug can live quite longer.

It is a strategy and a valid one at that, I just think you should be aware that the main pitfall of it, this is, in the future, you may discover some kind of callable struct that does exactly what you but does not inherit from Function and you may discover all of your code would work seamlessly with it, except by your type annotations.

Of course, in the case of Function the workaround is simple: just wrap whatever callable inside an anonymous function. However, for other types it may be a pain to be wrapping or converting everything to the types you artificially restricted yourself to.