Overriding Subscript operator creates its own variables?

I tried to override the Subscript operator to make matrix indexing a bit more "user-friendly" in complex expressions with the following code according to the documentation:

Subscript[x__] := Part[x]; (* Indexed instead of Part has the same effect *)


I defined matrix X3×2 as X = Range[10, 15]~Partition~2;.

Now, I assign this matrix as the first element of an a list and I prepend a full-one-row to it. I execute these two commands four times:

a = {X};
PrependTo[Subscript[a, 1], ConstantArray[1, 2]];


After 4 executions of this cell I get the following dimensions:

Dimensions[Subscript[a, 1]] (* {7, 2} *)
Dimensions[Part[a, 1]]      (* {3, 2} *)


When I print out the matrices I get two distinct ones:

Part[a, 1]
(* {{10, 11}, {12, 13}, {14, 15}} *)

Subscript[a, 1]
(* {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {10, 11}, {12, 13}, {14, 15}} *)


I reset a to {X} on every iteration, despite of this I see {1, 1} prepended four times into the a1 matrix. My question is why this happens?

The confusion is arising probably due to a misunderstanding of what PrependTo does. Note that PrependTo has attribute HoldFirst. After prepending ConstantArray[1,2] to the first part of a, the result is stored not in a, but rather as a DownValue to Subscript. The Subscript doesn't get turned into Part thanks to the HoldFirst attribute. Also, the symbol a never even changes with each call of PrependTo, and therefore the code a={X} is superfluous.

Starting from a fresh kernel, after running this,

Subscript[x__] := Part[x];


The following gives the definition associated with Subscript:

Definition[Subscript]

Attributes[Subscript] = {NHoldRest}
Subscript[x__] := Part[x]


Now set a={x} and run your PrependTo code once:

PrependTo[Subscript[a, 1], ConstantArray[1, 2]];


But run Definition[Subscript] again, and you'll notice that the following has been added:

Subscript[{{{10, 11}, {12, 13}, {14, 15}}}, 1] = {{1, 1}, {10, 11}, {12, 13}, {14, 15}}


Therefore, at the very end, when you call Subscript[a,1], the definition Subscript[x__] := Part[x]; is not being invoked. Rather the newly created definition is being called.

• Thank you! As I see, PrependTo really has the HoldFirst attribute in contrast with the simple Prepend, according to Definition. However, when I change my code to use Prepend the definition of Subscript changes again the same way (which I don't understand). Apr 4, 2016 at 5:04
• @szotsaki Prepend shouldn't change any definitions (I just checked to confirm). Be sure to clear the old definitions before checking. Try again starting from a fresh kernel. Apr 4, 2016 at 7:03
• I ran the code above (fully concatenated is here) with a totally fresh kernel and I had two definitions for Subscript. I think this is because Set (=) has HoldFirst attribute (and that can explain why also PrependTo has) which causes again a₁ to have an additional definition. Apr 5, 2016 at 6:57
• @szotsaki Ah, I see. When you said "...to use Prepend..." I didn't realize you also mean to use Set. And you're right; it's behaving the same way because of the HoldFirst attribute. Apr 5, 2016 at 13:03