I want to have a function called printRes[expr_,var_], which does the following:


(* derivative of a*x^3 relative to x is 3ax^2, and when x=1, result is 3a. *)

I am unable to put all this into a row after many tries. How do I do it?

  • $\begingroup$ Like StringTemplate["The derivative of `fun` with respect to `var` is `res` when `var` = `val`"]@<|"fun" -> ToString[f, TraditionalForm], "var" -> x, "val" -> 1, "res" -> ToString[D[f, x] /. x -> 1, TraditionalForm]|>? $\endgroup$ – J. M. is away Dec 10 '16 at 12:44
  • $\begingroup$ Hi, @J.M. Thanks for mention StringTemplate, haven't used it before. But there is a problem, x=1 must be evaluated before evaluation of printRes $\endgroup$ – matheorem Dec 10 '16 at 12:50
  • $\begingroup$ So, what did you see after running the snippet I gave? Note the expression fed to "res" in the association. $\endgroup$ – J. M. is away Dec 10 '16 at 12:53
  • $\begingroup$ @J.M. Your solution seems not give the expected result. I have edited my post to make it more clear $\endgroup$ – matheorem Dec 10 '16 at 13:05
  • $\begingroup$ Well, the trouble is that you assigned x to be 1 at the outset. $\endgroup$ – J. M. is away Dec 10 '16 at 13:08

Localize your x using Block. Use LocalizedBlock if you want to allow non-symbols for x.

SetAttributes[printRes, HoldAll]
printRes[expr_, x_] :=
   Print[D[expr, x]]

If you really want to both make use of the value of x and ignore it,

SetAttributes[printRes, HoldAll]
printRes[expr_, x_] :=
   res = Hold[Evaluate@D[expr, x]];
  {res, ReleaseHold[res]}

But I find a function with such behaviour weird and confusing.

  • $\begingroup$ Thank you so much, Szabolcs! I just understand your answer, very neat and clear. upvoted $\endgroup$ – matheorem Dec 10 '16 at 15:29
  • 1
    $\begingroup$ A complete solution would be like this : ClearAll[printRes]; SetAttributes[printRes, HoldAll]; printRes[expr_, x_] := Module[{expr0, res}, Block[{x}, expr0 = HoldForm@Evaluate@expr; res = HoldForm@Evaluate@D[expr, x];]; Row[{"derivative of ", expr0, " relative to ", HoldForm@x, " is ", res, ", and when ", HoldForm@x, " = ", x, ", result is ", ReleaseHold[res], "."}]] $\endgroup$ – matheorem Dec 10 '16 at 15:31

How about:

SetAttributes[printRes, HoldAll]
With[{trad = TraditionalForm}, 
 With[{hold = trad@HoldForm@# &}, 
  printRes[expr_, y_] := 
   "derivative of " <> #1 <> " relative to " <> #2 <> " is " <> #3 <> 
      ", and when " <> #2 <> "=" <> #4 <> ", the result is " <> #5 & @@ 
    ToString /@ 
     Block[{y}, {hold@expr, hold@y, hold@D[expr, y], trad@y, trad@D[expr, y]}]]]
  • $\begingroup$ Hi, xzczd. Thank you so much. It works! But I just found I missed something important in my post which may bring true difficulty. Take a look at my updated post again. Very sorry for my mistake. $\endgroup$ – matheorem Dec 10 '16 at 14:09
  • $\begingroup$ @matheorem I found a cleaner solution, check my update. $\endgroup$ – xzczd Dec 10 '16 at 14:14
  • $\begingroup$ upvoted! Thank you so much. It is weird that it is failed on my first try. But it seems great now. I need sometime to figure it out : ) $\endgroup$ – matheorem Dec 10 '16 at 14:25
  • $\begingroup$ @matheorem Well, this solution has avoided most of the Hold* stuff, the key point is the Block. We first use Block to temporarily localize the variable so expr, D[expr, y], etc. will evaluate but not evaluate to a number, then use HoldForm to hold those should not evaluate even if they're no longer inside the Block. For more information, try printRes[expr, x] // Trace. $\endgroup$ – xzczd Dec 10 '16 at 14:46
  • $\begingroup$ I think the truth is more tricky. You used hold=HoldForm@#& instead of hold=HoldForm makes an essential difference (neglect TraditionalForm) $\endgroup$ – matheorem Dec 10 '16 at 15:10

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.