2
$\begingroup$

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?

$\endgroup$
5
$\begingroup$

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

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

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]

$\endgroup$
1
  • $\begingroup$ 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. $\endgroup$ Feb 25 '17 at 9:26
0
$\begingroup$

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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.