On Thursday, 2 July 2015 17:13:50 UTC+2, Yichao Yu wrote:
>
> On Thu, Jul 2, 2015 at 11:09 AM, Jan Drugowitsch <[email protected] 
> <javascript:>> wrote: 
> > 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]> 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. 
>
> Implicit and elegant sometimes conflict with each other =) 
>
> If you have control over the code that uses this, using a macro is the 
> way to go. A function can't possibly do this. 
>
> You could have a look at https://github.com/one-more-minute/Lazy.jl 
> though. 
>

Thanks, I'll check it out.

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 
>

Reply via email to