2

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?

Ruslan
  • 7,152
  • 1
  • 23
  • 52

3 Answers3

5

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

Simon Woods
  • 84,945
  • 8
  • 175
  • 324
1

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]

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
  • 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. – Simon Woods Feb 25 '17 at 09:26
0

How about this

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.

Felix
  • 3,871
  • 13
  • 33