14
$\begingroup$

(In case this is version specific I am using Mathematica 10.1 under Windows.)

While responding to Partition array without unpacking I noticed something about MapAt that I don't believe I have before:

pQ = Developer`PackedArrayQ;
x = Range @ Range @ 3
pQ[x]
Map[pQ, x]
MapAt[pQ, x, 2]
{{1}, {1, 2}, {1, 2, 3}}

False

{True, True, True}

{{1}, False, {1, 2, 3}}

Note the last output line: the second element is False rather than True. The element {1, 2} has apparently been unpacked by MapAt before the function that is mapped ever sees it. Also notably the other elements are not unpacked:

pQ /@ MapAt[pQ, x, 2]   (*  {True, False, True}  *)

It is understandable that it would unpack a list which it was going to operate within , e.g. MapAt[f, x, {2, 1}] but not a list passed verbatim to the operating function. I cannot think of a good reason for MapAt to unpack in this case, and without a counterargument I would consider it a bug.

Is this a bug or oversight, or is there a reason for this behavior that I am failing to consider?

$\endgroup$
7
  • 3
    $\begingroup$ v11 does the same. I considered asking this same question earlier today, but then I didn't. $\endgroup$
    – Szabolcs
    Commented Oct 7, 2016 at 14:33
  • $\begingroup$ v.10.0.1 on Mac OS 10.10.5 does the same. $\endgroup$
    – march
    Commented Oct 7, 2016 at 15:34
  • $\begingroup$ My guess is that MapAt takes complex position specification, even Span is allowed. It would take relatively complex logic to figure out what to unpack and what to leave packed, so they didn't implement that. At least this is why I didn't write about MapAt when I complained about Partition and Append to support. It seems there's still plenty of opportunity for optimization. $\endgroup$
    – Szabolcs
    Commented Oct 7, 2016 at 15:36
  • $\begingroup$ Same result in v9.0.1 and v8.0.4 $\endgroup$
    – xzczd
    Commented Oct 7, 2016 at 15:48
  • $\begingroup$ @Szabolcs I am not sure I agree with that reasoning. If MapAt started by unpacking everything would have figured it was a design decision along those lines, but since it manages to keep elements one and three in this example packed it is obviously possible to unpack only some elements and not others. I do not see the need/reason for unpacking the deepest level. I don't see how Span factors into this. If we use MapAt[pQ, x, 2 ;; 3] (which also unpacks) it is apparent that neither two nor three need to be unpacked. (continued) $\endgroup$
    – Mr.Wizard
    Commented Oct 7, 2016 at 16:02

0