How combine pure functions of several slots? [duplicate]

How can one define in a functional way a 1st-order linear differential operator involving several independent variables that can then be applied to a function of that many variables?

Consider an example with two variables, where one wants to form D[f[x, y], x] + 3 D[f[x, y], y] from a function f. Of course one could define

diff[f_][x_, y_] := D[f[x, y], x] + 3 D[f[x, y], y]

so that for a function such as

g[x_, y_] := x^2 y + Cos[x + 2 y]

we just evaluate:

diff[g][x, y]
2 x y + 3 (x^2 - 2 Sin[x + 2 y]) - Sin[x + 2 y]   (* desired final output *)

But how can such an operator be defined functionally, that is, without explicitly using variables initially?

We could try

diffOp[y_] := Derivative[1, 0][y] + 3 Derivative[0, 1][y]

and then

diffOp[g]
3 (-2 Sin[#1 + 2 #2] + #1^2 &) + (-Sin[#1 + 2 #2] + 2 #1 #2 &)

But now how does one use such a combination of pure functions of several variables so as to produce the same result as from diff[g][x,y]?

The crux of the difficulty appears in the following simpler problem. Consider two functions of two variables:

g1 = (#1^2 + #2) &
g2 = Cos[#1 #2] &

How can one produce the same result as, say,

g1[x, y] + 3 g2[x, y]
(* x^2 + y + 3 Cos[x y] *)

directly from the functional linear combination g1 + 3 g2 -- by forming an expression of the form oper[g1 + 3 g2][x, y]?

By contrast with the single-variable situation, where a simple Through would serve as the oper',Through` will not work in the multi-variable situation here:

Through[(g1 + 3 g2)[x, y]]
(* x^2 + y + (3 (Cos[#1 #2] &))[x, y] *)

A pure function embedded in that output.

Note that a simple sum g1 + g2 instead of the linear combination g1 + 3 g2, Through will work (just as it does for a single variable):

Through[(g1 + g2)[x, y]]
(* x^2 + y + Cos[x y] *)
• Through[(g1 + g2)[x, y]]? Sep 27 '13 at 15:05
• Your question is somewhat misleading in that even the single argument function suffers from the same problem, i.e. Through[(f1 + 3 f2)[x]]
– gpap
Sep 27 '13 at 15:49
• Would a replacement based approach work for you, e.g. thru[expr_[vars__]] := expr /. f_Function :> f[vars] Sep 27 '13 at 15:51
• @gpap: Yep, my single-argument example was much too simple. Sep 27 '13 at 15:52
• I am closing this as a duplicate. Please see the linked question. If you feel that this is not a duplicate please edit your question make that clear and flag or vote to reopen. Sep 27 '13 at 17:27

In Mathematics, you can define new functions using operation on their images. Your example, $g_1+3 g_2$ is effectively defined as the function $x\mapsto g_1(x)+3g_2(x)$. Mathematicians use the following notation for functions: The $f$ before the semicolon is just a label.

In Mathematica, an assignment such as g1 = (#1^2 + #2) & introduces the label $g1$ but more importantly it creates the rule $( \#1, \#2 )\mapsto \#1^2+\#2$.

Paraphrasing your question: how can we create, out of $\#\#\mapsto g1(\#\#)$ and $\#\#\mapsto g2(\#\#)$, a new rule $\#\#\mapsto whateverLabel(\#\#)$ without explicitly giving $whateverLabel(\#\#)$ yet keeping it rather arbitrary.

Some operations on functions, (such as multiplication by a number $α f$), have a natural meaning in terms of the images of the functions; but natural is not the same as nonexistent. And in the end, you need to have the equivalent of the line $x\mapsto α f(x)$.

Therefore, your quest is impossible. You could, for example, limit your quest and keep the operations limited to a small subset (sums of functions, multiplication by a number, multiplication of functions). In that case, we might be able to help.

PS. Think twice before replying that one could define the operations on the images by the operations on the labels.

(Sorry, this is too long to fit into a comment) A possible workaround is to use fresh unevaluated symbols to represent your expression of free functions

expr = 3 f1 + 2Exp[-f2]

g1 = (#1^2 + #2) &;
g2 = Cos[#1 #2] &;

This will produce a list with the functions of said variables.

funlist = {g1, g2}; arglist = {x, y};
dummylist = {f1, f2};
funrule = #@(Sequence @@ arglist) & /@ funlist

{x^2+y, Cos[x y]}

Then you can use a replacement rule, as suggested in one of the comments: