This is a very quick-n-dirty (so expect it to break), works on the first four examples in the 12.0 documentation. I'll revisit to accommodate named range cases (All, UpTo, etc.) if/when time permits, but this should get you pointed in the right direction.
subsetmap[f_, l_, r_] :=
ReplacePart[l, Thread[r -> f[l[[Sequence @@ #]] & /@ r]]];
subsetmap[f_, l_, r_Span] :=
With[{t = Range @@ r}, ReplacePart[l, Thread[t -> f[l[[t]]]]]] ;
V12 examples:
SubsetMap[Reverse, {x1, x2, x3, x4, x5, x6}, {2, 4}] ==
subsetmap[Reverse, {x1, x2, x3, x4, x5, x6}, {2, 4}]
SubsetMap[RotateLeft, {x1, x2, x3, x4, x5, x6}, {2, 4, 5}] ==
subsetmap[RotateLeft, {x1, x2, x3, x4, x5, x6}, {2, 4, 5}]
SubsetMap[Accumulate, {x1, x2, x3, x4, x5, x6}, 2 ;; 5] ==
subsetmap[Accumulate, {x1, x2, x3, x4, x5, x6}, 2 ;; 5]
SubsetMap[Reverse,
Array[Subscript[x, ##] &, {3, 3}], {{1, 1}, {2, 2}, {3, 3}}] ==
subsetmap[Reverse,
Array[Subscript[x, ##] &, {3, 3}], {{1, 1}, {2, 2}, {3, 3}}]
True
True
True
True
This seems more robust, and allows spans and {All,2} flavors (named ranges). I use MapAt to tag, then process. Note that for single-dimension lists, the alternative element position format shown in the SubsetMap docs must be used, e.g., {{1},{3},{5}} for {1,3,5}. This seems to work on the examples I tried, but again, caveat lector.
subsetmap[f_, l_, r_] := Module[{h1, h2, t},
h2 = MapAt[h1, l, r];
t = Most /@ Position[h2, h1];
ReplacePart[l, Thread[t -> f[l[[Sequence @@ #]] & /@ t]]]];
DeleteDuplicatesonrshould take care of this without affecting anything else. – 1110101001 Apr 24 '19 at 18:31