2

Say I have a function f[x_]:=a x + b. Now I want to get the a x + b part from the function to use in e.g. StringForm. This without using HoldForm or Unevaluated in the definition of f

That is, I want the function ExpandOnce:

In[1] := f[x_]:=a x + b
         StringForm["f(x)=``",ExpandOnce[f]]
Out[1]:= f(x)=a x + b

The above could work by using the Definition command, but that also includes the left hand side of the definition. It would also be great if it's not restricted to only definitions, but also any variable that holds an expression. E.g. %.

Any help appreciated.

I would expect this to be somewhere in this forum, but I've only found nuances of this.

Related links

Carl Woll
  • 130,679
  • 6
  • 243
  • 355

2 Answers2

4

Assuming that f has only 1 downvalue, then you can use:

ExpandOnce[f] := Replace[
    DownValues[f][[1]],
    _[_, rhs_] :> HoldForm[rhs]
]

Your example:

Clear[f]
f[x_] := a x + b
StringForm["f(x)=``", ExpandOnce[f]]

f(x)=a x+b

Note that contrary to the answers in the comments, I don't use ToString in the definition of ExpandOnce. I think using ToString is usually a bad idea, as something like the following can happen:

Clear[f]
f[x_] := 10^-7 x + 1/2
StringForm["f(x)=``", ToString @ ExpandOnce[f]]
f(x)= x    1
--- + -
  7   2
10
Carl Woll
  • 130,679
  • 6
  • 243
  • 355
2

More general than going through the DownValues would be to Trace the evaluation and look only at the first step,

f[x_] := a x + b
StringForm["f(x)=``", Trace[f[x]][[2]]]

f(x)=a x + b

Of course if Trace[f[x]] is a huge affair, then this becomes very inefficient. Maybe the option TraceDepth -> 1 will help here:

f[x_] := a x + b
StringForm["f(x)=``", Trace[f[x], TraceDepth -> 1][[2]]]

f(x)=a x + b

For the % symbol the trace is longer, involving the lookup in the Out database. We must therefore go to the fourth evaluation step,

2 + 91
(* 93 *)
StringForm["%=``", Trace[%][[5]]]

%=93

Roman
  • 47,322
  • 2
  • 55
  • 121