I have always thought that f@g
will give the same result as f[g]
in all cases, and it is just a matter of style which one to use and that g
will always evaluates first, and then f
will evaluate using the result of g
evaluation. I never thought that there can be any precedence issue here, since no one ever mentioned it in all the times I have been using Mathematica.
So I was really surprised when I found one case where this was not so. So my question is: How does one know when f@g
is not the same as f[g]
?
The help says nothing about this (thanks to chat room for giving me the link to this, I searched and could not find it)
http://reference.wolfram.com/mathematica/ref/Prefix.html
Even though one can see the word precedence
and grouping
but no explanation of where these are talked about and no more links to follow
Prefix[expr, h, precedence, grouping] can be used to specify how the output form should be parenthesized.
clearly this is a precedence issue. But I have never seen this mentioned before any where.
Tr[Times @@@ {{2, 3}, {4, 5}}]
Tr @ Times @@@ {{2, 3}, {4, 5}}
Tr @ ( Times @@@ {{2, 3}, {4, 5}} )
What seems to have happened is that in Tr@Times@@@....
the command Tr
grabbed Times
before Times
was applied. You can replaced Tr
by Total
also and see the same effect.
ps. This is another reason for me to not use @
too much. I I really never liked to use @
and always liked the good old fashioned []
as it seems clearer also, and now safer also.
question is: What is the rule(s) of thumb to use? One should always look ahead and check before using @
to make sure precedence is met? Any other cases than this one might have to watch out for? If there are very few cases, may be one can add them to their cheat sheet. Where are the precedence
of all operators listed so one can check?
Answer
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.
Comments
Post a Comment