Skip to main content
3 of 3
added 340 characters in body
lericr
  • 34.1k
  • 2
  • 22
  • 78

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.

lericr
  • 34.1k
  • 2
  • 22
  • 78