R.M chose PatternTest
as an example but I find that subtly misleading. PatternTest is highly unusual because it binds tighter than [ ]
, meaning x_?head[arg]
parses as (x_?head)[arg]
, but even without this behavior the parentheses would be needed.
In your own example the parentheses are unnecessary and, being a fan of terse coding, I suggest you leave them out unless the bounds of your function are unclear. There is no ambiguity in Select[ data, # == 1 & ]
and it is easy to see the function's bounds.
In longer sections of code parentheses can be helpful for visual (human) parsing but I usually favor line breaks for that purpose. I feel that these are more visible and their purpose more clear.
As alluded to in the second paragraph there are of course times that the parentheses are needed, as well as times they can improve readability. There are two different placements and both, sometimes together, have a place.
The first form: ( body & )
is useful for limiting the reach of &
, while the second: ( body ) &
is useful to extend it. I feel that reserving them for these purposes makes their meaning more clear.
One sees from the precedence table that &
is fairly far down the list, so a natural reading of &
is to consider its body to be most things to the left side, bounded by Set
-type operators or CompoundExpression: ;
(and of course ,
). (Yes, there are other possible bounds but these are by far the most common in practice.) Reading my own code if I used ( ... &)
it tells me that the bound needed to be limited, e.g.:
5 + (Sqrt[#] &) /@ {1, 2, 3}
Union[list, SameTest -> (Mod[#1, 3] == Mod[#2, 3] &)]
Conversely if I used ( ... ) &
I know that I wanted to extend the bound, e.g.:
(# = #2) & @@@ {{a, 1}, {b, 2}, {c, 3}}
$PrePrint = (Print@#; #) &
From my perspective sprinkling parentheses needlessly only obfuscates the function of the code and I wish to avoid that, but there is some subjectivity even within these guidelines and I don't mean to imply that parentheses should be used only when syntactically necessary.
Consider:
NestWhile[# + 1 &, 888, ! PrimeQ[#1] || ! PrimeQ[#3] &, 3]
In my opinion putting ( )
anywhere in the first argument is pointless as this is already as clear as it possibly can be. The second &
is a more interesting case. I would not use the ( body &)
form because as I see it ..., ( stuff ), ...
is redundant: commas already serve to group expressions so the ( )
tell me nothing.
I might use ( body ) &
if I or someone likely to read the code may not always remember the precedence of ||
versus &
:
NestWhile[# + 1 &, 888, (! PrimeQ[#1] || ! PrimeQ[#3]) &, 3]
Here the ( )
do at least tell me something that is not already apparent from the commas: the function body extends through the bounded expression.