Here's my approach to determine the number of slots in the pure function without counting those in any sub-functions. That means MapIndexed[#1^#2 &, #1] &
(per @TeakeNutma's comment in @JohnMcGee's answer) will only return one slot. I do this by deleting all inner Function
s before counting the slots:
Clear[slotCount]
slotCount[f_Function]:=Module[{deleteInner},
deleteInner=Replace[f,_Function:>Sequence[],{1,Infinity}];
DeleteDuplicates[Cases[deleteInner,_Slot,{1,Infinity},Heads->True]]//Length
]
Notes: Using Heads->True
for Cases
will count slots correctly for cases like #1[#2]
.
Testing on the example functions in @TeakeNutma's answer
{#,slotCount[#]}&/@{Function[{},Null],MapIndexed[#1^#2&,#]&,#1+#2&,{#1,#2,#3,##}&,#1+#4&}//Grid[#,Frame->All]&
I'm not quite sure #1 + #4 &
would have 4 slots (instead of just 2). Below is a modified version of my slotCount
function that will return 4:
Clear[slotCountPositionAware]
slotCountPositionAware[f_Function]:=Module[{deleteInner,slotList,maxSlot},
deleteInner=Replace[f,_Function:>Sequence[],{1,Infinity}];
slotList=DeleteDuplicates[Cases[deleteInner,_Slot,{1,Infinity},Heads->True]];
maxSlot[l_List]:=If[l=={},0,l/.Slot[x_]:>x//Max];
maxSlot[slotList]
]
{#,slotCountPositionAware[#]}&/@{Function[{},Null],MapIndexed[#1^#2&,#]&,#1+#2&,{#1,#2,#3,##}&,#1+#4&}//Grid[#,Frame->All]&
Count[f, _Slot, ∞]
$\endgroup$#one + #two &
) $\endgroup$GoodFuncQ[func]
returns true iffunc
has exactly 2 arguments, otherwise, false. $\endgroup$Check
for error messages during application, as I suspect such tests cannot be written robustly for all possible input, at least not without unreasonable overhead. Perhaps one of the argument testing frameworks I presented here will be useful to you. $\endgroup$