Dear Julia users,

I am implementing an algorithm to solve a specific type of Volterra 
integral equation, and that simplifies significantly if some of its 
parameters are set to zero or one. The function implementing the algorithm 
takes quite a few arguments, such that writing specific versions for 
different arguments being zero/one would lead to too many different 
functions, which I would like to avoid. What I would rather like to do is 
to write one generic function and let the compiler prune different parts of 
the function, depending on the argument types.

A minimal example of what I would like to do is

immutable Zero <: Number; end

const _zero = Zero()

Base.promote_rule{T<:Number}(::Type{Zero}, ::Type{T}) = T
Base.convert{T<:Number}(::Type{T}, ::Zero) = zero(T)

*(::Zero, ::Zero) = _zero
*(::Zero, ::Bool) = _zero
*(::Bool, ::Zero) = _zero
*(::Zero, ::Number) = _zero
*(::Number, ::Zero) = _zero

f(a, b, c) = a * (println("summing b + c"); b + c)

println("Evaluating f(0, 1, 2)")
f(0, 1, 2)
println("Evaluating f(_zero, 1, 2)")
f(_zero, 1, 2)

(with Zero defined similar 
to https://groups.google.com/forum/#!topic/julia-users/0ab30bE8q6c)
Running the above results in

Evaluating f(0, 1, 2)
summing b + c
Evaluating f(_zero, 1, 2)
summing b + c

even though the result of the second "summing b + c" is discarded, and 
therefore wouldn't need to be evaluated. This is no surprise, as *(.,.) is 
a standard function that evaluates its operands before applying the 
function. Is there any way to change this behavior and turn *(.,.) into a 
function that performs short-circuit evaluation? If not, is there an 
alternative approach that achieves this without writing tons of specialized 
functions?

Thanks,
Jan

Reply via email to