Не уверен, какая рекурсия вам нужна, но по моему опыту шаблон (вдохновленный Хаскелем?) 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: (Старый график был неправильным, как указал Пилси) 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]
, где масштабирование ближе к линейному.