Oh I just realized deepcopy still gets applied every time that function runs. So if I just create another variable and add it to the expression, boxing doesn’t happen. THAT’s how Fix2 solves the problem.
julia> function abmult(r::Int)
if r < 0
r = -r
end
r1 = deepcopy(r); f(x) = r1*x
return f
end
abmult (generic function with 1 method)
julia> f = abmult(4); @code_warntype f(2)
MethodInstance for (::var"#f#3"{Int64})(::Int64)
from (::var"#f#3")(x) @ Main REPL[7]:5
Arguments
#self#::var"#f#3"{Int64}
x::Int64
Body::Int64
1 ─ %1 = Core.getfield(#self#, :r1)::Int64
│ %2 = (%1 * x)::Int64
└── return %2
So I guess that means if you’re working with closures, don’t capture a variable that gets reassigned to (or at least be VERY careful about it). I’m actually very careful about reassigning variables anyway because I got burned by type instabilities before. I can see why you wouldn’t want to capture something like this.