# Using Through on functions that take multiple arguments

I want simple syntax that results in this:

{{f[1, 2], g[1, 2]}, {f[3, 4], g[3, 4]}}


though I'm willing to settle for:

{{f[{1, 2}], g[{1, 2}]}, {f[{3, 4}], g[{3, 4}]}}


if that's easier somehow. (And for completeness, and Re: the answer I accepted, I'm also fine with the form

{{f[1, 2], f[3, 4]}, {g[1, 2], g[3, 4]}}


which differs from the original form by a simple Transpose anyway.)

I would expect the function Through to help here, but it doesn't seem able to work with functions that take multiple arguments. My naive attempt looks like this:

Through@{f, g}[{{1, 2}, {3, 4}}]

{f[{{1, 2}, {3, 4}}], g[{{1, 2}, {3, 4}}]} (*out*)


which is clearly not what I want (as it does no threading over the arguments). If a function is defined to take one argument, then Through makes the most of that:

f[x_] := x^2
g[x_] := x^3
Through@{f, g}[{{1, 2}, {3, 4}}]

{{{1, 4}, {9, 16}}, {{1, 8}, {27, 64}}} (*out*)


(f and g now get applied to the lowest level, where there's only 1 argument.) So what I want is a way to get Through to 'make the most' of functions that take multiple arguments. Instead it gives me:

Clear[f, g]
f[x_, y_] := x^2 + y
g[x_, y_] := x^3 + y
Through@{f, g}[{{1, 2}, {3, 4}}]

{f[{{1, 2}, {3, 4}}], g[{{1, 2}, {3, 4}}]} (*out*)

• Try Through @* {f, g} /@ {{1, 2}, {3, 4}}. – J. M. will be back soon Aug 28 '17 at 21:47
• I think that when you apply the functions f and g with only one argument each (the monomial case) you get the desired result not because Through works like you'd expect but because Mathematica can raise lists to (integer) powers – user42582 Aug 28 '17 at 21:59
• @user, I used composition @* instead of application @; the former shortcut only became available in recent versions. What version are you using? – J. M. will be back soon Aug 28 '17 at 22:18
• Related: (11298) – Mr.Wizard Aug 29 '17 at 10:26
• Could use Through@*{Apply[f], Apply[g]} /@ {{1, 2}, {3, 4}} to get rid of the inner lists. – Carl Woll Aug 29 '17 at 17:33

list = {{1, 2}, {3, 4}};

Apply[#, list, {1}] & /@ {f, g}


{{3, 13}, {3, 31}}

Or with the operator form of Map:

Map[Apply[#, list, {1}] &] @ {f, g}


Or in terse notation:

# @@@ list & /@ {f, g}

• Though several people gave good answers, I like yours best for both simplicity and that it gives the (slightly) preferred output that I mentioned at the beginning of my post. – Max Aug 28 '17 at 22:18
• @Max This does not produce the form you requested, {{f, f}, {g, g}} rather than {{f, g}, {f, g}}. – Mr.Wizard Aug 29 '17 at 10:28
• @Mr.Wizard You're right. But it so happens that difference isn't important to me (and besides it's a simple Transpose away) -- I'll edit my question to reflect that. And for future readers, I imagine this answer could still be the most convenient because it works with the standard function form f[x,y], rather than needing a re-definition f[{x_,y_}]:=f[x,y] as the other answers do. – Max Aug 29 '17 at 16:57
• Though @Carl Woll gave a modification to J.M.'s comment that makes it usable with the standard f[x,y] form as well. – Max Aug 29 '17 at 17:41
• @Max, right, Carl is using level-1 Apply[] (@@@) in his instead of Map[] (/@) in mine, which did expect lists as arguments. – J. M. will be back soon Aug 29 '17 at 23:46

I like using Slot free notation, so the following appeals to me:

Through @* {f, g} @@@ {{1, 2}, {3, 4}}


{{f[1, 2], g[1, 2]}, {f[3, 4], g[3, 4]}}

And for the OP using version 9:

Through /@ {f, g} @@@ {{1, 2}, {3, 4}}


{{f[1, 2], g[1, 2]}, {f[3, 4], g[3, 4]}}

Also, the short hand @* was introduced in M10, but you can still use the long hand in earlier versions:

Composition[Through, {f, g}] @@@ {{1, 2}, {3, 4}}


{{f[1, 2], g[1, 2]}, {f[3, 4], g[3, 4]}}

• There's just something nice about keeping things slot-free... :) – J. M. will be back soon Aug 29 '17 at 23:44
func[x_List] :=  Module[{},
Map[Through[{f, g}[#] ] &, x]
]