18353, "bradcray", "When should '.indices' be a procedure vs. iterator?", "2021-09-07T19:51:13Z"
This issue is a follow-on to #17883 which re-defined .indices
on arrays to make it more distinct from .domain
. Specifically, the goal of this issue is to ensure that we're in agreement about when .indices
should be a procedure vs. an iterator, where the three main options are:
- it should always be a procedure
- it should always be an iterator
- it should sometimes be a procedure and sometimes an iterator
As background, .indices
on types like tuples, strings, lists, etc. return ranges today, which has certain advantages:
- O(1) representation in memory
- supports convenient queries like
assert(myType.indices.low == 0);
In my PR #18274 which began the process of deprecating .indices
being a near-alias for .domain
, I essentially took the third approach, based on the following philosophy:
- for dense, rectangular arrays, return the indices as a domain in order to preserve a similar behavior to the
.indices
queries on other types (O(1) representation, supports similar queries) - for other arrays (sparse, associative), use an iterator that yields the indices rather than a procedure that returns a domain
My rationale for the irregular case was a minor fear that in the case of a distributed sparse or associative array, there may not be enough memory to store the indices as a local sparse or associative domain. I also imagined that, given an iterator, it would be simple enough to capture the indices back into a domain (or array or list or ...) if that's what the user wanted.
That said, here are some alternative perspectives:
- maybe it should always return a domain, even in the irregular cases, where if there's an OOM error, that's the user's problem for trying to do the impossible; and if they want to iterate over the indices instead, they can always use
for[all] i in MyArr.domain ...
. - maybe it should always be an iterator for consistency since any of these can be expressed as an iterator