1. SetDelayed说实话我没有详细探索过,但它应该也属于虽可编译但高度受限的情况。这里可以提供一个例子:
Compile[{b}, With[{a := 1}, b + a]] // CompilePrint
2. 这个其实我在你之前在SE的某答案下面也解释过一遍,并不是Evaluate让代码可编译了,而是Evaluate使得那段代码在被Compile“接手”前进行了计算,而计算生成的表达式又恰好可以编译。比如,
Compile[{x, y}, Evaluate@EuclideanDistance[{x, y}, {1, 2}]] // CompilePrint
其实是等效于将
Compile[{x, y}, EuclideanDistance[{x, y}, {1, 2}]]
的
EuclideanDistance[{x, y}, {1, 2}]
部分选中然后Ctrl+Shift+Enter,也就是说,Compile接收到的只是
Sqrt[Abs[-1 + x]^2 + Abs[-2 + y]^2]
一个与使用Evaluate效果相当的做法是使用纯函数 Compile[{x, y}, #] &[EuclideanDistance[{x, y}, {1, 2}]]
原理当然也是一样的:调节计算次序,突破Compile的HoldAll属性。关于这个,其实可以参考这帖:
http://tieba.baidu.com/p/4886024974 ——其实,我早想动笔却一直没写的《计算次序杂谈》的核心部分可以说就在这帖里。