Thanks Yichao, Mauro, and especially Tim for the explanations -- I'm glad I 
ended up asking this question. I think I will end up just using a branch as 
suggested.

On Thursday, March 31, 2016 at 7:49:00 AM UTC-4, Tim Holy wrote:
>
> Yichao is right, because doing so won't help performance in any way 
> (indeed, 
> it will hurt it massively compared to an `if a.b...` runtime branch in 
> your 
> code). You get the performance benefit from multiple dispatch only when 
> the 
> compiler knows the "value" ahead of time (e.g., when it's compiling your 
> code), and transitions between the value-domain and type-domain prevent 
> that 
> from happening. 
>
> Seems like you might be looking for this: 
>
> julia> type A{b} 
>            x::Float64 
>        end 
>
> julia> foo(a::A{true}) = 1 
> foo (generic function with 1 method) 
>
> julia> foo(a::A{false}) = 0 
> foo (generic function with 2 methods) 
>
> julia> a = A{true}(7) 
> A{true}(7.0) 
>
> julia> foo(a) 
> 1 
>
> julia> b = A{false}(7) 
> A{false}(7.0) 
>
> julia> foo(b) 
> 0 
>
>
> HOWEVER, I urge you not to do this frivolously. The compiler has to 
> generate 
> separate versions of every function that takes an A{true} and A{false}. 
> This 
> means your code will be slower to load/start. If you overuse this trick, 
> you 
> can end up getting combinatorial explosions in the number of compiled 
> variants 
> you require, and your code will become completely unusable. 
>
> A runtime check of a boolean is very fast, and if the outcome is fairly 
> predictable (
> http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array)
>  
> it can be very difficult to observe 
> any performance hit at all. 
>
> We do use such tricks in various places in core julia code, but only when 
> we've first tried not to. So it's a wonderful trick, but use it very 
> judiciously. 
>
> Best, 
> --Tim 
>
> On Wednesday, March 30, 2016 10:59:37 PM Yichao Yu wrote: 
> > On Wed, Mar 30, 2016 at 10:51 PM, Chris <[email protected] 
> <javascript:>> wrote: 
> > > Here's my current dilemma, (hopefully) explained by this simple 
> example: 
> > > 
> > > I have a composite type that has a bool field: 
> > > 
> > > type A 
> > > 
> > >   x::Float64 
> > >   b::Bool 
> > > 
> > > end 
> > > 
> > > I have a function with different behavior based on the value of A.b. 
> The 
> > > manual suggests the following solution: 
> > > 
> > > function dothing(a::A, ::Type{Val{false}}) 
> > > 
> > >    ... 
> > > 
> > > end 
> > > 
> > > function dothing(a::A, ::Type{Val{true}}) 
> > > 
> > >   ... 
> > > 
> > > end 
> > > 
> > > That's fine, but now I have to call the function as dothing(a, 
> Val{a.b}), 
> > 
> > Don't do this, just use a branch. Never construct a type with a type 
> > parameter of runtime determined value. 
> > The doc should be made very clear to discourage this! 
> > 
> > > which just strikes me as slightly redundant/verbose. Is there some way 
> to 
> > > make this more compact, i.e. just dothing(a), while still avoiding the 
> > > check of a.b inside the function? Perhaps parameterizing the type A 
> > > itself? 
> > > 
> > > Hopefully I made myself relatively clear. Thanks in advance. 
>
>

Reply via email to