New Issue: Proposal for modestly redefining '.indices' on arrays

17883, "bradcray", "Proposal for modestly redefining '.indices' on arrays", "2021-06-07T23:10:00Z"

As of PR #15039 or so, we added .indices queries to most indexable types as a means of writing code for them that refers to their indices abstractly rather than assuming the indices are, say, 1..size or 0..<size. At that time, .indices became a synonym for .domain for arrays. Issue #15103 proposed that we retire .domain in favor of .indices on arrays, but was received fairly negatively.

[For historical purposes, this issue captures a fork in the discussion of #15103 that started at this point ]

This issue proposes another way to remove the redundancy: What if, rather than returning the array's actual domain, this query returned (or perhaps yielded in some cases?) the array's index set locally. For example, for an n x n Block-distributed array named B, B.domain would return a (const) reference to B's actual Block-distributed domain as it does today, whereas B.indices would return {1..n, 1..n} (or {0..<n, 0..<n} or whatever indices B.domain had) as a local default rectangular domain.

This would have the benefits of:

  • providing a data-structure neutral way of getting a local copy of the indices of the data structure in question
  • removing the "two ways of doing the exact same thing" case that we have today in which .domain and .indices do the same thing
  • providing a user-facing way to ask for B's index set without getting a block-distributed thing back or querying on a per-dimension basis—the only two ways we can do so today I believe.

An obvious disadvantage would be:

  • .indices vs. .domain are similar, so learning to distinguish them is subtle and could have a significant performance impact when making the wrong choice (e.g., var A: [B.indices] real; vs. var A: [B.domain] real; or forall i in B.indices vs. forall i in B.domain).

One open question is whether .indices would have to return the indices in a closed form (say as a sparse domain for a sparse array or an associative domain for an associative array) or whether it would be reasonable for it to be implemented in a closed form in some cases (say, when the storage required is O(1), as for dense rectangular arrays) but as an iterator in others (say, when it's not, as for sparse / associative arrays).