Piping and Replacement
I do not have a rule, other than to suggest using ()
for grouping, like this
((x^2 + y + Log[z])^2 /. {y -> x/2} // Expand) /. {z -> E^x}
(* x^2/4 + x^3 + x^4 + x Log[E^x] + 2 x^2 Log[E^x] + Log[E^x]^2 *)
A ()
pair is not always needed, like here
(x^2 + y + Log[z])^2 /. {y -> x/2} /. z -> E^x
But if you not sure, just do it all the time. It won't hurt
( (x^2 + y + Log[z])^2 /. {y -> x/2} ) /. z -> E^x
The above gives the same answer, but it has ()
to make sure the grouping is as intended.
As a rule I would avoid following // function
with anything but another // function2
due to the precedence of //
. The very property that makes //
convenient to follow code with (grouping the left-hand side) makes it difficult to follow it with anything else, because binding looks like this:
If your style demands it I suggest you configure your code such that your string of operations is done inside functions, e.g.:
a + b + c // f1 // (# /. c -> 2 &)
Or form a compound function:
a + b + c // (f1[##] /. c -> 2 &)
This adds semantic complexity, and it would be cleaner of course to just write:
f1[a + b + c] /. c -> 2
It might also suit your style to use different operators, though at the moment I cannot see how that would directly solve your style issue. As an example see:
Prefix operator with low precedence
It occurs to me that if you have if the operators that you wish to string after //
match a certain pattern this might be accomplished with something like this:
SetAttributes[Colon, HoldAll]
Colon[lhs_, h_[f : _Symbol | _Function, rest__]] := f[lhs] ~h~ rest
Now:
a + b + c \[Colon] f1 /. c -> 2
a + b + c \[Colon] f1 + q + r + s
which displays as:
yields:
f1[2 + a + b]
q + r + s + f1[a + b + c]
This however fails and would require a more complicated definition:
a + b + c \[Colon] f1 + q + r + s /. c -> 2
Combining the infix forms of Mathematica's functions with the prefix or postfix forms of other functions can get tricky. One must pay careful attention of the rules of precedence for each operator form. Here are two tips on what to do when a complex combination of operators does work as expected.
Retreat. Enter the expression or part of the expression in normal form. In your case, I would would retreat to
Expand[(x^2 + y + Log[z])^2 /. y -> x/2] /. z -> E^x
Now there is little doubt about what the order of evaluation will be.
Wrap the expression with
Hold
andInputForm
and evaluate that, which will show you how Mathematica brackets the expression. Applying this to your expression:InputForm[Hold[(x^2 + y + Log[z])^2 /. y -> x/2 // Expand /. z -> E^x]]
Hold[(Expand /. z -> E^x)[(x^2 + y + Log[z])^2 /. y -> x/2]]
Now you can clearly see what is going wrong with your expression.