Through: how to use it with subtraction of functions?

As the documentation says the command Through works as it follows:

f[x_]=x;
g[x_]=x^2;
Through[(f+g)[x]]

--> x + x^2


Like this, I also expect it works as below:

Through[(f-g)[x]]

--> x - x^2


It, however, returns:

Through[(f-g)[x]]

--> x + (-g)[x]


Do you guys know how to make Mathematica return as I expect for the subtraction?

I use Mathematica11.1 on Windows10 64bit.

• Taiki, you might want to use SetDelayed (:=) instead of Set (=) when defining f and g (i.e., ClearAll[f, g]; f[x_]:= x and g[x_]:= x^2 ) if you want Through[(f + g)[z]] to give z+z^2 (not f[z]+g[z]). – kglr Jul 8 at 20:42
• @kglr I don't see any difference between SetDelayed(:=) and Set(=) in this case. I understand general definitions of SetDelayed(:=) and Set(=) – Taiki Bessho Jul 8 at 20:52

To understand what's happening always check the FullForm of your expresion.

FullForm[(f - g)[x]]

(* Plus[f,Times[-1,g]] *)


That is the expression Mathematica is working with internally. Probably you were expecting Subtract[f, g][x], but that is not the case.

You could ReplaceAll (/.) the Times[-1,#] with Composition[Minus,#].

Through[(f-g)[x]]/.Times[-1,q_]->Composition[Minus,q]
(* f[x]-g[x] *)

%//FullForm
(* Plus[f[x],Times[-1,g[x]]] *)


You can compose Minus with g use it with Plus:

Through[(f + Minus @* g)[x]]


x - x^2

Other ways:

Through[(f + (-g @ # &))[x]]


x - x^2

Through[(f + (-#&) @* g)[x]]


x - x^2

I sometimes want to apply a linear combination of functions to an argument. This can be more difficult if the linear combinations are generated by code, so that rewriting them some form to make Through convenient is difficult. So I usually use a utility like the following:

linearThrough[(Optional[a_?NumericQ] f_ + Optional[b_?NumericQ] g_)[x__]] :=
a f[x] + b g[x];


OP's example:

linearThrough[(f - g)[x]]
(*  f[x] - g[x]  *)


You can also use Subtract if you prevent it from evaluating to Plus[f, Times[-1, g]] prematurely:

Through[Unevaluated@Subtract[f, g][x]]
(*  f[x] - g[x]  *)


Since I somewhat broadened the scope by bring in linear combinations of functions, here is a similar utility, in which the linear operators are specified as a argument, everything else is assumed to be constant:

linearOperate[heads_List][comb_[x__]] :=
(comb /. F : Alternatives @@ heads :> F[x]) /;
InternalLinearQ[comb, heads] || FreeQ[comb, Alternatives @@ heads];


Examples:

linearOperate[{f, g}][(f - g)[x]]
(*  f[x] - g[x]  *)

linearOperate[{f, g, h}][(a f - g + h - b + 9)[x]]
(*  9 - b + a f[x] - g[x] + h[x]  *)

linearOperate[{f, g, h}][(a f)[x]]
(*  a f[x]  *)

linearOperate[{f, g, h}][(3)[x]]
(*  3  *)


This last example is the reason for the extra test, ... || FreeQ[comb, Alternatives @@ heads]: InternalLinearQ says a constant is not linear:

InternalLinearQ[3, {f, g, h}]
(*  False  *)
`