# How to pre-evaluate parts of a lambda or a delayed-assigned function?

I have an expression which I'd like to evaluate and use as a subexpression of a delayed-assigned expression. But I need it to be evaluated before actual assignment, while other parts of the full expression shouldn't be evaluated at this stage. See this simple example.:

testFunc[f_] := Evaluate[(5 + x - x)] D[f, x]


If I enclose the whole RHS into Evaluate, the expression does pre-evaluate, but since f doesn't explicitly depend on x, the whole expression becomes 0. OTOH, if done verbatim as above, Evaluate has no effect, and ?testFunc tells me that the RHS wasn't evaluated before assignment.

I've tried some other approaches, like this:

testFunc = Evaluate[(5 + x - x)] D[#, x] &


or this (hoping that the replacement will actually evaluate its RHS):

testFunc = mark[(5 + x - x)] D[#, x] & /. mark[x_] :> Evaluate[x]


But these approaches also don't appear to work.

Of course, one way is like

With[{expr = 5 + x - x}, testFunc = expr D[#, x] &]


, but when there are multiple such expr things, this way becomes very hard to follow, especially if it was created from a formula which I just wanted to optimize by pre-evaluation or simplification.

So, what is a good way to achieve pre-evaluation of subexpressions in delayed assignments or lambdas?

You could make your mark thing work like this:

evalmark = Function[Null, Unevaluated[#] /. mark[x_] :> RuleCondition[x], HoldFirst];

evalmark[
test1[f_] := mark[5 + x - x] D[f, x];
test2[f_] := mark[x + x] f^2;
]

?test1
?test2


test[f_] := 5 D[f,x]

test2[f_] := (2 x) f^2

• Hmm, what does RuleCondition actually do? Does it evaluate the match before it's applied as a replacement? Feb 25 '17 at 6:20
• @Ruslan, yes exactly. Look here for more information. Feb 25 '17 at 9:20

Unless I've missed something obvious (always a possibility), what you want is simple to implement by writing a factory function.

Clear[x]; makeF[expr_] = expr D[#, x]&;


Then

f = makeF[5 + x - x]


5 D[#1, x]&

f[2 x]


10

and

Module[{y = 3}, g = makeF[5 x + y]]


(3 + 5 x) D[#1, x]&

g[Sin[x]]


(3 + 5 x) Cos[x]

• I think something * D[f,x] was just an example. The intention is to replicate the behaviour of With but to do it in-place, ie without removing the pre-evaluated terms from the original expression. Feb 25 '17 at 9:26

testFunc[f_, expr_] := Module[{localexpr},
localexpr = expr; (* Evaluates automatically *)
Print[localexpr];
Return[localexpr D[f, x]];
];

expr = (5 + x - x);
f = 2 x;

testFunc[f, expr]
(* 5
10 *)


The Print is only to confirm that expr indeed has been evaluated.

• The Evaluate is superfluous. Feb 24 '17 at 22:03
• You are right, change incorporated. Feb 24 '17 at 22:05
• If I'm not mistaken, this suggests what I already showed in the OP as the "last resort" solution, not really acceptable. Feb 25 '17 at 6:14