As I recall,
Base.length is used to return types with a single dimension
Base.size is used to return types with more than one dimension
I have build a tree type and I want to return the total number of nodes in the tree. Should I extend
size or neither?
Further, each node of the tree carry a “weight”. So I am thinking about extending
Base.sum for the total weight.
Any thoughts welcome. Thanks!
size should probably be consistent with
length if implemented. Assuming the type support iteration implementing
length will be very fair.
sum, again, if it is iterable it’ll be strange if the sum is not summing the item in iteration. If iteration returns the weight it’ll be fair but otherwise I think you’ll be better off with a different function
When you say consistent, do you mean that
size should return a tuple and
length should return a single number? I was struggling due to the shape of the tree because it is neither linear nor multi-dimensional
The type supports iteration in the sense that it can be traversed depth-first or breath-first (currently depth-first only). The nodes have composite type so I am implementing
sum(f, itr) interface and expects function
f to return a numeric type.
Yes. And although I’m not sure right now what the official rule would be, my rule of thumb will be that if you support indexing then it has an interface that looks like an array that you can have
size. If you don’t then don’t bother.
Put it another way, follow
In that case I’d say if the iteration returns nodes that doesn’t support arithmetic then you probably should still not special case
sum even though it does’t really conflict with anything. (But sincne there’s no conflict you can also do what you feel convinient without causing much trouble). sth like
sum(node_weight, iter) shouldn’t be too hard to write either though…
Actually, there could be a couple of summable fields besides weight. Should I define something like this?
Base.sum(::Tree) = error("Please use `sum(f, ::Tree)` instead.")
Mmm… if I do that then it seems to be a hassle because I would have to do the same thing for other statistical functions like
Just leave them unimplemented should be fine? You are not extending all the functions that you are not planning to implement are you?
Sure, I can leave them unimplemented. I was just thinking about being a good “citizen” for implementing the full interface. Thanks for your help.
This depends on whether you want to support any of the interfaces.
I am not sure that the array interface, which has
size, makes much sense for a tree. But if you want to support iteration, you should define
Base.length and the relevant traits if applicable. And, crucially,
If you do not want to support either interface, you are free to do what you like. Some types in packages define
length without supporting iteration.