2
$\begingroup$

Let's say we have a list g with variable d as its element:

Clear[g, d]
g = {1,2,3,d}

Now g[[4]] evaluates to d. But after d is assigned, g[[4]] evaluates to d's value. But it seems like g[[4]] is still pointing to d:

In[48]:= d = 1

Out[48]= 1

In[49]:= g[[4]]

Out[49]= 1

In[50]:= d = 2

Out[50]= 2

In[51]:= g[[4]]

Out[51]= 2

So is there anyway to get the symbol of g[[4]]? SymbolName does not work in this case. SymbolName[g[[4]]] results in an error.

$\endgroup$
3
  • $\begingroup$ Take a look at OwnValues[g] and FullDefinition[g]. The closest I can get is Extract[First[OwnValues[g]], {2, 4}, Defer] but I cannot take the SymbolName as it's wrapped in Defer and removing that will evaluate it as 2. $\endgroup$
    – flinty
    Commented Aug 7, 2020 at 12:56
  • $\begingroup$ ^ that said, you can get it using strings StringCases[ToString@Extract[First[OwnValues[g]], {2, 4}, Defer], "Defer[" ~~ x_ ~~ "]" :> x] // First $\endgroup$
    – flinty
    Commented Aug 7, 2020 at 13:05
  • $\begingroup$ Closely related to this question. $\endgroup$
    – Alan
    Commented Aug 7, 2020 at 13:15

2 Answers 2

1
$\begingroup$
ClearAll[g, d]
g = {1, 2, 3, d}
Part[g, 4]  (* what you expect *)
Trace[Part[g, 4]] (* how it is produced *)
d = 4; (* assign value *)
Trace[Part[g, 4]]  (* now you get the evaluated part *)
OwnValues[g] // FullForm  (* examine the assignment result *)
Extract[%, {1, 2, 4}, HoldForm]  (* extract what you want *)
$\endgroup$
2
  • $\begingroup$ Hi, your output in full form is HoldForm[d] whereas the output of SymbolName would be "d". $\endgroup$ Commented Aug 7, 2020 at 18:49
  • $\begingroup$ @ChrisDegnen Well, OP said "get the symbol" not "get the symbol name", although yes OP did mention SymbolName. OP can choose. It might be desirable to be able to ReleaseHold at some point. If not, OP can just apply ToString. $\endgroup$
    – Alan
    Commented Aug 7, 2020 at 19:14
1
$\begingroup$

You can obtain the name using Hold

Clear[g, d]
g = {1, 2, 3, d};
d = 2;

o = OwnValues[g];
m = MapAll[Hold, o];
h = FirstCase[m, RuleDelayed[_, Hold[z_]] :> z, _, Infinity];
s = ToString[h[[4]]];
n = StringTake[s, {6, -2}]

"d"

$\endgroup$

Your Answer

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

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