Skip to main content

programming - when is f@g not the same as f[g]?



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?



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:


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.


Comments

Popular posts from this blog

mathematical optimization - Minimizing using indices, error: Part::pkspec1: The expression cannot be used as a part specification

I want to use Minimize where the variables to minimize are indices pointing into an array. Here a MWE that hopefully shows what my problem is. vars = u@# & /@ Range[3]; cons = Flatten@ { Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; Minimize[{Total@((vec1[[#]] - vec2[[u[#]]])^2 & /@ Range[1, 3]), cons}, vars, Integers] The error I get: Part::pkspec1: The expression u[1] cannot be used as a part specification. >> Answer Ok, it seems that one can get around Mathematica trying to evaluate vec2[[u[1]]] too early by using the function Indexed[vec2,u[1]] . The working MWE would then look like the following: vars = u@# & /@ Range[3]; cons = Flatten@{ Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; NMinimize[ {Total@((vec1[[#]] - Indexed[vec2, u[#]])^2 & /@ R...

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

What is and isn't a valid variable specification for Manipulate?

I have an expression whose terms have arguments (representing subscripts), like this: myExpr = A[0] + V[1,T] I would like to put it inside a Manipulate to see its value as I move around the parameters. (The goal is eventually to plot it wrt one of the variables inside.) However, Mathematica complains when I set V[1,T] as a manipulated variable: Manipulate[Evaluate[myExpr], {A[0], 0, 1}, {V[1, T], 0, 1}] (*Manipulate::vsform: Manipulate argument {V[1,T],0,1} does not have the correct form for a variable specification. >> *) As a workaround, if I get rid of the symbol T inside the argument, it works fine: Manipulate[ Evaluate[myExpr /. T -> 15], {A[0], 0, 1}, {V[1, 15], 0, 1}] Why this behavior? Can anyone point me to the documentation that says what counts as a valid variable? And is there a way to get Manpiulate to accept an expression with a symbolic argument as a variable? Investigations I've done so far: I tried using variableQ from this answer , but it says V[1...