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 FunctionExpand
in 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
:
FunctionExpand@Abs'[0] // Trace
(*
-> {{{FunctionExpand[Abs],Abs},Abs^\[Prime]},(Abs^\[Prime])[0]}
*)
while
Abs'[0] // FunctionExpand//Trace
(*
-> {FunctionExpand[(Abs^\[Prime])[0]],0}
*)
In particular, notice how in the first case mma first evaluates FunctionExpand[Abs]
, obtaining Abs
, then continuing. This is precisely due to how strongly @
binds as compared to //
.
EDIT: Inspired by @Leonid's comment, this is also informative:
Hold[FunctionExpand@Abs'[0]] // FullForm
Hold[Abs'[0] // FunctionExpand] // FullForm
(*
-> Hold[Derivative[1][FunctionExpand[Abs]][0]]
Hold[FunctionExpand[Derivative[1][Abs][0]]]
*)
which is a much better demonstration of what is going on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With