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]> 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