# 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}}. Aug 28, 2017 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 Aug 28, 2017 at 21:59
• @user, I used composition @* instead of application @; the former shortcut only became available in recent versions. What version are you using? Aug 28, 2017 at 22:18
• Related: (11298) Aug 29, 2017 at 10:26
• Could use Through@*{Apply[f], Apply[g]} /@ {{1, 2}, {3, 4}} to get rid of the inner lists. Aug 29, 2017 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, 2017 at 22:18
• @Max This does not produce the form you requested, {{f, f}, {g, g}} rather than {{f, g}, {f, g}}. Aug 29, 2017 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, 2017 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, 2017 at 17:41
• @Max, right, Carl is using level-1 Apply[] (@@@) in his instead of Map[] (/@) in mine, which did expect lists as arguments. Aug 29, 2017 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... :) Aug 29, 2017 at 23:44
func[x_List] :=  Module[{},
Map[Through[{f, g}[#] ] &, x]
]


Using Comap: (since v14.0, 2023)

Comap[{f,g},#]&/@{{1, 2}, {3, 4}}


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

Using ComapApply: (since v14.0, 2023)

ComapApply[{f,g},#]&/@{{1, 2}, {3, 4}}


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

• Comap and ComapApply have operator forms: Comap[{f, g}] /@ ... Mar 29 at 20:26

Using Query

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


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

Using Tuples and SplitBy:

Thread@SplitBy[#1 @@ #2 & @@@ Tuples[{{f, g}, {{1, 2}, {3, 4}}}], Head]


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