# Pure function inside another pure function

I have the following working expression:

In[15]:= Length[Select[IntegerPartitions[10],First[#1]==5&]]
Out[15]= 7


But, instead of using the constant 5 I want to map all values from 1 to 10 into this function. If I nest the pure function inside another it doesn't work:

In[18]:= Map[Length[Select[IntegerPartitions[10],First[#]==#&]]&,Range[10]]
Out[18]= {0,0,0,0,0,0,0,0,0,0}


What is the way to do this?

• You may need to use the variant form Map[Function[{x},...,First[#]==x&]]],...]. – Daniel Lichtblau Dec 6 '13 at 22:29
• This variant seems to work. Map[ With[{a = #}, Length[Select[IntegerPartitions[10], First[#] == a &]]] &, Range[10]] Out[257]= {1, 5, 8, 9, 7, 5, 3, 2, 1, 1} – Daniel Lichtblau Dec 6 '13 at 22:31
• The name is not virtual function but Pure Function in a Mathematica context. – Sjoerd C. de Vries Dec 6 '13 at 23:41
• Possibly duplicate (16947). – Silvia Dec 7 '13 at 4:26

You can have a pure function inside a pure function even in this case, you just can't have the name of the parameter being "#" in both. This works:

Map[Function[x,
Length[Select[IntegerPartitions[10], First[#] == x &]]], Range[10]]

• Just a nit to pick since I think someone unused to Mathematica might get confused, I think it’d be better to say that “the parameter # in the outer function gets overwritten in the inner function # and so it needs to be bound to a different name either via Function[x, ...] or With[{x=#}, ...]”. – b3m2a1 Mar 16 '20 at 20:22

This is probably not going to be the best answer but offering it as an opener or as a guide to towards a better solution

Setting your initial input as a function

f[n_]:=Length[Select[IntegerPartitions[10],First[#]==n&]]


then

Map[f,Range[10]]

{1, 5, 8, 9, 7, 5, 3, 2, 1, 1}


No doubt regular contributors can improve on this

Using Curry or OperatorApplied

Pure function nesting is one of the use cases for Curry, introduced in version 11.3:

Length[
Select[IntegerPartitions[10], Curry[First[#] == #2 &][#]]
] & /@ Range[10]

(* {1, 5, 8, 9, 7, 5, 3, 2, 1, 1} *)


First[#1] == #2 & defines a two argument pure function. By wrapping Curry[...][#] around this, we bind the inner slot reference #2 to the value of the outer slot reference #. After binding, we are left with a single argument function that is suitable for use with Select. For example, in one mapping iteration the outer # has the value 7 and the curried function Curry[First[#1] == #2 &][7] is essentially equivalent to First[#1] == 7 &.

Update for version 12.1

In version 12.1, OperatorApplied is the new name for Curry. The documentation for Curry states that it is now being phased out.

Currying The Hard Way

A rather obscure idiom makes it possible to perform such currying in pure functions, even before version 11.3:

Length[
Select[IntegerPartitions[10], #0[[0]][First[#[1]] == #2] &[Slot, #]]
] & /@ Range[10]

(* {1, 5, 8, 9, 7, 5, 3, 2, 1, 1} *)


The cryptic expression #0[[0]][First[#[1]] == #2]&[Slot, #] performs the necessary currying. #0[[0]] expands to Function. The disguised use of the symbol Function is necessary to avoid shadowing the inner slot references. #[1] expands to Slot[1], i.e. #1. #2 expands to the value of the outer #. So, if the outer # were 7, then we would get First[#1] == 7 & as desired.

This construction is likely too ugly to actually use. Thank goodness for the arrival of Curry :)

• This is a nice use case I for one had not anticipated. – Daniel Lichtblau Apr 27 '19 at 13:05

You can also perform this without "netsted functions" issue. For example:

Count[IntegerPartitions[10][[All, 1]], #] & /@ Range[10]


It could be even faster but we have to assume that you know the output of IntegerPartitions (explained on the bottom):

Reverse @ Tally[IntegerPartitions[10][[All, 1]]][[All, 2]]


Description

• IntegerPartitions[10][[All, 1]] because only first elements are important

• [[All, 2]] after Tally -> here we assume that we know that there will be a set of values from 1 to 10, otherwise some sort of filtering is needed.

• Reverse because IntegerPartitions list values are decreasing.