0

Why would this work

Times[a, b, c, d] /. Times :> List
(* {a, b, c, d} *)

but this doesn't work (the Times still remains even when the List has been added)?

Times[a, b, c, d] /. Times[p__] :> List[p]
(* {a b c d} *)

Applying Trace shows that Times might have applied itself to p__ before the pattern is matched, so that the expression now became just a b c d/. p__:>{p}. If that's the case, why would Times[p__] become p__?

Times[a, b, c, d] /. Times[p__] :> List[p] // Trace
(* {{{Times[p__],p__},p__:>{p},p__:>{p}},a b c d/. p__:>{p},{a b c d}} *)
seismatica
  • 5,101
  • 1
  • 22
  • 33
  • 1
    Times[p__] directly evaluates to p__. You need HoldPattern, Verbatim, or a dummy pattern: (x:Times)[p__]. This question is a duplicate. I am looking now. – Mr.Wizard Jul 21 '14 at 06:03
  • 1
  • 1
    For clarity, all of these work: Times[a, b, c, d] /. HoldPattern[Times[p__]] :> List[p] -- Times[a, b, c, d] /. HoldPattern[Times][p__] :> List[p] -- Times[a, b, c, d] /. Verbatim[Times][p__] :> List[p] -- Times[a, b, c, d] /. (x : Times)[p__] :> List[p] – Mr.Wizard Jul 21 '14 at 06:12
  • Bravo @Mr.Wizard! I learned something new today (HoldPattern) from you. – seismatica Jul 21 '14 at 06:13
  • Glad I could help. :-) By the way, while it doesn't answer this question you could also use: Times[a, b, c, d] /. p_Times :> List @@ p. However, be aware that this relies on evaluation of the righ-hand-side, meaning that it won't work inside a Hold: Hold[Times[a, b, c, d]] /. p_Times :> List @@ p outputs Hold[List @@ (a b c d)] – Mr.Wizard Jul 21 '14 at 06:18

0 Answers0