Le lundi 05 janvier 2015 à 18:53 -0800, Greg Plowman a écrit :
>         
>                 The only reason I can think of is that a copy may be
>                 costly for certain 
>                 types, and it's not needed in most cases since the
>                 summation will create 
>                 a new value in the general case. But as you noted this
>                 is not true when 
>                 the array only contains one element. So it looks like
>                 the most efficient 
>                 fix would be to copy only when n == 1 in
>                 _mapreduce(). 
>         
> 
> 
> I must admit I don't really understand the code, however it doesn't
> look like evaluation would be affected for n>=2. 
> The extra cost would only be for 1-element arrays:
> 
> 
> Apparently, for 1-element arrays, zero(::MyType) needs to be defined
> For 0-element arrays, both zero(::MyType) and zero(::Type{MyType})
> need to be defined
> (strangely, for 0-element arrays, mr_empty() calls r_promote(::AddFun,
> zero(T)) which effectively calls zero(T) + zero(zero(T)), so both
> forms of zero() need to be defined
Yes, but that's not an issue as the definitions are equivalent:
zero(x::Number) = oftype(x,0)
zero{T<:Number}(::Type{T}) = convert(T,0)

help?> oftype
Base.oftype(x, y)

   Convert "y" to the type of "x" ("convert(typeof(x), y)").


> In any case, at the moment I guess I have 2 workarounds:
> 
> 
> I could define MyType as a subtype of Number and provide zero()
> functions. 
> However, I'm not sure what the side effects of subtyping are, and
> whether this is advisable?
I don't think it would be a problem, it may well make a lot of sense if
your type is similar to a number (which is apparently the case since you
can sum it).

> 
> type MyType <:Number
>     x::Int
> end
> 
> Base.zero(::Type{MyType}) = MyType(0) # required for sum(0-element
> array)
> Base.zero(::MyType) = MyType(0)       # required for sum(0-element
> array) and sum(1-element array)
> 
> +(a::MyType, b::MyType) = MyType(a.x + b.x)
> 
> 
> 
> 
> Alternatively, I could define my own sum() functions, but then if I
> want the general functionality of all variants of sum(), this seems
> non-trivial.
Indeed. Another solution is to make a pull request with a possible fix,
it could be included quite soon in a 0.3.x minor release so that you can
use it.


Regards

Reply via email to