# Composing function returning list and function taking multiple arguments

What is the easiest way to compose a function that returns a list of $n$ elements with a function that takes $n$ arguments. If I know this $n$ a priori, I can do something like

{x1,...,xn} = f1[...];
f2[x1,...,xn]


where for $n=2$ this would be {x1,x2} = ... etc. Is there a way of accomplishing such a composition without having to introduce named variables? What about the case, where I don't know the $n$?

In other words, I'd like to somehow curry/uncurry functions on the fly.

Apply[f2, f1[...]]


Or, in the Mathematica shorthand:

f2 @@ f1[...]

• That was simple.
– eof
Commented Sep 21, 2014 at 16:50

More of a comment than an answer, because I suspect this trivial solution to your minimal working example does not get at the real question. In any case, what is wrong with lists?

f1[list_] := list^2
f1 /@ {{a, b}, {c, d, e}}

(*{{a^2, b^2}, {c^2, d^2, e^2}}*)

f2[list_] := Plot[#[x], {x, 0, 2}] & /@ list
f2 /@ {{Sin, Cos, Log}, {# &, #^2 &}}


There are two distinct operations under discussion here: "argument spreading" and function composition.

We will define concrete examples of f1 and f2 for purposes of discussion:

f1[n_] := n ^ {0, 1, 2}

f2[x_, y_, z_] := x + y - z


So:

f1[3]
(* {1, 3, 9} *)

f2[1, 3, 9]
(* -5 *)


f1 returns a List of values, but the arguments to f2 are a simple Sequence. The required spreading of arguments is called "application" and is facilitated by Apply which has a short form @@:

f2 @@ f1[3]
(* -5 *)


Sometimes it is useful to curry a combination of explicit arguments and listed arguments. An application of Sequence can be used for this purpose:

f2[1, Sequence @@ {3, 9}]
(* -5 *)


Function Composition

The preceding examples all involved actual function invocations. Sometimes it is useful to take a more functional approach and combine functions prior to actually calling them.

For example, we could define f3 that represents the desired combination of f1 and f2 using pure function notation like this:

f3 = f2 @@ f1[##] &

f3[3]
(* -5 *)


Version 10 introduced some nice new operator short forms. It permits a definition like this:

f4 = Apply[f2] @* f1

f4[3]
(* -5 *)


f4 is defined in so-called "point-free" style, where there is no mention of the arguments.

@* is the left composition operator. There is also a right composition operator, /*:

f5 = f1 /* Apply[f2]

f5[3]
(* -5 *)