# Defining an operator: Partially evaluate a Pure Function

I would like to define an operator that takes some parameters as input and returns a function. Here is an example:

operator[indexLists_] := Function[weights,Table[Total[weights[[indexLists[[i]]]]], {i, Length[indexLists]}]];
example = {{1, 2, 3}, {5, 2, 1}, {1, 2}, {6, 7}};
op1 = operator[example]


which returns

Function[weights$, Table[Total[ weights$[[{{1, 2, 3}, {5, 2, 1}, {1, 2}, {6, 7}}[[i]]]]], {i, Length[{{1, 2, 3}, {5, 2, 1}, {1, 2}, {6, 7}}]}]]


what I would want is a partially evaluated version, i.e.

op2 = Function[weights, {Total[weights[[{1, 2, 3}]]], Total[weights[[{5, 2, 1}]]], Total[weights[[{1, 2}]]], Total[weights[[{6, 7}]]]}]


Both op1 and op2 return functions that perform the same thing, e.g. when called with "Range" as argument they return {6, 8, 3, 13}.

This is a toy example. In my real example, the function returned by the operator performs some complex transformation of the input parameter "weights" that I want to pre-compute in order to be more efficient when evaluating the function many times. I could not figure out how to get around to HoldAll attribute of the pure function.

One idea is to use Inactive/Activate:

operator[indexLists_] := Block[{weights},
Activate @ Inactive[Function][
weights,
Table[Inactive[Total][Inactive[Part][weights,indexLists[[i]]]],{i,Length[indexLists]}]
]
]


Inactivating Function wasn't strictly necessary, but it prevented the variable weights from being modularized to weights\$. Inactivating Total and one of the Part functions prevented undesired evaluations. Your example:

example = {{1,2,3},{5,2,1},{1,2},{6,7}};
op1 = operator[example]


Function[weights, {Total[weights[[{1, 2, 3}]]], Total[weights[[{5, 2, 1}]]], Total[weights[[{1, 2}]]], Total[weights[[{6, 7}]]]}]

and

op1[Range]


{6, 8, 3, 13}

An approach to circumvent the HoldAll attribute is to "inject" the expressions into Function after (partially) evaluating them:

operator[indexLists_] :=
Block[{weights, f},
Function[weights, #] & @Thread[f[weights, indexLists]] /.
f[xx__] :> Total[Part[xx]]]


Inside Block, I clear not only the variable weights but also an auxiliary f that is replaced at the very end with Total[Part[...]]. This replacement rule is one way to inject things into held expressions. Before that, I first create a slot # inside Function into which I insert the evaluated Table generated by the indexList argument to operator. This is where the temporary name f is used as a placeholder for the desired operation which can't be executed at that stage. It creates the necessary structure inside Function into which the replacement rule then inserts Total[Part[...]].