Is there a common pattern in Julia (perhaps with some kind of a macro) for the following case?
I have a function that runs a model through several thousands of time steps, and I want to have two versions:
one where each time-step is saved,
just a sum over all time steps is computed
As the parameters of this model will be optimized using Optim.jl on many sets, I would like to keep the functions as performant as possible and avoid conditions inside the loop, yet without copy-pasting a large part of code (only two lines are different).
function foo(x,v::Val{T}) where T
if T
return x
else
return -x
end
end
julia> @code_llvm foo(12, Val(true));
define i64 @julia_foo_66629(i64) #0 !dbg !5 {
top:
ret i64 %0
}
julia> @code_llvm foo(12, Val(false));
define i64 @julia_foo_66663(i64) #0 !dbg !5 {
top:
%1 = sub i64 0, %0
ret i64 %1
}
I was hanging on too much on my lessons from my early computer science courses which assumed very little cleverness on the part of the compiler.
Is the following then a good pattern to handle multiple dispatch of optional parameters within the function body?
function foo(x, y::T=nothing) where T
if T == Nothing
sum = zero(eltype(x))
end
for i in eachindex(x)
if T == Nothing
sum += x[i]
else
y[i] = x[i]+1
end
end
if T == Nothing
return sum
else
return y
end
end
struct Verbose_T end
const verbose = Verbose_T()
struct Debug_T end
const debug = Debug_T()
function foo(x, loglevel=nothing)
if loglevel==debug
@show x
elseif loglevel == verbose
println("entering foo")
else
#we need no default branch today
end
return x
end
Feel free to use more reasonable / julian type names. I like to use intentionally lenghty/nonclashing names for stuff that really is just internals.
edit: You call by
foo(12)
foo(12, debug)
foo(12, verbose)
Also, my suggestions are slightly outdated on current master. I think nowadays keyword parameters are the way to go.
Thanks for the replies! I suppose I was aiming at making types explicit, since the function is going to be run many times inside the optimization function and I wanted to avoid type instability, but I see now that it is not necessary.