Question on TraceScan
The main point of this question is the logic behind the operation of the first argument of TraceScan
(as well as the associated fourth argument but that is not needed for the problem in question): it sometimes excludes some evaluation steps (which Trace
with option TraceOriginal->True
gives) but sometimes it includes them as demonstrated in the following examples. I am interested in understanding the logic behind this behavior and how t开发者_开发技巧o force TraceScan
to give the full set of evaluation steps. This question originally arose in this thread (see my comments to the answer). The general comparison of the behavior of TraceScan
as compared to that of Trace
was given by WReach here but it does not answer the following questions:
1.) Why doesn't TraceScan
give the final expression f[a,1]
in this
case while Trace
gives:
In[1]:= SetAttributes[traceScan,HoldAll];
traceScan[expr_]:=(list={};TraceScan[AppendTo[list,#]&,expr];list)
In[3]:= ClearAll[f,a];
Trace[f[a,1],TraceOriginal->True]
Out[4]= {f[a,1],{f},{a},{1},f[a,1]}
In[5]:= ClearAll[f,a];
traceScan[f[a,1]]
Out[6]= {f[a,1],f,a,1}
2.) And, in the following case, why do both Trace
and TraceScan
give the
final expression f[1,a]
wheras only Trace
gives the intermediate expression
f[a,1]
which corresponds to the step of the evaluation before applying the Orderless
attribute of f
:
In[7]:= ClearAll[f,a];
SetAttributes[f,Orderless]
Trace[f[a,1],TraceOriginal->True]
Out[9]= {f[a,1],{f},{a},{1},f[a,1],f[1,a]}
In[12]:= ClearAll[f,a];
SetAttributes[f,Orderless]
traceScan[f[a,1]]
Out[14]= {f[a,1],f,a,1,f[1,a]}
3.) And why in this last case do both Trace
and TraceScan
give the final
expression ff[1,b]
and the intermediate expression ff[b,1]
which corresponds to the step of the evaluation before applying the Orderless
attribute of ff
:
In[21]:= ClearAll[f,ff,a];
SetAttributes[ff,Orderless];f=ff;a=b;
Trace[f[a,1],TraceOriginal->True]
Out[23]= {f[a,1],{f,ff},{a,b},{1},ff[b,1],ff[1,b]}
In[24]:= ClearAll[f,ff,a];
SetAttributes[ff,Orderless];f=ff;a=b;
traceScan[f[a,1]]
Out[26]= {f[a,1],f,ff,a,b,1,ff[b,1],ff[1,b]}
4.) Is there a way to force TraceScan
to always give exhaustive
information about evaluation as Trace
does?
In addition
Here is another, more informative version of traceScan
which uses the fourth argument:
SetAttributes[traceScan, HoldAll];
traceScan[expr_] := (list1 = list2 = {};
TraceScan[AppendTo[list1, #] &, expr, _,
AppendTo[list2, {##}]&];
Column[{list1, list2}])
Cases 1 and 2. Citing the Documentation:
Normally, ...
Trace
intercepts expressions only after function arguments have been evaluated. By settingTraceOriginal->True
, you can getTrace
also to look at expressions before function arguments have been evaluated.
It seems that setting TraceOriginal->True
just results in prepending additional information to the default output of Trace
. As the result, we see unnecessary additional "intermediate expression" f[a,1]
which in really does not appear in the evaluation chains in both cases as it is shown by TraceScan
and TracePrint
:
In[1]:= ClearAll[f, a];
SetAttributes[f, Orderless]
TracePrint[f[a, 1]]
During evaluation of In[1]:= f[a,1]
During evaluation of In[1]:= f
During evaluation of In[1]:= a
During evaluation of In[1]:= 1
During evaluation of In[1]:= f[1,a]
Out[3]= f[1, a]
So it looks like a bug in Trace
.
Case 3. In this case everything works as expected because the intermediate expression ff[b,1]
indeed appears in the evaluation chain as the result of applying of the definition associated with f
. Nothing unexpected.
Conclusion. Both Trace
and TraceScan
give exhaustive information about evaluation chain but the output generated by Trace
can additionally contain misleading "intermediate expression" which is in fact just the initial expression of the chain.
精彩评论