# Get the name of a symbol passed to a function

I'm trying to get the name of a symbol passed to a function with this:

f[x_] := {SymbolName[x], x}
SetAttributes[f, HoldFirst]
x = 5;
f[x]


But x is being evaluated anyway:

SymbolName::sym: Argument 5 at position 1 is expected to be a symbol. >>
{SymbolName[5], 5}


What am I missing here?

-
I'm fairly certain this is a duplicate. Please help me locate it, or correct my assertion. –  Mr.Wizard Dec 4 '12 at 13:13
@Mr.Wizard If it's a dupe (quite possible), then I haven't seen the original, since I don't recall it. –  Leonid Shifrin Dec 4 '12 at 13:16
@Leonid perhaps I was thinking of this question but that is the converse of the present one, or perhaps it was on Stack Overflow. –  Mr.Wizard Dec 4 '12 at 13:24
@Mr.Wizard That one is related, but not a dupe. But the issue is very common, I would not be surprised if it was asked in some slightly different context before. –  Leonid Shifrin Dec 4 '12 at 13:30

You are missing Unevaluated:

SetAttributes[f, HoldFirst]
f[x_] := {SymbolName[Unevaluated@x], x}


because SymbolName does not hold its arguments, so you have to prevent evaluation also there.

Generally, if you are passing some argument via a chain of function calls, and want to keep it unevaluated, you have to prevent it's evaluation at each stage (function call). If the chain is long, it may be easier (and more robust) to wrap the argument in Hold, for the passing purposes, and unwrap in the function that actually needs it.

Note by the way that it is better to set attributes before you give definitions to a function, to avoid some surprises, unless you know precisely what you do and why.

-
"... it is better to set attributes before you give definitions to a function, to avoid some surprises." I argue that it's better to set the Attribute at the appropriate time, being mindful of the ramifications of the order. This has powerful uses as you know. I know what you are trying to warn new users against but for a long time that "rule" kept me from understanding and using Attributes to their full potential. Maybe this is one of those "you must know the rules before you decide to break them" cases. –  Mr.Wizard Dec 4 '12 at 13:22
@Mr.Wizard I stand by what I advised. Those who know these advanced uses know what they do. Most people would find it highly confusing when their functions would not work according to their definitions, only to discover (with pain, hours later), that there was some evaluation happening at definition-time which ruined their definitions. I am speaking from personal experience here, but I know that lots of other people got into this trap at some point, and more than once. –  Leonid Shifrin Dec 4 '12 at 13:27
You already had my vote but I appreciate the addition. Quite reasonably your answers are generally viewed as authoritative (even if you disagree) and it's good, IMHO, to at least allow for situations where an Attribute is not set first. –  Mr.Wizard Dec 4 '12 at 13:35
@Mr.Wizard Thanks, I appreciate that. I used to give more detailed answers which would also explain the reasons behind some of the rules. A little more busy now :) –  Leonid Shifrin Dec 4 '12 at 13:37
@LeonidShifrin I was alluring to R - quite lamely as it seems. Thx for the offer though! –  Yves Klett Dec 4 '12 at 13:51