Thanks for answering. Sorry I deleted my question after finding what I 
wanted. If some people are interested, I like the two solutions below:

for t in (Vector, Matrix)
    @eval begin
        function f2(x::$t)
            println("I'm an array")
            $(t  == Vector ? :(println("I'm a vector")) :  :(println("I'm a 
matrix")))
        end
    end
end

or even

@generated function f{T, N}(x::Array{T, N})
    quote
        println("I'm an array")
        $(N == 1 ? :(println("I'm a vector")) :  :(println("I'm a matrix")))
    end
end



On Tuesday, September 29, 2015 at 8:57:10 PM UTC-4, Stefan Karpinski wrote:
>
> The branch on the first version will be eliminated. The second version is 
> far more idiomatic, however. Consider that the second version is trivially 
> extensible to more types while the first version cannot be extended at all.
>
> On Tuesday, September 29, 2015, Matt <[email protected] <javascript:>> 
> wrote:
>
>> 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?
>>
>

Reply via email to