Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I often find it useful to define a symbol from strings (often in a loop in which I define other symbols). This I accomplish with Symbol (and often ToString).

However, if the symbol has already been defined, my call to Symbol returns not the symbol, but that to which the symbol evaluates.

This may arise rarely, but I stumbled upon it when automatically generating usage messages, as in the following example.

vars = {x,y};
x$dN = {x1, x2};
y$dN = {y1, y2};
For[ i = 1, i <= Length[vars], i++,
  Evaluate[
    Symbol[
      ToString[vars[[i]]] <> "$dN"
    ]
  ]::usage
  =
  "generic (no argument) thermodynamic quantity vector"
]

(* Symbol::symname: The string "{x1, x2}$dN" cannot be used for a symbol name. 
   A symbol name must start with a letter followed by letters and numbers" *)

This is the obvious error because I'm trying to define the usage for x$dN, which evaluates to x$dN = {x1, x2}.

So my question is: can we sometimes leave a symbol unevaluated, yet use it as a symbol?

share|improve this question

marked as duplicate by Mr.Wizard May 12 at 22:30

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1  
Try something like ReleaseHold@Hold[MessageName][ToExpression["symb", InputForm, Hold], "usage"]. Using ToExpression with a third argument is key here. –  Jacob Akkerboom May 12 at 19:41
    
@JacobAkkerboom, your solution was easiest for me to instantiate. Thanks! –  Rico Picone May 12 at 20:00
1  
Fundamentally this has been covered a number of times before. Despite this not being an exact duplicate it surely "already has an answer" there: (197), (783), (2651), (2926), (37755) Therefore I shall close it to prevent redundant efforts. –  Mr.Wizard May 12 at 22:29

1 Answer 1

up vote 6 down vote accepted

In your example it is possible to assign a usage message although the variable has a value. Short example:

var = 1;
Function[v, v::usage = "blue", HoldFirst] @@ MakeExpression["var"]

The trick is to keep the variable var unevaluated all the time which can be tricky.

In my example above this is accomplished by three things:

  • MakeExpression does what Symbol does in your code, but it wraps the result automatically in HoldComplete. Therefore, var will not be evaluated at this point
  • Function[....,HoldFirst] creates a functions which too, holds its first argument unevaluated.
  • MessageName which is the symbol::msg operator too holds its first argument. Check Attributes[MessageName] to see that.
share|improve this answer
    
halirutan, thanks for the thorough explanation! –  Rico Picone May 12 at 20:01

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