1
$\begingroup$

Consider the following function:

f[arg_] := Print[Unevaluated[arg]]; Attributes[f] = HoldAll; 

The purpose of the function is to print the arguments unevaluated. In particular, what's important to me is that a symbol that already has a value will be printed as the symbol and not the value. For example:

x = 1; f[x]; 

The output is x as desired. But now I want to have the same behaviour with multiple arguments, either as a List or a BlankSequence. Here are my attempts:

With a List:

fList[args_] := Print[Unevaluated /@ args]; Attributes[fList] = HoldAll; x = 1; y = 1; fList[{x, y}] 

With a BlankSequence:

fBS[args__] := Print[Unevaluated /@ {args}]; Attributes[fBS] = HoldAll; x = 1; y = 1; fBS[x, y] 

In both cases the expected output is {x, y}, but what I actually get is {Unevaluated[1], Unevaluated[1]}! It seems that the HoldAll attribute doesn't actually do anything in these cases... Is there any way to solve this issue?

Thanks.

Edit in response to comments:

I understand that f[{x,y}] with the original f will work, if all I want to do is print the arguments. But what I wrote here is just a simple toy example. The actual function I want to use in my program does other things with the arguments, and needs to be able to access each argument's symbol individually.

Consider this (also toy) example instead:

g[arg_] := ToCharacterCode[ToString[Unevaluated[arg]]]; Attributes[g] = HoldAll; x = 1; y = 1; 

The output of g[x] will be {120}. But the output of g[{x, y}] will be {123, 120, 44, 32, 121, 125} which is of course not what I want. I want a function that will return {120, 121}, i.e. the character codes of the letters x and y.

If I try for example:

gList[args_] := ToCharacterCode[ToString /@ Unevaluated[args]]; Attributes[gList] = HoldAll; gList[{x, y}] 

I get {{49}, {49}} which are the character codes of 1, instead of {{120}, {121}} which is what I want. Is there any function that will return the desired result?

$\endgroup$
9
  • $\begingroup$ For the case of fList, just use your f (f[{x, y}]). For the case of dBS, use fBS[args__] := f[{args}]. There is no need to map on individual arguments, if you anyway want them all to print unevaluated values. $\endgroup$ Commented Aug 2, 2021 at 17:12
  • 2
    $\begingroup$ The issue is that Map[Unevaluated, {args}] evaluates {args}. $\endgroup$ Commented Aug 2, 2021 at 17:13
  • $\begingroup$ Thanks! Please see my edit for a clarification. $\endgroup$ Commented Aug 2, 2021 at 18:42
  • $\begingroup$ In your updated gList example, ToString is not a Hold function and evaluates its argument. You could fix this by using Function[Null, ToString[Unevaluated[#]], HoldAll] or by defining a new HoldFirst toString function that doesn't evaluate its argument. $\endgroup$ Commented Aug 2, 2021 at 18:50
  • $\begingroup$ Attributes[g] = {HoldAll, Listable};? $\endgroup$ Commented Aug 2, 2021 at 18:51

1 Answer 1

2
$\begingroup$

Your original f already handles the List case:

f[arg_] := Print[Unevaluated[arg]]; Attributes[f] = HoldAll; x = 1; y = 1; f[{x, y}] 

For the multi-argument version, you need to hold the arguments before passing them to Map. For example, using HoldComplete:

fBS[args__] := Print @@ Unevaluated /@ HoldComplete[args]; Attributes[fBS] = HoldAll; x = 1; y = 1; fBS[x, y] 
$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.