OK Thanks Milan.
1. I think for now I'll just use subtype of Number.
I have an uneasy feeling this is not entirely the way to go because I get
stuff that might not be valid for my type. An example is convert() see
below. But for my purpose now, it's not really a problem.
2. My comment about both forms of zero() being required for summing
0-element arrays wasn't to suggest it was an issue (I can also now see that
both forms of zero() end up calling convert() as you pointed out. Thanks).
My point was minor and twofold:
a. Summing a 0-element array creates (at least??) 3 objects (zero(T),
zero(Type{T}), and the their addition) which I originally thought
was rather convoluted and inefficient. I'm sure it's to keep code general.
Regardless its really not an issue
b. For non-Number types it does require defining both forms of zero().
Again, not really an issue.
3. Note that if I subtype from Number, then I still need to do one of the
following:
a. define both forms of zero() - I think the better option
b. define convert(MyType, Int) - this is more general than I want. Although
zero() eventually calls convert(MyType, 0) which makes sense, it
doesn't always make sense to define convert for arbitrary Int.
(In my actual case, MyType is a large collection of vectors, 2/3D-arrays
that are counters. I use pmap and want to reuse returned objects after
reducing by sum, which is why I want sum to return a new object).
4. As far as submitting a Pull Request, I think this is way out of my
league. I'm a newcomer to programming, Julia, pull requests, ... (Actually
I didn't really know what a pull request was until I looked it up after
your suggestion). For what it's worth:
a. My main concern is that sum() should always return a new object (so I
don't have to externally check size of array)
b. I feel uneasy about subtyping from Number (I can't really say why,
except that I might be getting more than I want, as in convert example
above)
c. Your solution below seems good.
Thanks for help.
It's much appreciated.
- Greg
If you look at the definition of sum()
that's used in your example, you'll see that it calls _mapreduce(),
which in turn relies on the r_promote() function when only one element
is passed. The code can be seen using edit(Base.r_promote).
For numbers, it indeed does
r_promote(::AddFun, x::Number) = x + zero(x)
But for other types, no copy is done:
r_promote(::AddFun, x) = x
This must be because zero() is not necessarily defined for arbitrary
types. But for the sum to be defined, it looks to me that zero() must be
defined too, and it looks like the code assumes that too. So I'm not
sure why the definition for numbers is not used for everything.