AFAICT functions in Julia are considered to be bits type:
julia> f(x) = x
f (generic function with 1 method)
julia> isbitstype(typeof(f))
true
which means that deepcopy on them is a no-op. Here is a definition of deepcopy:
function deepcopy(x)
isbitstype(typeof(x)) && return x
return deepcopy_internal(x, IdDict())::typeof(x)
end
The reason for this is that each function has its own type (but it can have many methods).
The solution that phipsgabler proposes works because each time you define an anonymous function it gets its own new type. See here:
julia> typeof(x -> x)
var"#1#2"
julia> typeof(x -> x)
var"#3#4"
julia> typeof(x -> x)
var"#5#6"
This has one downside though - each time you pass an fresh anonymous function to another function it has to be compiled, e.g.:
julia> @time map(x -> x, 1:2);
0.024220 seconds (49.61 k allocations: 2.734 MiB)
julia> @time map(x -> x, 1:2);
0.023754 seconds (48.25 k allocations: 2.530 MiB)
julia> @time map(x -> x, 1:2);
0.023336 seconds (48.25 k allocations: 2.530 MiB)
vs
julia> fun = x -> x
#7 (generic function with 1 method)
julia> @time map(fun, 1:2);
0.023459 seconds (48.23 k allocations: 2.530 MiB)
julia> @time map(fun, 1:2);
0.000016 seconds (4 allocations: 192 bytes)
julia> @time map(fun, 1:2);
0.000013 seconds (4 allocations: 192 bytes)
Going back to your original question. Even if you write something like:
julia> f(x) = x
f (generic function with 1 method)
julia> g = x -> f(x)
#1 (generic function with 1 method)
julia> g(1)
1
you get:
julia> f(x) = 2x
f (generic function with 1 method)
julia> g(1)
2
because f(x) = 2x replaces the method for the function f but its type does not change (as commented above - one function can have many methods and you can even update the methods of the function as in the example above). This is related to a so called "world age" issue that you have explained here in the Julia manual.