SymbolName applied to a list of variables, some of which may have values assigned

寵の児 提交于 2019-12-11 08:58:23

问题


In Mathematica:

I would like to pass a variable number of arguments to a function.

I would like to print the name of each argument. The problem is that SymbolName evaluates its input. For a given variable, you can get around this:

a=18;
SymbolName[Unevaluated[a]]

works. But that won't work if the variable is in a list. For example:

printname[x__]:=Print[Table[SymbolName[Unevaluated[{x}[[i]]]],{i,1,Length[{x}]}]];
printname[a,b,c]

will not work. Any suggestions?

Thanks in advance.


回答1:


Mathematica tries to evaluate the argument of Unevaluated[] when you call it. So {x}[[i]] gets converted into {18, b, c}[[i]] which you didn't want and then the iteration over i doesn't work anymore because Unevaluated[] doesn't let the Table access the iterator.

So, to really solve the issue you should disable Mathematica's evaluation completely for the functions that you want to pass the symbols through.

In[1]:= SetAttributes[SymbolName, HoldAll];
        SetAttributes[Map, HoldAll];

After this you can just do

In[2]:= a=18; SymbolName @@@ Unevaluated /@ {a, b, c}
Out[2]:= {a, b, c}

where @@@ and /@ are shorthand for Apply[] and Map[].

Setting Hold[] or similar attributes in Mathematica's built in functions can lead to trouble. See this question and answer in the Mathematica stackexchange for more information.

Specifically, to make a function that takes an arbitrary number of arguments would be

sym = SymbolName @@@ Unevaluated /@ {##} &

But the List[] function that takes the sequence of arguments ## for the function & will again evaluate a and turning HoldAll on for List[] is not OK.

Thus the easiest way to do this is to define a function with HoldAll that just passes the args into a Block[] as the list of local variables. This makes a creates an isolated context where the variables do not evaluate to anything.

In[1]:= SetAttributes[f, HoldFirst];
In[2]:= f[seq__] := Block[{seq}, Print[SymbolName /@ {seq}]];
In[3]:= a=18; f[a, b, c]
Out[3]:= {a, b, c}


来源:https://stackoverflow.com/questions/31040972/symbolname-applied-to-a-list-of-variables-some-of-which-may-have-values-assigne

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!