On Thursday, 2 July 2015 16:55:33 UTC+2, Yichao Yu wrote:
>
> On Thu, Jul 2, 2015 at 10:48 AM, Tom Breloff <[email protected]
> <javascript:>> wrote:
> > Just curious... is there a reason simply checking for non-zero isn't
> enough?
> > Readability? Performance?
> >
> > f(a,b,c) = (Bool(a) ? a * (b + c) : 0.0)
>
> I'm guessing he want all code that gets his type automatically gets
> this behavior? If yes, I don't think there's anyway you can do that.
> If not, then just writing the branch or having a macro to rewrite that
> in your own code is probably the best solution.
>
Indeed, the reason why I don't want to check for zeros and ones explicitly
is that some of these appear in inner loops and would reduce performance.
I already thought of macros as a possible solution, but I was wondering if
the same could be achieved in a more implicit/elegant way.
Thanks,
Jan
> > On Thursday, July 2, 2015 at 9:47:59 AM UTC-4, Jan Drugowitsch wrote:
> >>
> >> Dear Julia users,
> >>
> >> I am implementing an algorithm to solve a specific type of Volterra
> >> integral equation, and that simplifies significantly if some of its
> >> parameters are set to zero or one. The function implementing the
> algorithm
> >> takes quite a few arguments, such that writing specific versions for
> >> different arguments being zero/one would lead to too many different
> >> functions, which I would like to avoid. What I would rather like to do
> is to
> >> write one generic function and let the compiler prune different parts
> of the
> >> function, depending on the argument types.
> >>
> >> A minimal example of what I would like to do is
> >>
> >> immutable Zero <: Number; end
> >>
> >> const _zero = Zero()
> >>
> >> Base.promote_rule{T<:Number}(::Type{Zero}, ::Type{T}) = T
> >> Base.convert{T<:Number}(::Type{T}, ::Zero) = zero(T)
> >>
> >> *(::Zero, ::Zero) = _zero
> >> *(::Zero, ::Bool) = _zero
> >> *(::Bool, ::Zero) = _zero
> >> *(::Zero, ::Number) = _zero
> >> *(::Number, ::Zero) = _zero
> >>
> >> f(a, b, c) = a * (println("summing b + c"); b + c)
> >>
> >> println("Evaluating f(0, 1, 2)")
> >> f(0, 1, 2)
> >> println("Evaluating f(_zero, 1, 2)")
> >> f(_zero, 1, 2)
> >>
> >> (with Zero defined similar to
> >> https://groups.google.com/forum/#!topic/julia-users/0ab30bE8q6c)
> >> Running the above results in
> >>
> >> Evaluating f(0, 1, 2)
> >> summing b + c
> >> Evaluating f(_zero, 1, 2)
> >> summing b + c
> >>
> >> even though the result of the second "summing b + c" is discarded, and
> >> therefore wouldn't need to be evaluated. This is no surprise, as *(.,.)
> is a
> >> standard function that evaluates its operands before applying the
> function.
> >> Is there any way to change this behavior and turn *(.,.) into a
> function
> >> that performs short-circuit evaluation? If not, is there an alternative
> >> approach that achieves this without writing tons of specialized
> functions?
> >>
> >> Thanks,
> >> Jan
>