开发者

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 setting TraceOriginal->True, you can get Trace 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜