# Replacement Rule for Functions

Attempting to write a rule that will substitute an undetermined function of several variables by some other undeterminate functions (also, of the same several variables). I can do it in an inelegant way that is not very reusable (requires the specification of all the arguments individually). I'd like to be able to do it for any number of arguments. Unfortunately, I stumble into the following problem:

The following two rules return the same output when applied to a function

f @@ var /. f -> ( h[#1, #2, #3, #4] + g[#1, #2, #3, #4] &)
(* g(t,x,y,z)+h(t,x,y,z) *)
f @@ var /. f -> ( h[##] + g[##] &)
(* g(t,x,y,z)+h(t,x,y,z) *)


Here var = {t,x,y,z}. Unfortunately, they return different results when applied to the derivative of that function.

D[f @@ var, x] /. f -> ( h[#1, #2, #3, #4] + g[#1, #2, #3, #4] &)
(* g^(0,1,0,0)(t,x,y,z)+h^(0,1,0,0)(t,x,y,z) *)
D[f @@ var, x] /. f -> ( h[##] + g[##] &)
(* 0  *)


I'd like to understand both why the second rule doesn't work and why the first one does.

To clarify, my question is how to write a rule that does what the first of the above rules performs on both function and derivatives that can easily be applied to functions with many arguments.

• Carefully comparing FullForm[f @@ var] with FullForm[D[f @@ var, x]], and then taking a look at what you're actually trying to replace in D[f @@ var, x] /. f -> ( h[##] + g[##] &) should explain this behavior. – user6014 Mar 3 '19 at 22:02
• Are you at all able to formulate your replacement this way? D[(f @@ var) /. f -> (h[##] + g[##] &), x] – user6014 Mar 3 '19 at 22:05
• Here is the answer to why it does not work: Derivative of a pure function with SlotSequence – Kuba Mar 4 '19 at 20:58

I think you have found one of the quirks of the convoluted Mathematica evaluation rules. I suggest you try instead the alternative code:

D[f @@ {t. x, y, z}, x] /. {dd_[nn__][f][xx__] -> dd[nn][g][xx] + (dd[nn][h])[xx]} // InputForm


which returns

Derivative[0, 1, 0, 0][g][t, x, y, z] + Derivative[0, 1, 0, 0][h][t, x, y, z]


The reason for this is that the Derivative[] function returns an unusual expression form:

D[ f[x], x] == Derivative[1][f][x]


which is more convoluted than expected and why the replacement rule has to accept this form.

If you write g[##] + h[##] & in alternative form Total @* (Through @ {g, h} @ ## &) you get the desired result:

D[f @@ var, x] /. f -> (Total @* (Through @ {g, h} @ ## &))


Alternatively, you can inject g[##] + h[##] & for f in D[...] using With:

With[{f = (g[##] + h[##] &)}, D[f @@ var, x]]
% == %%


True