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