Redefined functions do not pass correctly as arguments

question

#1

Hi.

I’m having trouble with passing redefined functions as arguments of other functions (in my case, constantly redefined objetive functions to a minimizing method). The following behavior is observed in kernels 0.5.0 and 0.6.0-dev but not in 0.4.7 (I’m running a jupyter notebook at juliabox.com).

A minimal example is the following:
h(f::Function, n::Int) = f() + n # Define a function taking some arguments f() = 10 # Define a function to be passed as argument h(f,1) # This output 11 correctly

But if now we redefine “f”:
f() = 20 h(f,5) # This output 15!

That is, the function h takes n correctly but not the new function f (it should return 25).
For now, my solution is working on 0.4.7 but I wonder if there is an explanation for this behaviour (I already read this for example, but there is not a clear response).


#2

this is http://github.com/julialang/julia/issues/265 fixed on master


#3

On julia v0.5 you can work around issue #265 by making f() an anonymous function instead:

julia> h(f::Function, n::Int) = f() + n
h (generic function with 1 method)

julia> f = () -> 10
(::#1) (generic function with 1 method)

julia> h(f, 1)
11

julia> f = () -> 20
(::#3) (generic function with 1 method)

julia> h(f, 5)
25

#4

But what if f is a complicated function in which their definition requires non-inline computations?


#5

Anywhere you can place a single expression in Julia, you can also place a block of code using a begin...end block:

julia> f = () -> begin
       println("hello world")
       5
       end
(::#1) (generic function with 1 method)

julia> f()
hello world
5

Of course, the short answer is, as @yuyichao said, that this fixed in julia master, so this hack won’t be required in the future.


#6

You can still use the function syntax:

julia> f = function(x)
         "..."
         return x + 1
       end
(::#1) (generic function with 1 method)

julia> f(1)
2