# Patterns are not Sequences are not Lists, or: Global Function Argument Reversal

H[z_] := z /. {F[p__] -> F[Reverse[p]]}

F[{x, y}] + F[{x, z}] + F[{}] // H


Almost. It gives an annoying "Nonatomic Reverse" error message at the first call of H - why only the first?!? - and moreover, I'd like to have this without the lists, i.e. an occurence of, say, F[X,Y] is replaced by F[Y,X]. To my dismay, the following does not work!

G[z_] := z /. {F[p__] -> ReverseApplied[F][p]}
F[x, y] + F[x, z] + F[] // G


Neither does any other argument reversal of F (e.g. recursive) "bite" in the pattern matching. What is going on? I mean, any p__ found inside a F first gets replace by a Sequence[p] but then everything goes haywire. It seems to be an operation order problem, Sequence is executed too late?!

EDIT: I tried out the tip, but it still doesn't seem to reverse. The following does work:

G[z_] := z /. {F[p___] -> Hold[ReverseApplied[F][p]]]} // ReleaseHold;


It is an order problem! Can someone explain?

• Try Reverse[F[p]] Commented Nov 26, 2021 at 14:13
• If F has down values that might not have the desired effect though. Commented Nov 26, 2021 at 14:58
• Maybe F @@ Reverse[{p}] will do what is wanted here? Commented Nov 26, 2021 at 15:00

You need to replace Rule (->) with RuleDelayed (:>):

ClearAll[H, G, p, x, z]
H[z_] := z /. {F[p_] :> (F @ Reverse[p])}

F[{x, y}] + F[{x, z}] + F[{}] // H

F[{}] + F[{y, x}] + F[{z, x}]

G1[z_] := z /. {F[p__] :> ReverseApplied[F][p]}
F[x, y] + F[x, z] + F[] // G1

F[] + F[y, x] + F[z, x]

G2[z_] := z /. {F[p__] :> (F @@ Reverse[{p}])}

F[x, y] + F[x, z] + F[] // G2

F[] + F[y, x] + F[z, x]


or, as suggested by Michael E2 in comments:

G3[z_] := z /. {F[p__] :> Reverse[F @ p]}
F[x, y] + F[x, z] + F[] // G3

F[] + F[y, x] + F[z, x]

• I accepted because it works, but can you also explain why my first try works after I inserted the Hold (i.e. -> instead of :> does not work, which is the same effect als Hold...if I only knew why :-) (Also, why does Reverse work on Sequence?) Commented Nov 26, 2021 at 14:29
• @HaukeReddmann, see tutorial/ImmediateAndDelayedDefinitions. I think your Hold/ReleaseHold combination is effectively doing what RuleDelayed does.
– kglr
Commented Nov 26, 2021 at 14:35
• I think I understand: Rule applies the first "bite", then evaluates, then scans for the next "bite" etc., which causes havoc due to the Sequences applying to the wrong functions. Ha, learned something again :-) Commented Nov 26, 2021 at 14:43