when is f@g not the same as f[g]?
Operator Precedence Table
Unless one wishes to write in FullForm
a competent Mathematica user must be familiar with at least the majority of syntax precedence rules, which are described in the Operator Precedence table.
Clarification: I do not mean that one must memorize (most of) this entire table be competent, but rather that one should know it well enough not to be surprised most of the time. Since memorizing the complete table is impractical (for me at least) I recommend having analysis tools at the ready when writing or reading code.
Here is an excerpt from that table:
It can be seen that expr1 @@@ expr2
is well below expr1 @ expr2
on the table which means that @
has greater binding power than @@@
. In other words:
f @ g @@@ h
is interpreted as(f @ g) @@@ h
notf @ (g @@@ h)
You can see that there are a number of forms between expr1[expr2]
and expr1 @ expr2
-- these are the cases where the two will behave differently in a potentially unanticipated way. For example:
Part
:f @ g [[1]]
is interpreted asf[ g[[1]] ]
notf[g][[1]]
Increment
:f @ g ++
is interpreted asf[g++]
notf[g]++
PreIncrement
:f @ ++ g
is valid input:f[++g]
Of course the relatively high binding power of @
(see the rest of the table) means that many such things as f @ g + h
are interpreted f[g] + h
rather than f[g + h]
. Most operators and input forms have lower binding power than @
so this behavior should be evident with minimal experimentation.
In addition to these the excerpt includes a couple of other interesting forms. The first is PatternTest
which is unusual for having greater binding power than application brackets, therefore:
f?g[h]
is interpreted as(f?g)[h]
notf?(g[h])
The second is infix notation a ~f~ b
(which many people know I am found of). This has lower binding power than @
, and it is left-associative which means:
p @ q ~f~ i @ j ~g~ x @ y
is interpreted asg[f[p[q], i[j]], x[y]]
Precedence
function
There is an undocumented function Precedence
that when applied a Symbol gives the precedence of the corresponding operator, if one exists. Here is my effort to match its output to the order declared in the table above:
{#, Precedence@#} & /@
{PatternTest, default, Part, Increment, Decrement, PreIncrement,
PreDecrement, Prefix, InvisibleApplication, Infix, Map, MapAll, Apply} // TableForm
$\begin{array}{ll} \text{PatternTest} & 680. \\ \text{default} & 670. \\ \text{Part} & 670. \\ \text{Increment} & 660. \\ \text{Decrement} & 660. \\ \text{PreIncrement} & 660. \\ \text{PreDecrement} & 660. \\ \text{Prefix} & 640. \\ \text{InvisibleApplication} & 640. \\ \text{Infix} & 630. \\ \text{Map} & 620. \\ \text{MapAll} & 620. \\ \text{Apply} & 620. \end{array}$
I don't know if there is a Symbol that corresponds to expr1[expr2]
but since the default precedence value (illustrated arbitrarily by default
) matches its location in the table I don't think it matters.
If you are looking for complete answer, take a look at Mr. Wizard's :)
Also, see the comments of @JacobAkkerboom below, who proved I was too hasty. :)
I was right that the function OP is asking about at the end is Precedence
but I was wrong in my interpretation of what is happening.
I will leave this for future visitors as it is not so obvious.
Also, everyone that upvoted, feel free to un-upvote if you wish :)
right part:
Precedence of functions is given by Precedence
:)
More here: What are some useful, undocumented Mathematica functions?
"Good old fashioned" []
is safer but I really like @
, I just have to remeber what is going to happen basing on my experiece, because no one will remember all precedences :)
In fact, sometimes I like to do f @ ( some code )
. The more different brackets, the more transparent code is, IMO.
wrong part
Precedence[Apply]
Precedence[Compose]
620 670
So that's why Tr[Times]
is done before Times
is applied to the list.
What is also an answer to your question about precedences of functions. It is Precedence
, an undocumented function.
There is a discussion about what @
is. In my opinion f @ g
does not mean that there's operation Prefix
with f
on g
. Prefix
is only a syntax form(?). What is happening is:
Compose[f, g]
That's why I've checked Precedence
of Compose
.
More about Compose
: Why there is no name... (this link is true itself :P)
As you see the wrong part is longer...