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 *)
Argument Spreading = Apply
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 *)