I was playing around with map
and encountered some unexpected behaviour when changing the definition of the argument function.
Define a function
julia> f(x) = x + 2
f (generic function with 1 method)
Apply map
to the function and a collection.
julia> map(f,1:3)
3-element Array{Int64,1}:
3
4
5
Redefine f
f(x) = x + 3
WARNING: Method definition f(Any) in module Main at REPL[1]:1 overwritten at REPL[3]:1.
f (generic function with 1 method)
Apply map
to redefined f
and the same collection.
julia> map(f,1:3)
3-element Array{Int64,1}:
3
4
5
Hmmm. Looks like f
never changed. Collect
the collection.
map(f,collect(1:3))
3-element Array{Int64,1}:
4
5
6
Oh, now it changed. Change f
one more time.
f(x) = x + 4
WARNING: Method definition f(Any) in module Main at REPL[3]:1 overwritten at REPL[13]:1.
f (generic function with 1 method)
Apply map
to f
and the collected collection.
map(f,collect(1:3))
3-element Array{Int64,1}:
4
5
6
It’s still using the previous definition of f
. Well then.
I expected map
to use the current definition of f
, so if I change f
and call map
again same arguments as before, map
would use the new definition of f
, much like changing the second argument to map
changes the collection that f
gets applied to. But instead, it looks like map
is using the definition of f
from when map
was first called.
This is not the kind of behaviour I would infer from the documentation which states simply that map(f,c...)
“transform[s] collection c by applying f to each element.” I spent a while reading other documentation on functions to find the answer, but didn’t see anything describing or explaining this kind of behaviour.
I can get around this by writing map(x->f(x),r)
, but that seems rather roundabout.
Is this behaviour on purpose? Is there a better way to work around it?