不确定您需要哪种递归,但根据我的经验(受 Haskel 启发?)您的函数定义中的first,rest 模式可能非常强大:
f[onearg_]:=onearg
f[first_,rest__]:=first+2 f[rest]
In[148]= Trace@f[2,3,4]
Out[148]= {f[2,3,4],2+2 f[3,4],{{f[3,4],3+2 f[4],{{f[4],4},2 4,8},3+8,11},2 11,22},2+22,24}
当然,如果需要,您可以访问Length[{rest}]。
编辑 2:(Pilsy 指出,旧图不正确)Mathematica 实际上复制了“其余”部分,因此如果实际函数的成本可以忽略不计,则缩放变为二次方。
f[] := 0;
f[onearg_] := onearg[[1, 1]];
f[first_, rest__] := f[first] + f[rest];
ListLogLogPlot[Part[#, -1, 1],
Joined -> True, PlotRange -> {{100, All}, Automatic},
AxesLabel -> {"#Arguments", "Runtime"}] &@
Reap@Nest[
Function[all,
Sow[{Length[all], First@Timing[Table[f @@ all, {10}]]}];
Join[all, RandomReal[{-1, 1}, {10, 10, 10}]]], {}, 100]
下图显示了上面的廉价内部函数f[onearg_]:=onearg[[1,1]] 的输出,其中缩放在参数数量上确实是二次的,而对于昂贵的内部函数f[onearg_]:=SingularValueList[onearg,1],缩放更接近于线性。