Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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}}]

Mathematica graphics

Tr @ Times @@@ {{2, 3}, {4, 5}}

Mathematica graphics

Tr @ ( Times @@@ {{2, 3}, {4, 5}} )

Mathematica graphics

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?

share|improve this question
1  
you might want to look at @m_goldbergs answer here: mathematica.stackexchange.com/questions/19219/… –  Pinguin Dirk Aug 14 '13 at 6:50
    
there are some hints in the following tutorials in the Mathematica Documentation Center: tutorial/OperatorInputForms; tutorial/SpecialWaysToInputExpressions; tutorial/DefiningOutputFormats –  bobknight Aug 14 '13 at 6:55
1  
One issue is that Precedence cannot be easily found in the documentation. –  Yves Klett Aug 14 '13 at 7:24
1  
Related: How to introduce Prefix operator with low precedence to avoid unwanted binding toward the left. –  István Zachar Sep 9 '13 at 8:36

2 Answers 2

up vote 31 down vote accepted

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:

enter image description here

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 not f @ (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 as f[ g[[1]] ] not f[g][[1]]
  • Increment: f @ g ++ is interpreted as f[g++] not f[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] not f?(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 as g[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.

share|improve this answer
    
That table is a complete answer but do you think my interpretation is correct? –  Kuba Aug 14 '13 at 7:45
    
@Kuba Since Precedence is undocumented I am uncertain of your application and its authority; I prefer to reference the table instead. –  Mr.Wizard Aug 14 '13 at 7:47
2  
@LeoFang It would be better familiarize yourself with the syntax table so that each case can be handled most efficiently however there is nothing wrong with using extra parentheses. I personally find that limiting the use of parentheses enhances readability of my own code as I know that they are usually there for a purpose. You can also use the application bracket form rather than parentheses e.g. Map[f, # + 2 & @ g] instead of (f) /@ (# + 2 & @ g). –  Mr.Wizard Aug 14 '13 at 7:53
1  
Mr.Wizard I largely agree, but I think still a lot can be learned from Precedence. Just to realize that prefix, infix and postfix notations are all governed by comparing their precedence-numbers is great, I think. Especially that the number for a postfix notation can be compared with that of a prefix one. So you can have all notations in a row in your mind and induce "relative precedences" by transitivity. The Precedence function can then help to get good examples, like your f@g++, which makes you realize ++ has higher precedence than @. (and therefore higher than // etc) –  Jacob Akkerboom Aug 14 '13 at 8:05
    
@JacobAkkerboom You should take all your comments and put them into an answer :) –  Kuba Aug 14 '13 at 8:14

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...

share|improve this answer
1  
@Nasser That's why we all should go back to main Q&A often :) What are some useful.. –  Kuba Aug 14 '13 at 6:52
1  
I spend more than one hr searching on this before, and also asked on chat. I could not even find help on @ since Mathematica ?@ gives nothing. It is very frustrating why one can't find help on @ when it is one of the most used symbols around. I had no idea it is called Prefix and did not even know there was a precedence function. –  Nasser Aug 14 '13 at 6:58
2  
@Nasser about documentation, it is really great on the beginning. Later, when one is starting asking deeper question it can be really annoying to find the answers one is looking for. :/ –  Kuba Aug 14 '13 at 7:25
2  
Kuba, actually the example by Mr.Wizard shows why it is about Prefix. f@g++ gets parsed to f[g++]. This is because @ has lower precedence than Increment. We can see that indeed Precedence[Increment]==660. So if the precedence of @ was really 670, it would have been parsed as Increment[f[g]]. Note that you can never get Mathematica to show you an expression with @ in it in output. It is really a matter of parsing, Mathematica forgets how the expression was entered. I think no function like Compose is used as it would feel strange to me to use such a function in parsing code. –  Jacob Akkerboom Aug 14 '13 at 7:47
2  
Compare also Hold[f@g ..] and Hold[f@g++]. I think you cannot explain the difference if you think the precedence of @ should be 670 :) –  Jacob Akkerboom Aug 14 '13 at 7:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.