0
$\begingroup$

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?

$\endgroup$

1 Answer 1

2
$\begingroup$

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.

$\endgroup$
4
  • $\begingroup$ 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). $\endgroup$
    – szotsaki
    Apr 4, 2016 at 5:04
  • $\begingroup$ @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. $\endgroup$
    – QuantumDot
    Apr 4, 2016 at 7:03
  • $\begingroup$ 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. $\endgroup$
    – szotsaki
    Apr 5, 2016 at 6:57
  • $\begingroup$ @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. $\endgroup$
    – QuantumDot
    Apr 5, 2016 at 13:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.