The Rule
versus RuleDelayed
issue probably warrants closing this question. That is a basic distinction easily discoverable in the documentation and books and examples etc. However, there are nuances here that it might be worth discussing.
If you do this
g[x3, x2, x1] /. {g[arg___] :> ReverseApplied[g][arg]}
you need to be aware that the g
expressions will be evaluated. To demonstrate, let's give g
a definition:
g[a_, b_, c_] := h[a, b]
Now evaluate
g[x3, x2, x1] /. {g[arg___] :> ReverseApplied[g][arg]}
(* h[x3, x2] *)
Presumably, what we wanted to get was h[x1, x2]
. So, to answer your question of "what is the correct way of doing this?", you should do what you already knew how to do: use ReverseApplied
, but do it directly.
ReverseApplied[g][x3, x2, x1]
(* h[x1, x2] *)
There is no need to go through the whole replacement exercise, just apply ReverseApplied
directly.
Now, if the expression g[x3, x2, x1]
does not evaluate to something other than itself, then the suggested replacements based on RuleDelayed
will work, but the simpler way to do it would be to simply apply Reverse
:
(* I'll use gg to distinguish from the previous case *)
Reverse@gg[x3, x2, x1]
(* gg[x1, x2, x3] *)
A situation where this might make sense is if the arguments have distinct types that define a correct order. For example, let's define gg
like this:
gg[a_Integer, b_String] := StringRepeat[b, a]
In the expected case we have
gg[3, "abc"]
(* "abcabcabc" *)
But maybe we somehow have gg["abc", 3]
that we want to evaluate in the "obvious" way. Then we can just do
Reverse[gg["abc", 3]]
(* "abcabcabc" *)
Or, of course, we can still use the more general
ReverseApplied[gg]["abc", 3]
(* "abcabcabc" *)
which avoids having to consider whether the gg["abc", 3]
expression will evaluate or not.