Bug introduced in 5.2 or earlier and fixed in 10.1.0
This is another question on the design choices in Mathematica. I understand that without direct reply from the developers it may not be possible to give a definitive and exhaustive answer to "why" questions but such topics have often been fruitful.
Why does list assignment of the form {a, b, c} = tensor
where tensor
is packed result in unpacked values for a
, b
, and c
?
To illustrate:
packedQ = Developer`PackedArrayQ;
tensor = RandomReal[99, {3, 5, 7}];
tensor // packedQ
True
{a, b, c} = tensor;
packedQ /@ {a, b, c}
{False, False, False}
It is possible to make the assignments without unpacking the sub-arrays of tensor
by manually unpacking the outer list using Apply
:
{a, b, c} = List @@ tensor;
packedQ /@ {a, b, c}
{True, True, True}
Why doesn't Set
operate like this by default?
That is, why doesn't Set
only unpack the right-hand-side as far as necessary, to the level of the left-hand-side?
tensor
already has the headList
, why doesList @@ tensor
have any effect onSet
at all, considering it's evaluated beforeSet
even sees it? $\endgroup$Apply
does unpack the top level of the packed array. It does it always, even if the head to be applied is also aList
. $\endgroup$Set
is given tensor with its top-level unpacked, the lower levels will not be disturbed. $\endgroup$Set
gets a packed array on the RHS and a list on the LHS, it fully unpacks the RHS rather that only unpacking it to the level of the LHS. This seems like an unfortunate choice, but I have often learned that there are good reasons for such choices once I asked about them. $\endgroup$List
was probably considered not important. In fact, the only reason one would want to doList @@ packed
would be if one wants to unpack one level. It also seems to be the only way to do this (i.e. usingApply
), if one wants to only unpack one level. $\endgroup$