# How to create a list of variable names to some function of that variable

For example, for a single variable I can write

Print[Unevaluated[a], "=", f[a]]


But if I try the next thing I'd think of doing, assuming I want a list, it doesn't work (as intended):

Print[Unevaluated[#], "=", f[#]] & /@ {a, b, c}


This will print the actual value of a, instead of "a" itself (i.e. the variable name.) Any thoughts how I can achieve this?

-- Edit:

To be perfectly clear, I want something like:

{{"a", f[a]}, {"b", f[b]}, ...}


as the output. It tentatively seems to me that this just simply isn't possible (without putting a Hold or similar on every single thing in the list ...), but I hope I'm wrong.

-- Another edit:

Thanks for the comments; I've almost been able to do what I need. Here's the essential code:

{ SymbolName@Unevaluated[#] & /@ Unevaluated /@ Unevaluated@#1,
Distribute[f[#1, #2], List]} & @@
Unevaluated /@ Unevaluated@{{x, b, c}, {x, y}}


with output

{{x,b,c},{f(2,2),f(2,y),f(b,2),f(b,y),f(c,2),f(c,y)}}


Note that I'm only able to print "{x, b, c}" here. I actually would like a tree; i.e.,

{{x,{x,y}},{b,{x,y},{c,{x,y}}, {f(...), ...}


or something that is equivalent in letting my match the input to the output ..., any thoughts? I'm trying this myself but I keep getting stuck with how Unevaluated treats parameters ... (i.e. it's not listable; and Distribute seems to require that, in order to work in the expected way...)

(I should note, the only reason I want that tree form is because getting the exact form I asked for initially within the confines of the Distribute and so on seems harder (I couldn't work it out ...).) I don't actually care how it comes out, as long as I can Partition or whatever to get the appropriate structure.

-- Final edit:

Just incase anyone is interested, here is what I finally went with; it may not be amazingly elegant, but it's sufficient for what I needed. Note that it's actually neccessary to duplicate the expressions into the Unevaluated calls (afaik).

fMap = Flatten[Outer[f[#1, #2], A, B, 1]];
n1 = SymbolName@Unevaluated[#] & /@
Unevaluated /@ Unevaluated[{x, b, c, d}];
n2 = SymbolName@Unevaluated[#] & /@
Unevaluated /@ Unevaluated[{x, y, z}];


I can then create the listing I wanted via

Grid[{
grid1 =
Flatten@Insert[n1, ConstantArray["", Length@n2 - 1],
Table[{i + 1}, {i, Range[Length@n1]}]],
grid2 = Flatten@ConstantArray[n2, Length@n1],
fMap
}\[Transpose], Frame -> All];

-
I am sure what your purpose is but.. Print[ToString[#] <> "=" <> ToString[f[#]]] & /@ {a, b, c}; –  chris Sep 22 '12 at 9:37
@chris, try executing {a, b, c} = Range[3] before that. –  Ｊ. Ｍ. Sep 22 '12 at 9:39
Does Print[#, "=", f[#]] & /@ Defer /@ Unevaluated@{a, b, c} or Print[#, "=", f[#]] & /@ HoldForm/@ Unevaluated@{a, b, c} work for what you are trying to do? Or, Print[Unevaluated@#, "=", Unevaluated@f[#]] & /@ Unevaluated /@ Unevaluated@{a, b, c}?:) –  kguler Sep 22 '12 at 10:17
or Print[Unevaluated@#, "=", f[#]] & /@ Unevaluated /@ Unevaluated@{a, b, c} following kguler? This seems to do the same as your original statement. –  chris Sep 22 '12 at 10:19
I discussed Unevaluated in some detail in my post in this Mathgroup thread(my second post there). Some people found that useful. –  Leonid Shifrin Sep 22 '12 at 12:25

Print[{ToString@#, f @@ #}] & /@ HoldForm /@ Unevaluated@{a, b, c}
(* or *)
Print[{ToString@#, f @@ #}] & /@ Defer/@ Unevaluated@{a, b, c}


to get

{"a", f[1]}
{"b", f[2]}
{"c", f[3]}


printed. Remove Print, i.e. use {ToString@#, f @@ #} & /@ HoldForm /@ Unevaluated@{a, b, c} to get {{"a", f[1]}, {"b", f[2]}, {"c", f[3]}}.

To get {"a", f[a]} {"b", f[a]} {"c", f[a]}, change f@@# to f@#.

-
Accepting this because it answers what I originally asked. Note that I've added an extra little bit to the question now, though :) –  Noon Silk Sep 22 '12 at 11:36
@NoonSilk, thank you for the accept. I think it may be useful to treat the two parts in the new "bit" (constructing a tree and managing evaluation of symbols with assigned values) separately and combine them later. For the second part, it may be useful to update your question with information on which symbols have assigned values. –  kguler Sep 22 '12 at 12:26
You're right; doing everything seperately has worked. I think it also makes more sense this way. Thanks! –  Noon Silk Sep 22 '12 at 13:34
Hahaha, it turns out, this doesn't work, if instead of the list I have a variable containing the list ..., i.e. A = {a,b,c}; Print[{ToString@#, f @@ #}] & /@ HoldForm /@ Unevaluated@A; ... how strange. –  Noon Silk Sep 22 '12 at 13:46
@NoonSilk, this should not be surprising: note that once you set A={a,b,c}, A has the value {1,2,3}. Stuff you do with A after your initial assignment will not remember the symbols a, b, c. To get {"A",f[A]} you can simply use {ToString@#, f@#} &@HoldForm@A or to get {"A",f[{1,2,3}]} use {ToString@#, f @@ #} &@HoldForm@A. Note the use of @ before A as opposed to /@ (Map) which gets inside A and finds 1,2,3. –  kguler Sep 22 '12 at 14:08

Literally following what you've suggested you need as output:

{{"a", f[a]}, {"b", f[b]}, ...}

i.e. A list containing the string form name of a variable and the application of function f to that variable we get:

{SymbolName@#, HoldForm@f[#]} & /@ {a, b, c}


{{"a", f[a]}, {"b", f[b]}, {"c", f[c]}}

I hope this was what you wanted.

-
Following on from @kguler and @chris, it is actually: {SymbolName@Unevaluated[#], f[#]} & /@ Unevaluated /@ Unevaluated@{a, b, c}. Your version (as-is) has the same problem as the ealier ones; with apparently not enough Unevaluated's :) –  Noon Silk Sep 22 '12 at 10:27
Apologies, I didn't pick that up from the output line, now fixed, no Unevaluated needed. –  image_doctor Sep 22 '12 at 10:31