Okay, "promises" was too strong a word.
The documentation is somewhat vague on ArrayRules
, so one is left to make some guesses.
To interpret the documentation properly, it is also critical to distinguish between arguments described as list
, which refer to dense arrays, and arguments described as s
or SparseArray[...]
, which refer only to SparseArrays. I did not pay sufficient attention to this distinction.
The "NonzeroPositions" are not recomputed automatically, as doing so would be unreasonably expensive.
This is completely reasonable.
What ArrayRules
actually does is, in my opinion, not so reasonable from a user-friendliness perspective.
Let me describe what it does precisely (as I understand it now).
ArrayRules[x]
will:
- If
x
is a SparseArray
, then return the background element (which may be nonzero!) and explicit values (which may contain the background) in a specific format.
- Otherwise, return positions/values that are nonzero.
The documentation says, "ArrayRules[list] gives rules for SparseArray[list]", which is a completely reasonable concise explanation, but of course it should not be taken literally, as evidenced by the difference between ArrayRules[{{1} -> 1, {4} -> 1}]
and ArrayRules@SparseArray[{{1} -> 1, {4} -> 1}]
.
There is also a line saying "ArrayRules[list] assumes a default value of 0." Notice that this is only true for dense arrays (which is implied by the name list
, but that is too easy to overlook).
ArrayRules[x, b]
will:
- If
x
is a SparseArray
with background element b
, then return the background element and explicit values (which may contain the background) in a specific format
- If
x
is a SparseArray
with background element other than b
, then return the positions/values different from b
- If
x
is not a SparseArray
then return positions/values different from b
.
This may be okay from the implementor's perspective, but it is disturbingly inconsistent from a user's perspective. Why is there a special casing for whether the second argument is equal to the background element of the first one?
ArrayRules[x]
could be a function that just reveals the structure of a SparseArray: explicit values/positions and background element. In this case it should not work on a dense array and should not have a second argument. There is no need for a second argument because that background element is what it is. This would be a simple to understand function that operates on a sparse array data structure.
Otherwise ArrayRules[x, b]
could be a function which returns the values/positions of elements different from b
. The default b
could be taken to be 0
(for the one-argument form). This ArrayRules
would not care about what data structure x
is (dense or sparse). It would operate at a higher, conceptual level. It is also simple to understand.
Instead, we have an ArrayRules
which is a confusing mix of these two things.
All these things are not precisely stated in the documentation. The behaviour is sufficiently complicated that it would be hard to describe it concisely. So I am left to guess. Given that ArrayRules
works on dense arrays and that it has a second argument, guessing that the two-argument form does what I described in 2. above was completely reasonable.