# Map and Scan ignore HoldFirst

I am trying to write a simple function that takes a list of data and outputs it to a file. I'd like the name of the file to be the same as the variable that holds the list. It seems that giving a function the attribute HoldFirst solves this problem. For example:

a = 1;

ClearAll[printName];
SetAttributes[printName, HoldFirst];
printName[var_] := ToString@Unevaluated@var


When called, this returns

In: printName@a
Out: "a"


as expected.

However, things get murkier when I try to Map this function over a list. For example:

In: a = 1;
b = 2;
c = 3;

l1 = {a, b, c};

printName /@ l1

Out: {"1", "2", "3"}


For some reason Map seems to ignore the attribute HoldFirst. Is there a reason for this? The closest I see in the documentation to an answer is this:

"Map always effectively constructs a complete new expression and then evaluates it."

But, I don't think this is the problem, because I see similar behaviour with Scan.

Any insight would be appreciated. Thanks.

-

You have to think about, what happens when you evaluate the line l1={a,b,c}. At this point, all your variables on the right side are evaluated and l1 contains only the data.

The solution is simple: use Hold instead of List

a = 1;
b = 2;
c = 3;

l1 = Hold[a, b, c];

ReleaseHold[{printName /@ l1}]

-
Ah, of course. Thanks for the help! –  shopper Jul 13 '13 at 7:54