What is the difference between
f@*g@*h@x
and
f@g@h@x
Both evaluate to
f[g[h[x]]]
If they're the same, why introduce Composition as a new feature?
What is the difference between
f@*g@*h@x
and
f@g@h@x
Both evaluate to
f[g[h[x]]]
If they're the same, why introduce Composition as a new feature?
Clearly the @ notation is inspired by the usual mathematical notation for function composition. f@g[x] looks very similar to the mathematical notation $(f\circ g)(x)$. But it is important to understand that @ does not denote function composition. In mathematical notation $f\circ g$ is also a function. In Mathematica f@x is simply a different way to write f[x], but f@g is not (generally) a function. Both f@x and f[x] parse to the exact same Mathematica expression.
So what is the true equivalent of $f \circ g$? It is Composition[f, g] which can be more concisely written as f @* g since version 10, and can be used in situations where we need a function without applying it to an argument (e.g. with Map, or as an operator with Dataset).
Both of your examples evaluate to the very same things in the end, so they behave equivalently in this case. But the way Mathematica arrives to the same end result is different:
f@g@h@x parses to an expression with the FullForm f[g[h[x]]], which doesn't evaluate further. There's no evaluation step.
f@*g@*h@x parses to an expression with the full form Composition[f,g,h][x], which then evaluates to f[g[h[x]]].
It's also worth pointing out that @ and @* have different precedences and associativity properties as operators. f@g@x is equivalent to f@(g@x) and f@*g@x is equivalent to (f@*g)@x. Writing ...[...] has a different precedence again so f@*g[x] is the same as f@*(g[x]) (i.e. it's not the same as f@*g@x).
Composition[f,g], that is the most useful as you can easily pass around the composed function without having to craft it by hand.
– rcollyer
Apr 03 '15 at 15:25
f @ g is the same as f[g], while f @* g is roughly equivalent to f[g[#]] &. For example of usage, StringLength @* ToString /@ Range[10] works whereas StringLength @ ToString /@ Range[10] does not.
– 2012rcampion
Apr 03 '15 at 15:25
f @* g is not the same as f[g[#]]&. It is equivalent to Composition[f,g]. In the sense that either f @* g or Composition[f,g] are interpreted as the very same expression during parsing. It happens to be that f[g[#]] & works the same way as Composition[f,g], but they are very different expressions. (And of course, f[g[#]] & doesn't work exactly the same way, there are several subtle details that show in special edge cases. Plus Composition used to unpack packed arrays pre-version-10...)
– Szabolcs
Apr 03 '15 at 15:28
Composition it gets the point of what it does across.
– 2012rcampion
Apr 03 '15 at 15:30
f@*g@x and f@g@x simply parse to different expressions, which then are evaluated to the same? Try wrapping both in FullForm@Hold[...] to prevent evaluation and see them written using the same notation.
– Szabolcs
Apr 03 '15 at 15:47
@* is more useful e.g. here: Map[f@*g, ..., {2}] or in any situation where you need a function but do not need to apply it to anything. There's also the fact that (f@*g)[x] requires parentheses unlike f@g[x] or f@*g@x, so in the situation you describe f@*g seems more cumbersome and error prone when modifying code ...
– Szabolcs
Apr 03 '15 at 17:11
@* creates a function (which is not what @ does)?
– orome
Apr 03 '15 at 17:14
@ does to your answer (maybe with an example)? It would make a great answer even better. Thx.
– orome
Apr 03 '15 at 17:18
...[...] and ...@... have different precedence?
– orome
Apr 03 '15 at 22:48
@* was chosen over ∘ and why \[SmallCircle] is not even available as an undefined operator?
– Alan
May 02 '18 at 20:46
... why introduce Composition as a new feature?
Composition is used to create a new anonymous function that can be used in all the standard ways such as Map and Apply etc. To achieve the same thing without it one needs a Function. Much like operator forms the use of Composition allows one to eliminate extraneous Function constructs which can make code more linear and easier to read. The short form @* and its companion /* (see RightComposition) make its application pleasingly concise.
Composition is not typically used for a single application but instead when one wishes to perform an operation multiple times. Here are some related form:
f@*g@*h /@ {x, y, z}
f@g@h@# & /@ {x, y, z}
f /@ g /@ h /@ {x, y, z}
Each of these evaluate the same way in this particular case but there are differences that are not immediately apparent. We can see some of them if we define:
f = HoldForm; g = Print; h = Sqrt;
Now:
f@*g@*h /@ {x, y, z}
f@g@h@# & /@ {x, y, z}
f /@ g /@ h /@ {x, y, z}

Because Composition does not hold its arguments the Symbols g and h are resolved to Print and Sqrt in the output from the first line. In the second line f resolves first to HoldForm and as a result g and h remain verbatim. Finally in the last line each function application is evaluated sequentially therefore the Print fires and Null is returned as the actual output.
See also:
h = f @ g; h[x]andh = f @* g; h[x]. – David Zhang Apr 04 '15 at 15:42