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)
Evaluating f(0, 1, 2)
summing b + c
Evaluating f(_zero, 1, 2)
summing b + c
f(a,b,c) = (Bool(a) ? a * (b + c) : 0.0)
On Thu, Jul 2, 2015 at 10:48 AM, Tom Breloff <t...@breloff.com> 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.
Is this a toy reduction of a concept that you want to apply in a much more complex way?
On Thu, Jul 2, 2015 at 11:09 AM, Jan Drugowitsch <jdr...@gmail.com> 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 <t...@breloff.com> 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.
julia> foo(x) = x + 0*(x*x + 2)
foo (generic function with 1 method)
julia> @code_llvm foo(1)
define i64 @julia_foo_21664(i64) {
top:
ret i64 %0
}
julia> @code_llvm foo(1.0)
define double @julia_foo_21665(double) {
top:
%1 = fmul double %0, %0
%2 = fadd double %1, 2.000000e+00
%3 = fmul double %2, 0.000000e+00
%4 = fadd double %3, %0
ret double %4
}
julia> foo(x) = @fastmath x + 0*(x*x + 2)
foo (generic function with 1 method)
julia> @code_llvm foo(1.0)
define double @julia_foo_21656(double) {
top:
ret double %0
}