【发布时间】:2011-06-07 14:53:29
【问题描述】:
Mathematica 的求值器通常持有(或恢复?)Heads Unevaluated 作为 Symbols 的参数提供的表达式:
In[1]:= f[s, Unevaluated[1 + 1]]
Out[2]= f[s, Unevaluated[1 + 1]]
In[5]:= Trace[f[s,Unevaluated[1+1]],TraceOriginal->True]
Out[5]= {f[s,Unevaluated[1+1]],{f},{s},f[s,1+1],f[s,Unevaluated[1+1]]}
但RuleDelayed 并非如此。此外,在RuleDelayed 的情况下,任何 个 Unevaluated 包装器都会被剥离:
In[1]:= Attributes@RuleDelayed
RuleDelayed[s, Unevaluated[1 + 1]]
RuleDelayed[s, Unevaluated@Unevaluated[1 + 1]]
RuleDelayed[s, Unevaluated@Unevaluated@Unevaluated[1 + 1]]
RuleDelayed[Unevaluated@Unevaluated@Unevaluated[1 + 1], 1 + 1]
Out[1]= {HoldRest, Protected, SequenceHold}
Out[2]= s :> 1 + 1
Out[3]= s :> 1 + 1
Out[4]= s :> 1 + 1
Out[5]= 2 :> 1 + 1
为什么在RuleDelayed 的情况下,评估器会剥离任何 个Unevaluated 包装器?它对哪些用途有用?是否可以为任意Symbol(例如f)模拟这种行为?
也不清楚为什么Trace 显示的RuleDelayed 比f 更复杂:
In[2]:= Trace[RuleDelayed[s,1+1],TraceOriginal->True]
Out[2]= {s:>1+1,{RuleDelayed},{s},s:>1+1,s:>1+1,{RuleDelayed},{s},s:>1+1}
看起来RuleDelayed 被评估了两次...
【问题讨论】:
-
如果不删除它...不会导致两个嵌套的
Unevaluated? -
@belisarius 对于
f[s, Unevaluated[1 + 1]],一切都很简单。从哪里我们会得到两个嵌套的Unevaluated? -
@Sasha 在我之前回答(而且更好)
-
“但 RuleDelayed 并非如此,尽管它甚至具有 HoldRest 属性” - 正如我们多次讨论过的那样,
HoldRest(几乎)无关紧要 - 它只是将头部置于决定如何处理传递给它的原始表达式。如果Unevaluted的标准语义总是被强制执行,那么 evaluator 本身也是无关紧要的。真正的问题 IMO(我当然可能是错的)是为什么RuleDelayed的行为方式如此,或者,如果仍然证明评估者是罪魁祸首,为什么对评估者的行为做出例外处理. -
我认为函数属性确实与评估者有关。我的意思是属性与问题无关,至少如果您将其重新表述为“为什么 any 数量的
Unevaluated包装器被RuleDelayed剥离”。正如我在下面提到的cmets,Unevaluated的标准语义(也与评估器有关)不能解释在单个评估中剥离多个Unevaluated包装器,也不能解释在剥离单层Unevaluated时重新评估- 这些必须是相关头部的属性(RuleDelayed)