I want to write a method that is very similar between two types, with
slight divergences. I'd like to write it avoiding code duplication.
To take a simple example, let's say that the two types are Vector and
Matrix. The method must print "I'm an array" for the two types, and then
prints "I'm a vector" if the object is a vector, "I'm a matrix" if the
object is a matrix.
One way write this method is to use a "run time" dispatch
function f{T, N}(x::Array{T, N})
println("I'm an array")
if N == 1
println("I'm a vector")
elseif N == 2
println("I'm a matrix")
end
end
f2(rand(10, 10))
@code_warntype f2(rand(10, 10))
A way to dispatch at compile time is to define as many auxiliary function
as there are differing lines
function _ansfunction(x::Vector)
println("I'm a vector")
end
function _ansfunction(x::Matrix)
println("I'm a matrix")
end
function f1(x)
println("I'm an array")
_ansfunction(x)
end
f1(rand(10, 10))
@code_warntype f1(rand(10, 10))
Another solution would be to iterate through two NTuples, where N is the
number of differing lines
for (t, x) in ((:Vector, :(println("I'm a vector"))),
(:Matrix, :(println("I'm a Matrix"))))
@eval begin
function f2(x::$t)
println("I'm an array")
$x
end
end
end
f2(rand(10, 10))
@code_warntype f2(rand(10, 10))
These two last solutions work, but I really prefer the syntax of first
solution : it allows to write the differing lines exactly at the place
they're needed, when they're needed. It really starts to mattes when there
are a few differing lines. Is there a syntax as clear as the first
solution, but that "branch" at compile time?