Oh.. I did not try @code_native (to be honest I can't read the output anyway...). Thanks a lot for the precision. The whole discussion is clearer now.
On Wednesday, September 30, 2015 at 8:38:49 AM UTC-4, Mauro wrote: > > If you look at @code_native you'll see that the branch which still > exists in code_warntype is eliminated. > > On Wed, 2015-09-30 at 14:06, Matt <matth...@gmail.com <javascript:>> > wrote: > > Also, both Stefan and you mention that the branching is eliminated in > the > > first method. But if if I use on the first version > > > > @code_warntype f(rand(10, 10)) > > > > Body: > > > > begin # none, line 2: > > > > (Base.println)(Base.STDOUT,"I'm an array")::Any # line 3: > > > > unless 2 === 1::Bool goto 0 # line 4: > > > > return (Base.println)(Base.STDOUT,"I'm a vector")::Any > > > > goto 2 > > > > 0: # line 5: > > > > unless 2 === 2::Bool goto 1 # line 6: > > > > return (Base.println)(Base.STDOUT,"I'm a matrix")::Any > > > > goto 2 > > > > 1: > > > > return > > > > 2: > > > > end::Any > > > > > > > > while all other methods do eliminate branching: > > > > > > Body: > > > > begin # none, line 2: > > > > (Base.println)(Base.STDOUT,"I'm an array")::Any # line 3: > > > > return (Base.println)(Base.STDOUT,"I'm a matrix")::Any > > > > end::Any > > > > > > > > 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 <matth...@gmail.com > <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? > >>> > >> >