I was playing around with the Prefix and Postfix operators (@ and // respectively) and I ran into the following issue.
Given the following code, they evaluate in the same exact way:
Hold[MatrixPlot@Sort@data] // FullForm
(* Hold[MatrixPlot[Sort[data]]] *)
Hold[data // Sort // MatrixPlot] // FullForm
(* Hold[MatrixPlot[Sort[data]]] *)
However, given the following expressions, I get different results:
FunctionExpand@Abs'[0]
(* Abs'[0] *)
Abs'[0] // FunctionExpand
(* 0 *)
I’m not quite sure really why this is. In dozens of other snippets of code I’ve had, f@expr, expr // f, and f[expr] all evaluate to the same result. Why does this one particular case give this result?
This is a precedence issue. @ has higher precedence than //. To see what is going on, place the cursor on
FunctionExpandin both cases, then either cmd+. (on OS X) or ctrl+. on anything else, and you end up selecting things by precedence.Another way to see it is to use
Trace:while
In particular, notice how in the first case mma first evaluates
FunctionExpand[Abs], obtainingAbs, then continuing. This is precisely due to how strongly@binds as compared to//.EDIT: Inspired by @Leonid’s comment, this is also informative:
which is a much better demonstration of what is going on.