Is there a difference between Replace with parameter “All” and ReplaceAll












13














Here is my extremly basic understanding of Replace and ReplaceAll.



This post is also a way for me to check if I understood the mechanism behind, if you see mistakes in my explanation don't hesitate to correct me !



Replace is a function that will apply replacement rules on part of expression.



However, it will apply the replacement rules at specific level given in parameters (by default it will be {0} corresponding to the whole tree).



So here :



Replace[x^2 + 1, x^2 -> a]


It doesn't do anything as x^2 is a subpart of the tree but it is not the whole tree in itself.



I could do :



Replace[x^2 + 1, x^2 -> a, All]


To make it work. Then the code will look at all the levels of the trees (thus all the subtrees) and look for a matching replacement.



I could also do :



ReplaceAll[x^2 + 1, x^2 -> a]


And here is my question : is there actually any difference between using



Replace[expr, rule, All]


and



ReplaceAll[expr,rule]


or it is indeed the same thing ?





Another question linked to the answer



Then I don't understand this behavior :



diffReplaceReplaceAll = g[g[x]];

Replace[diffReplaceReplaceAll, g -> c, All]

g[g[x]]

g[g[x]][[1]]

g[x]

ReplaceAll[diffReplaceReplaceAll, g -> c]

c[c[x]]


If I take strictly what you say, ReplaceAll shoud return c[g[x]]



Indeed, it goes from the outside which is g[g[x]] (the whole tree), it looks at each part. So first it tries with the Head (the 0 part), which is $g$, it replaces it by $c$. And... it should stop here right ? Thus we would have c[g[x]] as a result. But it continues and replaces the second g. Why ?



My problem is very probably linked to a not fully understanding of what a part precisely is. But if I'm not wrong the 0'th part is the head and the 1st part is g[x] here right ?



I also have a problem with Replace : why if it goes from the inside to the outside I don't have at least g[c[x]] ?



Remark : I don't fully get your example as I'm not familiar with ":>", I am reading about it now.





I'm sorry but I still have problem to understand, here is the code I consider :



    expr = g[g[x]];
ReplaceAll[expr, g -> fonction]
ReplaceAll[expr, g[x_] -> fonction[x]]

fonction[fonction[x]]

fonction[g[x]]


I will write what I understand step by step of what is happening : the first ReplaceAll : ReplaceAll[expr, g -> fonction]




ReplaceAll looks at each part of expr, tries all the rules on it, and then goes on to the next part of expr. The first rule that applies to a particular part is used; no further rules are tried on that part or on any of its subparts.




Allright, I will look at each part of expr.




  • I look at the 0'th part of expr which is the Head : g.
    I have a matching pattern, g becomes fonction. I don't have to look at subparts of g as I had a matching (but even in this case, g doesn't have subparts so it wouldn't change anything).

  • I go at the next part (1st part) of expr : fonction[g[x]][[1]] = g[x]
    it doesn't match.

  • I go at the first subpart of g[x] : g[x][[0]] = g, it matches. I replace. I don't have to look at the subparts of g as it matched. At this point I thus have fonction[fonction[x]]

  • I look at the 2ndt part of expr : fonction[fonction[x]][[2]] : it doesn't exist.


Thus the code stops and the function returns : fonction[fonction[x]]



Now for the second ReplaceAll : ReplaceAll[expr, g[x_] -> fonction[x]]




  • I look at the 0'th part of expr : g[g[x]][[0]] = g : no matching

  • I look at the subparts of g : it doesn't have, so it stops for that.

  • Thus, now I look at the 1st part of expr : g[g[x]][[1]] = g[x]
    It matches : g[x] -> fonction[x]. I thus now have g[fonction[x]]... which I know is wrong.


Here is how I understood the algorithm and I still have a problem. I don't understand what precisely does the algorithm then.



And is the 0'th part really the head or the full expression ? Because in the documentation of Replace for example :




The default value for levelspec in Replace is {0}, corresponding to the whole expression.











share|improve this question





























    13














    Here is my extremly basic understanding of Replace and ReplaceAll.



    This post is also a way for me to check if I understood the mechanism behind, if you see mistakes in my explanation don't hesitate to correct me !



    Replace is a function that will apply replacement rules on part of expression.



    However, it will apply the replacement rules at specific level given in parameters (by default it will be {0} corresponding to the whole tree).



    So here :



    Replace[x^2 + 1, x^2 -> a]


    It doesn't do anything as x^2 is a subpart of the tree but it is not the whole tree in itself.



    I could do :



    Replace[x^2 + 1, x^2 -> a, All]


    To make it work. Then the code will look at all the levels of the trees (thus all the subtrees) and look for a matching replacement.



    I could also do :



    ReplaceAll[x^2 + 1, x^2 -> a]


    And here is my question : is there actually any difference between using



    Replace[expr, rule, All]


    and



    ReplaceAll[expr,rule]


    or it is indeed the same thing ?





    Another question linked to the answer



    Then I don't understand this behavior :



    diffReplaceReplaceAll = g[g[x]];

    Replace[diffReplaceReplaceAll, g -> c, All]

    g[g[x]]

    g[g[x]][[1]]

    g[x]

    ReplaceAll[diffReplaceReplaceAll, g -> c]

    c[c[x]]


    If I take strictly what you say, ReplaceAll shoud return c[g[x]]



    Indeed, it goes from the outside which is g[g[x]] (the whole tree), it looks at each part. So first it tries with the Head (the 0 part), which is $g$, it replaces it by $c$. And... it should stop here right ? Thus we would have c[g[x]] as a result. But it continues and replaces the second g. Why ?



    My problem is very probably linked to a not fully understanding of what a part precisely is. But if I'm not wrong the 0'th part is the head and the 1st part is g[x] here right ?



    I also have a problem with Replace : why if it goes from the inside to the outside I don't have at least g[c[x]] ?



    Remark : I don't fully get your example as I'm not familiar with ":>", I am reading about it now.





    I'm sorry but I still have problem to understand, here is the code I consider :



        expr = g[g[x]];
    ReplaceAll[expr, g -> fonction]
    ReplaceAll[expr, g[x_] -> fonction[x]]

    fonction[fonction[x]]

    fonction[g[x]]


    I will write what I understand step by step of what is happening : the first ReplaceAll : ReplaceAll[expr, g -> fonction]




    ReplaceAll looks at each part of expr, tries all the rules on it, and then goes on to the next part of expr. The first rule that applies to a particular part is used; no further rules are tried on that part or on any of its subparts.




    Allright, I will look at each part of expr.




    • I look at the 0'th part of expr which is the Head : g.
      I have a matching pattern, g becomes fonction. I don't have to look at subparts of g as I had a matching (but even in this case, g doesn't have subparts so it wouldn't change anything).

    • I go at the next part (1st part) of expr : fonction[g[x]][[1]] = g[x]
      it doesn't match.

    • I go at the first subpart of g[x] : g[x][[0]] = g, it matches. I replace. I don't have to look at the subparts of g as it matched. At this point I thus have fonction[fonction[x]]

    • I look at the 2ndt part of expr : fonction[fonction[x]][[2]] : it doesn't exist.


    Thus the code stops and the function returns : fonction[fonction[x]]



    Now for the second ReplaceAll : ReplaceAll[expr, g[x_] -> fonction[x]]




    • I look at the 0'th part of expr : g[g[x]][[0]] = g : no matching

    • I look at the subparts of g : it doesn't have, so it stops for that.

    • Thus, now I look at the 1st part of expr : g[g[x]][[1]] = g[x]
      It matches : g[x] -> fonction[x]. I thus now have g[fonction[x]]... which I know is wrong.


    Here is how I understood the algorithm and I still have a problem. I don't understand what precisely does the algorithm then.



    And is the 0'th part really the head or the full expression ? Because in the documentation of Replace for example :




    The default value for levelspec in Replace is {0}, corresponding to the whole expression.











    share|improve this question



























      13












      13








      13


      1





      Here is my extremly basic understanding of Replace and ReplaceAll.



      This post is also a way for me to check if I understood the mechanism behind, if you see mistakes in my explanation don't hesitate to correct me !



      Replace is a function that will apply replacement rules on part of expression.



      However, it will apply the replacement rules at specific level given in parameters (by default it will be {0} corresponding to the whole tree).



      So here :



      Replace[x^2 + 1, x^2 -> a]


      It doesn't do anything as x^2 is a subpart of the tree but it is not the whole tree in itself.



      I could do :



      Replace[x^2 + 1, x^2 -> a, All]


      To make it work. Then the code will look at all the levels of the trees (thus all the subtrees) and look for a matching replacement.



      I could also do :



      ReplaceAll[x^2 + 1, x^2 -> a]


      And here is my question : is there actually any difference between using



      Replace[expr, rule, All]


      and



      ReplaceAll[expr,rule]


      or it is indeed the same thing ?





      Another question linked to the answer



      Then I don't understand this behavior :



      diffReplaceReplaceAll = g[g[x]];

      Replace[diffReplaceReplaceAll, g -> c, All]

      g[g[x]]

      g[g[x]][[1]]

      g[x]

      ReplaceAll[diffReplaceReplaceAll, g -> c]

      c[c[x]]


      If I take strictly what you say, ReplaceAll shoud return c[g[x]]



      Indeed, it goes from the outside which is g[g[x]] (the whole tree), it looks at each part. So first it tries with the Head (the 0 part), which is $g$, it replaces it by $c$. And... it should stop here right ? Thus we would have c[g[x]] as a result. But it continues and replaces the second g. Why ?



      My problem is very probably linked to a not fully understanding of what a part precisely is. But if I'm not wrong the 0'th part is the head and the 1st part is g[x] here right ?



      I also have a problem with Replace : why if it goes from the inside to the outside I don't have at least g[c[x]] ?



      Remark : I don't fully get your example as I'm not familiar with ":>", I am reading about it now.





      I'm sorry but I still have problem to understand, here is the code I consider :



          expr = g[g[x]];
      ReplaceAll[expr, g -> fonction]
      ReplaceAll[expr, g[x_] -> fonction[x]]

      fonction[fonction[x]]

      fonction[g[x]]


      I will write what I understand step by step of what is happening : the first ReplaceAll : ReplaceAll[expr, g -> fonction]




      ReplaceAll looks at each part of expr, tries all the rules on it, and then goes on to the next part of expr. The first rule that applies to a particular part is used; no further rules are tried on that part or on any of its subparts.




      Allright, I will look at each part of expr.




      • I look at the 0'th part of expr which is the Head : g.
        I have a matching pattern, g becomes fonction. I don't have to look at subparts of g as I had a matching (but even in this case, g doesn't have subparts so it wouldn't change anything).

      • I go at the next part (1st part) of expr : fonction[g[x]][[1]] = g[x]
        it doesn't match.

      • I go at the first subpart of g[x] : g[x][[0]] = g, it matches. I replace. I don't have to look at the subparts of g as it matched. At this point I thus have fonction[fonction[x]]

      • I look at the 2ndt part of expr : fonction[fonction[x]][[2]] : it doesn't exist.


      Thus the code stops and the function returns : fonction[fonction[x]]



      Now for the second ReplaceAll : ReplaceAll[expr, g[x_] -> fonction[x]]




      • I look at the 0'th part of expr : g[g[x]][[0]] = g : no matching

      • I look at the subparts of g : it doesn't have, so it stops for that.

      • Thus, now I look at the 1st part of expr : g[g[x]][[1]] = g[x]
        It matches : g[x] -> fonction[x]. I thus now have g[fonction[x]]... which I know is wrong.


      Here is how I understood the algorithm and I still have a problem. I don't understand what precisely does the algorithm then.



      And is the 0'th part really the head or the full expression ? Because in the documentation of Replace for example :




      The default value for levelspec in Replace is {0}, corresponding to the whole expression.











      share|improve this question















      Here is my extremly basic understanding of Replace and ReplaceAll.



      This post is also a way for me to check if I understood the mechanism behind, if you see mistakes in my explanation don't hesitate to correct me !



      Replace is a function that will apply replacement rules on part of expression.



      However, it will apply the replacement rules at specific level given in parameters (by default it will be {0} corresponding to the whole tree).



      So here :



      Replace[x^2 + 1, x^2 -> a]


      It doesn't do anything as x^2 is a subpart of the tree but it is not the whole tree in itself.



      I could do :



      Replace[x^2 + 1, x^2 -> a, All]


      To make it work. Then the code will look at all the levels of the trees (thus all the subtrees) and look for a matching replacement.



      I could also do :



      ReplaceAll[x^2 + 1, x^2 -> a]


      And here is my question : is there actually any difference between using



      Replace[expr, rule, All]


      and



      ReplaceAll[expr,rule]


      or it is indeed the same thing ?





      Another question linked to the answer



      Then I don't understand this behavior :



      diffReplaceReplaceAll = g[g[x]];

      Replace[diffReplaceReplaceAll, g -> c, All]

      g[g[x]]

      g[g[x]][[1]]

      g[x]

      ReplaceAll[diffReplaceReplaceAll, g -> c]

      c[c[x]]


      If I take strictly what you say, ReplaceAll shoud return c[g[x]]



      Indeed, it goes from the outside which is g[g[x]] (the whole tree), it looks at each part. So first it tries with the Head (the 0 part), which is $g$, it replaces it by $c$. And... it should stop here right ? Thus we would have c[g[x]] as a result. But it continues and replaces the second g. Why ?



      My problem is very probably linked to a not fully understanding of what a part precisely is. But if I'm not wrong the 0'th part is the head and the 1st part is g[x] here right ?



      I also have a problem with Replace : why if it goes from the inside to the outside I don't have at least g[c[x]] ?



      Remark : I don't fully get your example as I'm not familiar with ":>", I am reading about it now.





      I'm sorry but I still have problem to understand, here is the code I consider :



          expr = g[g[x]];
      ReplaceAll[expr, g -> fonction]
      ReplaceAll[expr, g[x_] -> fonction[x]]

      fonction[fonction[x]]

      fonction[g[x]]


      I will write what I understand step by step of what is happening : the first ReplaceAll : ReplaceAll[expr, g -> fonction]




      ReplaceAll looks at each part of expr, tries all the rules on it, and then goes on to the next part of expr. The first rule that applies to a particular part is used; no further rules are tried on that part or on any of its subparts.




      Allright, I will look at each part of expr.




      • I look at the 0'th part of expr which is the Head : g.
        I have a matching pattern, g becomes fonction. I don't have to look at subparts of g as I had a matching (but even in this case, g doesn't have subparts so it wouldn't change anything).

      • I go at the next part (1st part) of expr : fonction[g[x]][[1]] = g[x]
        it doesn't match.

      • I go at the first subpart of g[x] : g[x][[0]] = g, it matches. I replace. I don't have to look at the subparts of g as it matched. At this point I thus have fonction[fonction[x]]

      • I look at the 2ndt part of expr : fonction[fonction[x]][[2]] : it doesn't exist.


      Thus the code stops and the function returns : fonction[fonction[x]]



      Now for the second ReplaceAll : ReplaceAll[expr, g[x_] -> fonction[x]]




      • I look at the 0'th part of expr : g[g[x]][[0]] = g : no matching

      • I look at the subparts of g : it doesn't have, so it stops for that.

      • Thus, now I look at the 1st part of expr : g[g[x]][[1]] = g[x]
        It matches : g[x] -> fonction[x]. I thus now have g[fonction[x]]... which I know is wrong.


      Here is how I understood the algorithm and I still have a problem. I don't understand what precisely does the algorithm then.



      And is the 0'th part really the head or the full expression ? Because in the documentation of Replace for example :




      The default value for levelspec in Replace is {0}, corresponding to the whole expression.








      replacement






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 30 '18 at 22:09







      StarBucK

















      asked Dec 30 '18 at 16:37









      StarBucKStarBucK

      765213




      765213






















          1 Answer
          1






          active

          oldest

          votes


















          22














          No, they're not the same thing



          From the documentation of Replace (4th to last point):




          If levelspec includes multiple levels, expressions at deeper levels in a given subexpression are matched first.




          From the documentation of ReplaceAll (emphasis mine, 1st point):




          ReplaceAll looks at each part of expr, tries all the rules on it, and then goes on to the next part of expr. The first rule that applies to a particular part is used; no further rules are tried on that part or on any of its subparts.




          This means that ReplaceAll goes from the outside in, while Replace goes from the inside out. You can see this with the following example:



          ReplaceAll[f[f[x]], f[x_] :> g[x]]
          (* g[f[x]] *)

          Replace[f[f[x]], f[x_] :> g[x], All]
          (* g[g[x]] *)


          Since f[f[x]] matches the rule, ReplaceAll does not consider f[x] (because it is a subpart of something that has already been matched by a rule). Replace[…,All] on the other hand happily replaces both occurrences, the inner one being first:



          Replace[f[f[x]], f[x_] :> Echo@g[x], All]
          (* >> g[x] *)
          (* >> g[g[x]] *)
          (* g[g[x]] *)


          The second example



          Looking at the second example from the updated question:



          ReplaceAll[f[f[x]], f -> g]
          (* g[g[x]] *)

          Replace[f[f[x]], f -> g, All]
          (* f[f[x]] *)


          There are two things going on here:



          Why does Replace not replace anything?



          This is another difference between Replace and ReplaceAll: Replace has an option Heads, which by default is False. It controls whether the heads of expressions can be replaced. Specifying Heads->True gives the desired result:



          Replace[f[f[x]], f -> g, All, Heads -> True]
          (* g[g[x]] *)


          Why does ReplaceAll suddenly replace both occurrences of f with g?



          This is because the left side of the rule f->g only matches f, i.e. the head (or 0th part) of f[f[x]]. According to the documentation "no further rules are tried on that part or on any of its subparts". And indeed, the f (now g) or any of its subparts (of which there are none) are not touched by any other rule. We can see this in more detail with the following two examples:



          ReplaceAll[f[f[x]], {f -> g, g -> h}]
          (* g[g[x]] *)

          ReplaceAll[f[f[x]][x, y], {h_[x_] :> {h, x}}]
          (* {f, f[x]}[x, y] *)


          The first example demonstrates the first part: Even though g->h would match the newly added g, the rule is not applied, since that part has already been touched.



          The second example demonstrates that after the head f[f[x]] has been replaced, its subparts f and f[x] are not considered for further replacements.



          A more detailed look



          Since some things still appear to be unclear, I've written two functions to visualize how ReplaceAll/Replace work (code at the end). They emit log messages for each visited part of the expression, to illustrate how the expression is traversed and when replacing stops. Here are the outputs for a few of the above examples:



          ReplaceAllVerbose[f[f[x]], f -> g]
          (* Level 0, Part All: f[f[x]] does not match f, visiting parts
          (* Level 1, Part 0: f matches f, replaced with g. No parts will be visited
          (* Level 1, Part 1: f[x] does not match f, visiting parts
          (* Level 2, Part 0: f matches f, replaced with g. No parts will be visited
          (* Level 2, Part 1: x does not match f, visiting parts
          (* Level 2, Part 1: Done visiting parts, result is x
          (* Level 1, Part 1: Done visiting parts, result is g[x]
          (* Level 0, Part All: Done visiting parts, result is g[g[x]]
          (* g[g[x]] *)

          ReplaceAllVerbose[f[f[x]], f[x_] -> g[x]]
          (* Level 0, Part All: f[f[x]] matches f[x_], replaced with g[f[x]]. No parts will be visited *)
          (* g[f[x]] *)

          ReplaceVerbose[f[f[x]], f[x_] -> g[x]]
          (* Level 0, Part All: f[f[x]] matches f[x_], replaced with f[f[x]] *)
          (* g[f[x]] *)

          ReplaceVerbose[f[f[x]], f[x_] -> g[x], All]
          (* Level 2, Part 1: x does not match f[x_] *)
          (* Level 1, Part 1: f[x] matches f[x_], replaced with g[x] *)
          (* Level 0, Part All: f[g[x]] matches f[x_], replaced with g[g[x]] *)
          (* g[g[x]] *)

          ReplaceVerbose[f[f[x]], f -> g, All]
          (* Level 2, Part 1: x does not match f *)
          (* Level 1, Part 1: f[x] does not match f *)
          (* Level 0, Part All: f[f[x]] does not match f *)
          (* f[f[x]] *)

          ReplaceVerbose[f[f[x]], f -> g, All, Heads -> True]
          (* Level 1, Part 0: f matches f, replaced with g *)
          (* Level 2, Part 0: f matches f, replaced with g *)
          (* Level 2, Part 1: x does not match f *)
          (* Level 1, Part 1: g[x] does not match f *)
          (* Level 0, Part All: g[g[x]] does not match f *)
          (* g[g[x]] *)


          Here the code for ReplaceAllVerbose/ReplaceVerbose:



          ReplaceAllVerbose[expr_, rule : (Rule | RuleDelayed)[lhs_, _], n_: 0, i_: All] /;
          MatchQ[expr, lhs] :=
          EchoFunction[
          StringForm[
          "``Level ``, Part ``: `` matches ``, replaced with ``. No parts will be visited",
          Spacer[10 n],
          n,
          i,
          expr,
          lhs,
          #
          ] &
          ][
          expr /. rule
          ]
          ReplaceAllVerbose[expr_, rule_, n_: 0, i_: All] :=
          EchoFunction[
          StringForm[
          "``Level ``, Part ``: Done visiting parts, result is ``",
          Spacer[10 n],
          n,
          i,
          #
          ] &
          ][
          Echo[
          StringForm[
          "``Level ``, Part ``: `` does not match ``, visiting parts",
          Spacer[10 n],
          n,
          i,
          expr,
          First@rule
          ]
          ];
          MapIndexed[
          ReplaceAllVerbose[#, rule, n + 1, First@#2] &,
          expr,
          Heads -> True
          ]
          ]

          ReplaceVerbose[expr_, rule : (Rule | RuleDelayed)[lhs_, _], level_: {0}, o : OptionsPattern] := MapIndexed[
          With[
          {
          n = Length@#2,
          i = Last[#2, All]
          },
          Echo@If[
          MatchQ[#, lhs],
          StringForm[
          "``Level ``, Part ``: `` matches ``, replaced with ``",
          Spacer[10 n],
          n,
          i,
          #,
          lhs,
          Replace[#, rule]
          ],
          StringForm[
          "``Level ``, Part ``: `` does not match ``",
          Spacer[10 n],
          n,
          i,
          #,
          lhs
          ]
          ];
          Replace[#, rule]
          ] &,
          expr,
          level,
          o
          ]





          share|improve this answer























          • I still have a problem actually, I made an edit :) Thanks for your answer (things start to be more clear but not totally)
            – StarBucK
            Dec 30 '18 at 18:48








          • 1




            Does the update answer your questions?
            – Lukas Lang
            Dec 30 '18 at 19:12










          • I think I see what you mean. When it says "no further rules are tried on that part or any of its subpart", we talk precisely about the part of the element that has been replaced. So here I replaced f which doesn't have part. Thus it stops. We don't talk about the next part of the whole expression that would be f[f[x]][[1]] in this example. (We first replaced f[f[x]][[0]], but the next part is not understood as f[f[x]][[1]] but as the next part of the element that has been replaced which is a part of f, which doesn't exist). Am I correct ?
            – StarBucK
            Dec 30 '18 at 19:35








          • 1




            Updated the answer again - you simply forgot to consider the whole expression before any of its parts in your attempted explanation above. The level 0 has nothing to do with part 0: Mathematica distinguishes between part and level specifications. E.g. in f[g[x],y], part 0 is f, 1 is g[x], 2 is y, {1,0} is g and {1,1} is x. Level 0 on the other hand is the whole expression f[g[x],y], level 1 is the list of expressions that are parts of level 0, so {f,g[x],y} (assuming heads are included). Level 2 is similarly given by {g,x}. See also Level[f[g[x],y],{1},Heads->True]
            – Lukas Lang
            Dec 30 '18 at 22:43








          • 1




            If you still have doubts, you can try to play around with the ReplaceAllVerbose/ReplaceVerbose functions above for other examples, to see in what order parts are visited and what happens to them. They do not support list of rules, but otherwise they should be fully equivalent to the built-in versions in terms of results and functionality.
            – Lukas Lang
            Dec 30 '18 at 22:57













          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "387"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f188605%2fis-there-a-difference-between-replace-with-parameter-all-and-replaceall%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          22














          No, they're not the same thing



          From the documentation of Replace (4th to last point):




          If levelspec includes multiple levels, expressions at deeper levels in a given subexpression are matched first.




          From the documentation of ReplaceAll (emphasis mine, 1st point):




          ReplaceAll looks at each part of expr, tries all the rules on it, and then goes on to the next part of expr. The first rule that applies to a particular part is used; no further rules are tried on that part or on any of its subparts.




          This means that ReplaceAll goes from the outside in, while Replace goes from the inside out. You can see this with the following example:



          ReplaceAll[f[f[x]], f[x_] :> g[x]]
          (* g[f[x]] *)

          Replace[f[f[x]], f[x_] :> g[x], All]
          (* g[g[x]] *)


          Since f[f[x]] matches the rule, ReplaceAll does not consider f[x] (because it is a subpart of something that has already been matched by a rule). Replace[…,All] on the other hand happily replaces both occurrences, the inner one being first:



          Replace[f[f[x]], f[x_] :> Echo@g[x], All]
          (* >> g[x] *)
          (* >> g[g[x]] *)
          (* g[g[x]] *)


          The second example



          Looking at the second example from the updated question:



          ReplaceAll[f[f[x]], f -> g]
          (* g[g[x]] *)

          Replace[f[f[x]], f -> g, All]
          (* f[f[x]] *)


          There are two things going on here:



          Why does Replace not replace anything?



          This is another difference between Replace and ReplaceAll: Replace has an option Heads, which by default is False. It controls whether the heads of expressions can be replaced. Specifying Heads->True gives the desired result:



          Replace[f[f[x]], f -> g, All, Heads -> True]
          (* g[g[x]] *)


          Why does ReplaceAll suddenly replace both occurrences of f with g?



          This is because the left side of the rule f->g only matches f, i.e. the head (or 0th part) of f[f[x]]. According to the documentation "no further rules are tried on that part or on any of its subparts". And indeed, the f (now g) or any of its subparts (of which there are none) are not touched by any other rule. We can see this in more detail with the following two examples:



          ReplaceAll[f[f[x]], {f -> g, g -> h}]
          (* g[g[x]] *)

          ReplaceAll[f[f[x]][x, y], {h_[x_] :> {h, x}}]
          (* {f, f[x]}[x, y] *)


          The first example demonstrates the first part: Even though g->h would match the newly added g, the rule is not applied, since that part has already been touched.



          The second example demonstrates that after the head f[f[x]] has been replaced, its subparts f and f[x] are not considered for further replacements.



          A more detailed look



          Since some things still appear to be unclear, I've written two functions to visualize how ReplaceAll/Replace work (code at the end). They emit log messages for each visited part of the expression, to illustrate how the expression is traversed and when replacing stops. Here are the outputs for a few of the above examples:



          ReplaceAllVerbose[f[f[x]], f -> g]
          (* Level 0, Part All: f[f[x]] does not match f, visiting parts
          (* Level 1, Part 0: f matches f, replaced with g. No parts will be visited
          (* Level 1, Part 1: f[x] does not match f, visiting parts
          (* Level 2, Part 0: f matches f, replaced with g. No parts will be visited
          (* Level 2, Part 1: x does not match f, visiting parts
          (* Level 2, Part 1: Done visiting parts, result is x
          (* Level 1, Part 1: Done visiting parts, result is g[x]
          (* Level 0, Part All: Done visiting parts, result is g[g[x]]
          (* g[g[x]] *)

          ReplaceAllVerbose[f[f[x]], f[x_] -> g[x]]
          (* Level 0, Part All: f[f[x]] matches f[x_], replaced with g[f[x]]. No parts will be visited *)
          (* g[f[x]] *)

          ReplaceVerbose[f[f[x]], f[x_] -> g[x]]
          (* Level 0, Part All: f[f[x]] matches f[x_], replaced with f[f[x]] *)
          (* g[f[x]] *)

          ReplaceVerbose[f[f[x]], f[x_] -> g[x], All]
          (* Level 2, Part 1: x does not match f[x_] *)
          (* Level 1, Part 1: f[x] matches f[x_], replaced with g[x] *)
          (* Level 0, Part All: f[g[x]] matches f[x_], replaced with g[g[x]] *)
          (* g[g[x]] *)

          ReplaceVerbose[f[f[x]], f -> g, All]
          (* Level 2, Part 1: x does not match f *)
          (* Level 1, Part 1: f[x] does not match f *)
          (* Level 0, Part All: f[f[x]] does not match f *)
          (* f[f[x]] *)

          ReplaceVerbose[f[f[x]], f -> g, All, Heads -> True]
          (* Level 1, Part 0: f matches f, replaced with g *)
          (* Level 2, Part 0: f matches f, replaced with g *)
          (* Level 2, Part 1: x does not match f *)
          (* Level 1, Part 1: g[x] does not match f *)
          (* Level 0, Part All: g[g[x]] does not match f *)
          (* g[g[x]] *)


          Here the code for ReplaceAllVerbose/ReplaceVerbose:



          ReplaceAllVerbose[expr_, rule : (Rule | RuleDelayed)[lhs_, _], n_: 0, i_: All] /;
          MatchQ[expr, lhs] :=
          EchoFunction[
          StringForm[
          "``Level ``, Part ``: `` matches ``, replaced with ``. No parts will be visited",
          Spacer[10 n],
          n,
          i,
          expr,
          lhs,
          #
          ] &
          ][
          expr /. rule
          ]
          ReplaceAllVerbose[expr_, rule_, n_: 0, i_: All] :=
          EchoFunction[
          StringForm[
          "``Level ``, Part ``: Done visiting parts, result is ``",
          Spacer[10 n],
          n,
          i,
          #
          ] &
          ][
          Echo[
          StringForm[
          "``Level ``, Part ``: `` does not match ``, visiting parts",
          Spacer[10 n],
          n,
          i,
          expr,
          First@rule
          ]
          ];
          MapIndexed[
          ReplaceAllVerbose[#, rule, n + 1, First@#2] &,
          expr,
          Heads -> True
          ]
          ]

          ReplaceVerbose[expr_, rule : (Rule | RuleDelayed)[lhs_, _], level_: {0}, o : OptionsPattern] := MapIndexed[
          With[
          {
          n = Length@#2,
          i = Last[#2, All]
          },
          Echo@If[
          MatchQ[#, lhs],
          StringForm[
          "``Level ``, Part ``: `` matches ``, replaced with ``",
          Spacer[10 n],
          n,
          i,
          #,
          lhs,
          Replace[#, rule]
          ],
          StringForm[
          "``Level ``, Part ``: `` does not match ``",
          Spacer[10 n],
          n,
          i,
          #,
          lhs
          ]
          ];
          Replace[#, rule]
          ] &,
          expr,
          level,
          o
          ]





          share|improve this answer























          • I still have a problem actually, I made an edit :) Thanks for your answer (things start to be more clear but not totally)
            – StarBucK
            Dec 30 '18 at 18:48








          • 1




            Does the update answer your questions?
            – Lukas Lang
            Dec 30 '18 at 19:12










          • I think I see what you mean. When it says "no further rules are tried on that part or any of its subpart", we talk precisely about the part of the element that has been replaced. So here I replaced f which doesn't have part. Thus it stops. We don't talk about the next part of the whole expression that would be f[f[x]][[1]] in this example. (We first replaced f[f[x]][[0]], but the next part is not understood as f[f[x]][[1]] but as the next part of the element that has been replaced which is a part of f, which doesn't exist). Am I correct ?
            – StarBucK
            Dec 30 '18 at 19:35








          • 1




            Updated the answer again - you simply forgot to consider the whole expression before any of its parts in your attempted explanation above. The level 0 has nothing to do with part 0: Mathematica distinguishes between part and level specifications. E.g. in f[g[x],y], part 0 is f, 1 is g[x], 2 is y, {1,0} is g and {1,1} is x. Level 0 on the other hand is the whole expression f[g[x],y], level 1 is the list of expressions that are parts of level 0, so {f,g[x],y} (assuming heads are included). Level 2 is similarly given by {g,x}. See also Level[f[g[x],y],{1},Heads->True]
            – Lukas Lang
            Dec 30 '18 at 22:43








          • 1




            If you still have doubts, you can try to play around with the ReplaceAllVerbose/ReplaceVerbose functions above for other examples, to see in what order parts are visited and what happens to them. They do not support list of rules, but otherwise they should be fully equivalent to the built-in versions in terms of results and functionality.
            – Lukas Lang
            Dec 30 '18 at 22:57


















          22














          No, they're not the same thing



          From the documentation of Replace (4th to last point):




          If levelspec includes multiple levels, expressions at deeper levels in a given subexpression are matched first.




          From the documentation of ReplaceAll (emphasis mine, 1st point):




          ReplaceAll looks at each part of expr, tries all the rules on it, and then goes on to the next part of expr. The first rule that applies to a particular part is used; no further rules are tried on that part or on any of its subparts.




          This means that ReplaceAll goes from the outside in, while Replace goes from the inside out. You can see this with the following example:



          ReplaceAll[f[f[x]], f[x_] :> g[x]]
          (* g[f[x]] *)

          Replace[f[f[x]], f[x_] :> g[x], All]
          (* g[g[x]] *)


          Since f[f[x]] matches the rule, ReplaceAll does not consider f[x] (because it is a subpart of something that has already been matched by a rule). Replace[…,All] on the other hand happily replaces both occurrences, the inner one being first:



          Replace[f[f[x]], f[x_] :> Echo@g[x], All]
          (* >> g[x] *)
          (* >> g[g[x]] *)
          (* g[g[x]] *)


          The second example



          Looking at the second example from the updated question:



          ReplaceAll[f[f[x]], f -> g]
          (* g[g[x]] *)

          Replace[f[f[x]], f -> g, All]
          (* f[f[x]] *)


          There are two things going on here:



          Why does Replace not replace anything?



          This is another difference between Replace and ReplaceAll: Replace has an option Heads, which by default is False. It controls whether the heads of expressions can be replaced. Specifying Heads->True gives the desired result:



          Replace[f[f[x]], f -> g, All, Heads -> True]
          (* g[g[x]] *)


          Why does ReplaceAll suddenly replace both occurrences of f with g?



          This is because the left side of the rule f->g only matches f, i.e. the head (or 0th part) of f[f[x]]. According to the documentation "no further rules are tried on that part or on any of its subparts". And indeed, the f (now g) or any of its subparts (of which there are none) are not touched by any other rule. We can see this in more detail with the following two examples:



          ReplaceAll[f[f[x]], {f -> g, g -> h}]
          (* g[g[x]] *)

          ReplaceAll[f[f[x]][x, y], {h_[x_] :> {h, x}}]
          (* {f, f[x]}[x, y] *)


          The first example demonstrates the first part: Even though g->h would match the newly added g, the rule is not applied, since that part has already been touched.



          The second example demonstrates that after the head f[f[x]] has been replaced, its subparts f and f[x] are not considered for further replacements.



          A more detailed look



          Since some things still appear to be unclear, I've written two functions to visualize how ReplaceAll/Replace work (code at the end). They emit log messages for each visited part of the expression, to illustrate how the expression is traversed and when replacing stops. Here are the outputs for a few of the above examples:



          ReplaceAllVerbose[f[f[x]], f -> g]
          (* Level 0, Part All: f[f[x]] does not match f, visiting parts
          (* Level 1, Part 0: f matches f, replaced with g. No parts will be visited
          (* Level 1, Part 1: f[x] does not match f, visiting parts
          (* Level 2, Part 0: f matches f, replaced with g. No parts will be visited
          (* Level 2, Part 1: x does not match f, visiting parts
          (* Level 2, Part 1: Done visiting parts, result is x
          (* Level 1, Part 1: Done visiting parts, result is g[x]
          (* Level 0, Part All: Done visiting parts, result is g[g[x]]
          (* g[g[x]] *)

          ReplaceAllVerbose[f[f[x]], f[x_] -> g[x]]
          (* Level 0, Part All: f[f[x]] matches f[x_], replaced with g[f[x]]. No parts will be visited *)
          (* g[f[x]] *)

          ReplaceVerbose[f[f[x]], f[x_] -> g[x]]
          (* Level 0, Part All: f[f[x]] matches f[x_], replaced with f[f[x]] *)
          (* g[f[x]] *)

          ReplaceVerbose[f[f[x]], f[x_] -> g[x], All]
          (* Level 2, Part 1: x does not match f[x_] *)
          (* Level 1, Part 1: f[x] matches f[x_], replaced with g[x] *)
          (* Level 0, Part All: f[g[x]] matches f[x_], replaced with g[g[x]] *)
          (* g[g[x]] *)

          ReplaceVerbose[f[f[x]], f -> g, All]
          (* Level 2, Part 1: x does not match f *)
          (* Level 1, Part 1: f[x] does not match f *)
          (* Level 0, Part All: f[f[x]] does not match f *)
          (* f[f[x]] *)

          ReplaceVerbose[f[f[x]], f -> g, All, Heads -> True]
          (* Level 1, Part 0: f matches f, replaced with g *)
          (* Level 2, Part 0: f matches f, replaced with g *)
          (* Level 2, Part 1: x does not match f *)
          (* Level 1, Part 1: g[x] does not match f *)
          (* Level 0, Part All: g[g[x]] does not match f *)
          (* g[g[x]] *)


          Here the code for ReplaceAllVerbose/ReplaceVerbose:



          ReplaceAllVerbose[expr_, rule : (Rule | RuleDelayed)[lhs_, _], n_: 0, i_: All] /;
          MatchQ[expr, lhs] :=
          EchoFunction[
          StringForm[
          "``Level ``, Part ``: `` matches ``, replaced with ``. No parts will be visited",
          Spacer[10 n],
          n,
          i,
          expr,
          lhs,
          #
          ] &
          ][
          expr /. rule
          ]
          ReplaceAllVerbose[expr_, rule_, n_: 0, i_: All] :=
          EchoFunction[
          StringForm[
          "``Level ``, Part ``: Done visiting parts, result is ``",
          Spacer[10 n],
          n,
          i,
          #
          ] &
          ][
          Echo[
          StringForm[
          "``Level ``, Part ``: `` does not match ``, visiting parts",
          Spacer[10 n],
          n,
          i,
          expr,
          First@rule
          ]
          ];
          MapIndexed[
          ReplaceAllVerbose[#, rule, n + 1, First@#2] &,
          expr,
          Heads -> True
          ]
          ]

          ReplaceVerbose[expr_, rule : (Rule | RuleDelayed)[lhs_, _], level_: {0}, o : OptionsPattern] := MapIndexed[
          With[
          {
          n = Length@#2,
          i = Last[#2, All]
          },
          Echo@If[
          MatchQ[#, lhs],
          StringForm[
          "``Level ``, Part ``: `` matches ``, replaced with ``",
          Spacer[10 n],
          n,
          i,
          #,
          lhs,
          Replace[#, rule]
          ],
          StringForm[
          "``Level ``, Part ``: `` does not match ``",
          Spacer[10 n],
          n,
          i,
          #,
          lhs
          ]
          ];
          Replace[#, rule]
          ] &,
          expr,
          level,
          o
          ]





          share|improve this answer























          • I still have a problem actually, I made an edit :) Thanks for your answer (things start to be more clear but not totally)
            – StarBucK
            Dec 30 '18 at 18:48








          • 1




            Does the update answer your questions?
            – Lukas Lang
            Dec 30 '18 at 19:12










          • I think I see what you mean. When it says "no further rules are tried on that part or any of its subpart", we talk precisely about the part of the element that has been replaced. So here I replaced f which doesn't have part. Thus it stops. We don't talk about the next part of the whole expression that would be f[f[x]][[1]] in this example. (We first replaced f[f[x]][[0]], but the next part is not understood as f[f[x]][[1]] but as the next part of the element that has been replaced which is a part of f, which doesn't exist). Am I correct ?
            – StarBucK
            Dec 30 '18 at 19:35








          • 1




            Updated the answer again - you simply forgot to consider the whole expression before any of its parts in your attempted explanation above. The level 0 has nothing to do with part 0: Mathematica distinguishes between part and level specifications. E.g. in f[g[x],y], part 0 is f, 1 is g[x], 2 is y, {1,0} is g and {1,1} is x. Level 0 on the other hand is the whole expression f[g[x],y], level 1 is the list of expressions that are parts of level 0, so {f,g[x],y} (assuming heads are included). Level 2 is similarly given by {g,x}. See also Level[f[g[x],y],{1},Heads->True]
            – Lukas Lang
            Dec 30 '18 at 22:43








          • 1




            If you still have doubts, you can try to play around with the ReplaceAllVerbose/ReplaceVerbose functions above for other examples, to see in what order parts are visited and what happens to them. They do not support list of rules, but otherwise they should be fully equivalent to the built-in versions in terms of results and functionality.
            – Lukas Lang
            Dec 30 '18 at 22:57
















          22












          22








          22






          No, they're not the same thing



          From the documentation of Replace (4th to last point):




          If levelspec includes multiple levels, expressions at deeper levels in a given subexpression are matched first.




          From the documentation of ReplaceAll (emphasis mine, 1st point):




          ReplaceAll looks at each part of expr, tries all the rules on it, and then goes on to the next part of expr. The first rule that applies to a particular part is used; no further rules are tried on that part or on any of its subparts.




          This means that ReplaceAll goes from the outside in, while Replace goes from the inside out. You can see this with the following example:



          ReplaceAll[f[f[x]], f[x_] :> g[x]]
          (* g[f[x]] *)

          Replace[f[f[x]], f[x_] :> g[x], All]
          (* g[g[x]] *)


          Since f[f[x]] matches the rule, ReplaceAll does not consider f[x] (because it is a subpart of something that has already been matched by a rule). Replace[…,All] on the other hand happily replaces both occurrences, the inner one being first:



          Replace[f[f[x]], f[x_] :> Echo@g[x], All]
          (* >> g[x] *)
          (* >> g[g[x]] *)
          (* g[g[x]] *)


          The second example



          Looking at the second example from the updated question:



          ReplaceAll[f[f[x]], f -> g]
          (* g[g[x]] *)

          Replace[f[f[x]], f -> g, All]
          (* f[f[x]] *)


          There are two things going on here:



          Why does Replace not replace anything?



          This is another difference between Replace and ReplaceAll: Replace has an option Heads, which by default is False. It controls whether the heads of expressions can be replaced. Specifying Heads->True gives the desired result:



          Replace[f[f[x]], f -> g, All, Heads -> True]
          (* g[g[x]] *)


          Why does ReplaceAll suddenly replace both occurrences of f with g?



          This is because the left side of the rule f->g only matches f, i.e. the head (or 0th part) of f[f[x]]. According to the documentation "no further rules are tried on that part or on any of its subparts". And indeed, the f (now g) or any of its subparts (of which there are none) are not touched by any other rule. We can see this in more detail with the following two examples:



          ReplaceAll[f[f[x]], {f -> g, g -> h}]
          (* g[g[x]] *)

          ReplaceAll[f[f[x]][x, y], {h_[x_] :> {h, x}}]
          (* {f, f[x]}[x, y] *)


          The first example demonstrates the first part: Even though g->h would match the newly added g, the rule is not applied, since that part has already been touched.



          The second example demonstrates that after the head f[f[x]] has been replaced, its subparts f and f[x] are not considered for further replacements.



          A more detailed look



          Since some things still appear to be unclear, I've written two functions to visualize how ReplaceAll/Replace work (code at the end). They emit log messages for each visited part of the expression, to illustrate how the expression is traversed and when replacing stops. Here are the outputs for a few of the above examples:



          ReplaceAllVerbose[f[f[x]], f -> g]
          (* Level 0, Part All: f[f[x]] does not match f, visiting parts
          (* Level 1, Part 0: f matches f, replaced with g. No parts will be visited
          (* Level 1, Part 1: f[x] does not match f, visiting parts
          (* Level 2, Part 0: f matches f, replaced with g. No parts will be visited
          (* Level 2, Part 1: x does not match f, visiting parts
          (* Level 2, Part 1: Done visiting parts, result is x
          (* Level 1, Part 1: Done visiting parts, result is g[x]
          (* Level 0, Part All: Done visiting parts, result is g[g[x]]
          (* g[g[x]] *)

          ReplaceAllVerbose[f[f[x]], f[x_] -> g[x]]
          (* Level 0, Part All: f[f[x]] matches f[x_], replaced with g[f[x]]. No parts will be visited *)
          (* g[f[x]] *)

          ReplaceVerbose[f[f[x]], f[x_] -> g[x]]
          (* Level 0, Part All: f[f[x]] matches f[x_], replaced with f[f[x]] *)
          (* g[f[x]] *)

          ReplaceVerbose[f[f[x]], f[x_] -> g[x], All]
          (* Level 2, Part 1: x does not match f[x_] *)
          (* Level 1, Part 1: f[x] matches f[x_], replaced with g[x] *)
          (* Level 0, Part All: f[g[x]] matches f[x_], replaced with g[g[x]] *)
          (* g[g[x]] *)

          ReplaceVerbose[f[f[x]], f -> g, All]
          (* Level 2, Part 1: x does not match f *)
          (* Level 1, Part 1: f[x] does not match f *)
          (* Level 0, Part All: f[f[x]] does not match f *)
          (* f[f[x]] *)

          ReplaceVerbose[f[f[x]], f -> g, All, Heads -> True]
          (* Level 1, Part 0: f matches f, replaced with g *)
          (* Level 2, Part 0: f matches f, replaced with g *)
          (* Level 2, Part 1: x does not match f *)
          (* Level 1, Part 1: g[x] does not match f *)
          (* Level 0, Part All: g[g[x]] does not match f *)
          (* g[g[x]] *)


          Here the code for ReplaceAllVerbose/ReplaceVerbose:



          ReplaceAllVerbose[expr_, rule : (Rule | RuleDelayed)[lhs_, _], n_: 0, i_: All] /;
          MatchQ[expr, lhs] :=
          EchoFunction[
          StringForm[
          "``Level ``, Part ``: `` matches ``, replaced with ``. No parts will be visited",
          Spacer[10 n],
          n,
          i,
          expr,
          lhs,
          #
          ] &
          ][
          expr /. rule
          ]
          ReplaceAllVerbose[expr_, rule_, n_: 0, i_: All] :=
          EchoFunction[
          StringForm[
          "``Level ``, Part ``: Done visiting parts, result is ``",
          Spacer[10 n],
          n,
          i,
          #
          ] &
          ][
          Echo[
          StringForm[
          "``Level ``, Part ``: `` does not match ``, visiting parts",
          Spacer[10 n],
          n,
          i,
          expr,
          First@rule
          ]
          ];
          MapIndexed[
          ReplaceAllVerbose[#, rule, n + 1, First@#2] &,
          expr,
          Heads -> True
          ]
          ]

          ReplaceVerbose[expr_, rule : (Rule | RuleDelayed)[lhs_, _], level_: {0}, o : OptionsPattern] := MapIndexed[
          With[
          {
          n = Length@#2,
          i = Last[#2, All]
          },
          Echo@If[
          MatchQ[#, lhs],
          StringForm[
          "``Level ``, Part ``: `` matches ``, replaced with ``",
          Spacer[10 n],
          n,
          i,
          #,
          lhs,
          Replace[#, rule]
          ],
          StringForm[
          "``Level ``, Part ``: `` does not match ``",
          Spacer[10 n],
          n,
          i,
          #,
          lhs
          ]
          ];
          Replace[#, rule]
          ] &,
          expr,
          level,
          o
          ]





          share|improve this answer














          No, they're not the same thing



          From the documentation of Replace (4th to last point):




          If levelspec includes multiple levels, expressions at deeper levels in a given subexpression are matched first.




          From the documentation of ReplaceAll (emphasis mine, 1st point):




          ReplaceAll looks at each part of expr, tries all the rules on it, and then goes on to the next part of expr. The first rule that applies to a particular part is used; no further rules are tried on that part or on any of its subparts.




          This means that ReplaceAll goes from the outside in, while Replace goes from the inside out. You can see this with the following example:



          ReplaceAll[f[f[x]], f[x_] :> g[x]]
          (* g[f[x]] *)

          Replace[f[f[x]], f[x_] :> g[x], All]
          (* g[g[x]] *)


          Since f[f[x]] matches the rule, ReplaceAll does not consider f[x] (because it is a subpart of something that has already been matched by a rule). Replace[…,All] on the other hand happily replaces both occurrences, the inner one being first:



          Replace[f[f[x]], f[x_] :> Echo@g[x], All]
          (* >> g[x] *)
          (* >> g[g[x]] *)
          (* g[g[x]] *)


          The second example



          Looking at the second example from the updated question:



          ReplaceAll[f[f[x]], f -> g]
          (* g[g[x]] *)

          Replace[f[f[x]], f -> g, All]
          (* f[f[x]] *)


          There are two things going on here:



          Why does Replace not replace anything?



          This is another difference between Replace and ReplaceAll: Replace has an option Heads, which by default is False. It controls whether the heads of expressions can be replaced. Specifying Heads->True gives the desired result:



          Replace[f[f[x]], f -> g, All, Heads -> True]
          (* g[g[x]] *)


          Why does ReplaceAll suddenly replace both occurrences of f with g?



          This is because the left side of the rule f->g only matches f, i.e. the head (or 0th part) of f[f[x]]. According to the documentation "no further rules are tried on that part or on any of its subparts". And indeed, the f (now g) or any of its subparts (of which there are none) are not touched by any other rule. We can see this in more detail with the following two examples:



          ReplaceAll[f[f[x]], {f -> g, g -> h}]
          (* g[g[x]] *)

          ReplaceAll[f[f[x]][x, y], {h_[x_] :> {h, x}}]
          (* {f, f[x]}[x, y] *)


          The first example demonstrates the first part: Even though g->h would match the newly added g, the rule is not applied, since that part has already been touched.



          The second example demonstrates that after the head f[f[x]] has been replaced, its subparts f and f[x] are not considered for further replacements.



          A more detailed look



          Since some things still appear to be unclear, I've written two functions to visualize how ReplaceAll/Replace work (code at the end). They emit log messages for each visited part of the expression, to illustrate how the expression is traversed and when replacing stops. Here are the outputs for a few of the above examples:



          ReplaceAllVerbose[f[f[x]], f -> g]
          (* Level 0, Part All: f[f[x]] does not match f, visiting parts
          (* Level 1, Part 0: f matches f, replaced with g. No parts will be visited
          (* Level 1, Part 1: f[x] does not match f, visiting parts
          (* Level 2, Part 0: f matches f, replaced with g. No parts will be visited
          (* Level 2, Part 1: x does not match f, visiting parts
          (* Level 2, Part 1: Done visiting parts, result is x
          (* Level 1, Part 1: Done visiting parts, result is g[x]
          (* Level 0, Part All: Done visiting parts, result is g[g[x]]
          (* g[g[x]] *)

          ReplaceAllVerbose[f[f[x]], f[x_] -> g[x]]
          (* Level 0, Part All: f[f[x]] matches f[x_], replaced with g[f[x]]. No parts will be visited *)
          (* g[f[x]] *)

          ReplaceVerbose[f[f[x]], f[x_] -> g[x]]
          (* Level 0, Part All: f[f[x]] matches f[x_], replaced with f[f[x]] *)
          (* g[f[x]] *)

          ReplaceVerbose[f[f[x]], f[x_] -> g[x], All]
          (* Level 2, Part 1: x does not match f[x_] *)
          (* Level 1, Part 1: f[x] matches f[x_], replaced with g[x] *)
          (* Level 0, Part All: f[g[x]] matches f[x_], replaced with g[g[x]] *)
          (* g[g[x]] *)

          ReplaceVerbose[f[f[x]], f -> g, All]
          (* Level 2, Part 1: x does not match f *)
          (* Level 1, Part 1: f[x] does not match f *)
          (* Level 0, Part All: f[f[x]] does not match f *)
          (* f[f[x]] *)

          ReplaceVerbose[f[f[x]], f -> g, All, Heads -> True]
          (* Level 1, Part 0: f matches f, replaced with g *)
          (* Level 2, Part 0: f matches f, replaced with g *)
          (* Level 2, Part 1: x does not match f *)
          (* Level 1, Part 1: g[x] does not match f *)
          (* Level 0, Part All: g[g[x]] does not match f *)
          (* g[g[x]] *)


          Here the code for ReplaceAllVerbose/ReplaceVerbose:



          ReplaceAllVerbose[expr_, rule : (Rule | RuleDelayed)[lhs_, _], n_: 0, i_: All] /;
          MatchQ[expr, lhs] :=
          EchoFunction[
          StringForm[
          "``Level ``, Part ``: `` matches ``, replaced with ``. No parts will be visited",
          Spacer[10 n],
          n,
          i,
          expr,
          lhs,
          #
          ] &
          ][
          expr /. rule
          ]
          ReplaceAllVerbose[expr_, rule_, n_: 0, i_: All] :=
          EchoFunction[
          StringForm[
          "``Level ``, Part ``: Done visiting parts, result is ``",
          Spacer[10 n],
          n,
          i,
          #
          ] &
          ][
          Echo[
          StringForm[
          "``Level ``, Part ``: `` does not match ``, visiting parts",
          Spacer[10 n],
          n,
          i,
          expr,
          First@rule
          ]
          ];
          MapIndexed[
          ReplaceAllVerbose[#, rule, n + 1, First@#2] &,
          expr,
          Heads -> True
          ]
          ]

          ReplaceVerbose[expr_, rule : (Rule | RuleDelayed)[lhs_, _], level_: {0}, o : OptionsPattern] := MapIndexed[
          With[
          {
          n = Length@#2,
          i = Last[#2, All]
          },
          Echo@If[
          MatchQ[#, lhs],
          StringForm[
          "``Level ``, Part ``: `` matches ``, replaced with ``",
          Spacer[10 n],
          n,
          i,
          #,
          lhs,
          Replace[#, rule]
          ],
          StringForm[
          "``Level ``, Part ``: `` does not match ``",
          Spacer[10 n],
          n,
          i,
          #,
          lhs
          ]
          ];
          Replace[#, rule]
          ] &,
          expr,
          level,
          o
          ]






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 2 at 13:00

























          answered Dec 30 '18 at 17:04









          Lukas LangLukas Lang

          6,4401929




          6,4401929












          • I still have a problem actually, I made an edit :) Thanks for your answer (things start to be more clear but not totally)
            – StarBucK
            Dec 30 '18 at 18:48








          • 1




            Does the update answer your questions?
            – Lukas Lang
            Dec 30 '18 at 19:12










          • I think I see what you mean. When it says "no further rules are tried on that part or any of its subpart", we talk precisely about the part of the element that has been replaced. So here I replaced f which doesn't have part. Thus it stops. We don't talk about the next part of the whole expression that would be f[f[x]][[1]] in this example. (We first replaced f[f[x]][[0]], but the next part is not understood as f[f[x]][[1]] but as the next part of the element that has been replaced which is a part of f, which doesn't exist). Am I correct ?
            – StarBucK
            Dec 30 '18 at 19:35








          • 1




            Updated the answer again - you simply forgot to consider the whole expression before any of its parts in your attempted explanation above. The level 0 has nothing to do with part 0: Mathematica distinguishes between part and level specifications. E.g. in f[g[x],y], part 0 is f, 1 is g[x], 2 is y, {1,0} is g and {1,1} is x. Level 0 on the other hand is the whole expression f[g[x],y], level 1 is the list of expressions that are parts of level 0, so {f,g[x],y} (assuming heads are included). Level 2 is similarly given by {g,x}. See also Level[f[g[x],y],{1},Heads->True]
            – Lukas Lang
            Dec 30 '18 at 22:43








          • 1




            If you still have doubts, you can try to play around with the ReplaceAllVerbose/ReplaceVerbose functions above for other examples, to see in what order parts are visited and what happens to them. They do not support list of rules, but otherwise they should be fully equivalent to the built-in versions in terms of results and functionality.
            – Lukas Lang
            Dec 30 '18 at 22:57




















          • I still have a problem actually, I made an edit :) Thanks for your answer (things start to be more clear but not totally)
            – StarBucK
            Dec 30 '18 at 18:48








          • 1




            Does the update answer your questions?
            – Lukas Lang
            Dec 30 '18 at 19:12










          • I think I see what you mean. When it says "no further rules are tried on that part or any of its subpart", we talk precisely about the part of the element that has been replaced. So here I replaced f which doesn't have part. Thus it stops. We don't talk about the next part of the whole expression that would be f[f[x]][[1]] in this example. (We first replaced f[f[x]][[0]], but the next part is not understood as f[f[x]][[1]] but as the next part of the element that has been replaced which is a part of f, which doesn't exist). Am I correct ?
            – StarBucK
            Dec 30 '18 at 19:35








          • 1




            Updated the answer again - you simply forgot to consider the whole expression before any of its parts in your attempted explanation above. The level 0 has nothing to do with part 0: Mathematica distinguishes between part and level specifications. E.g. in f[g[x],y], part 0 is f, 1 is g[x], 2 is y, {1,0} is g and {1,1} is x. Level 0 on the other hand is the whole expression f[g[x],y], level 1 is the list of expressions that are parts of level 0, so {f,g[x],y} (assuming heads are included). Level 2 is similarly given by {g,x}. See also Level[f[g[x],y],{1},Heads->True]
            – Lukas Lang
            Dec 30 '18 at 22:43








          • 1




            If you still have doubts, you can try to play around with the ReplaceAllVerbose/ReplaceVerbose functions above for other examples, to see in what order parts are visited and what happens to them. They do not support list of rules, but otherwise they should be fully equivalent to the built-in versions in terms of results and functionality.
            – Lukas Lang
            Dec 30 '18 at 22:57


















          I still have a problem actually, I made an edit :) Thanks for your answer (things start to be more clear but not totally)
          – StarBucK
          Dec 30 '18 at 18:48






          I still have a problem actually, I made an edit :) Thanks for your answer (things start to be more clear but not totally)
          – StarBucK
          Dec 30 '18 at 18:48






          1




          1




          Does the update answer your questions?
          – Lukas Lang
          Dec 30 '18 at 19:12




          Does the update answer your questions?
          – Lukas Lang
          Dec 30 '18 at 19:12












          I think I see what you mean. When it says "no further rules are tried on that part or any of its subpart", we talk precisely about the part of the element that has been replaced. So here I replaced f which doesn't have part. Thus it stops. We don't talk about the next part of the whole expression that would be f[f[x]][[1]] in this example. (We first replaced f[f[x]][[0]], but the next part is not understood as f[f[x]][[1]] but as the next part of the element that has been replaced which is a part of f, which doesn't exist). Am I correct ?
          – StarBucK
          Dec 30 '18 at 19:35






          I think I see what you mean. When it says "no further rules are tried on that part or any of its subpart", we talk precisely about the part of the element that has been replaced. So here I replaced f which doesn't have part. Thus it stops. We don't talk about the next part of the whole expression that would be f[f[x]][[1]] in this example. (We first replaced f[f[x]][[0]], but the next part is not understood as f[f[x]][[1]] but as the next part of the element that has been replaced which is a part of f, which doesn't exist). Am I correct ?
          – StarBucK
          Dec 30 '18 at 19:35






          1




          1




          Updated the answer again - you simply forgot to consider the whole expression before any of its parts in your attempted explanation above. The level 0 has nothing to do with part 0: Mathematica distinguishes between part and level specifications. E.g. in f[g[x],y], part 0 is f, 1 is g[x], 2 is y, {1,0} is g and {1,1} is x. Level 0 on the other hand is the whole expression f[g[x],y], level 1 is the list of expressions that are parts of level 0, so {f,g[x],y} (assuming heads are included). Level 2 is similarly given by {g,x}. See also Level[f[g[x],y],{1},Heads->True]
          – Lukas Lang
          Dec 30 '18 at 22:43






          Updated the answer again - you simply forgot to consider the whole expression before any of its parts in your attempted explanation above. The level 0 has nothing to do with part 0: Mathematica distinguishes between part and level specifications. E.g. in f[g[x],y], part 0 is f, 1 is g[x], 2 is y, {1,0} is g and {1,1} is x. Level 0 on the other hand is the whole expression f[g[x],y], level 1 is the list of expressions that are parts of level 0, so {f,g[x],y} (assuming heads are included). Level 2 is similarly given by {g,x}. See also Level[f[g[x],y],{1},Heads->True]
          – Lukas Lang
          Dec 30 '18 at 22:43






          1




          1




          If you still have doubts, you can try to play around with the ReplaceAllVerbose/ReplaceVerbose functions above for other examples, to see in what order parts are visited and what happens to them. They do not support list of rules, but otherwise they should be fully equivalent to the built-in versions in terms of results and functionality.
          – Lukas Lang
          Dec 30 '18 at 22:57






          If you still have doubts, you can try to play around with the ReplaceAllVerbose/ReplaceVerbose functions above for other examples, to see in what order parts are visited and what happens to them. They do not support list of rules, but otherwise they should be fully equivalent to the built-in versions in terms of results and functionality.
          – Lukas Lang
          Dec 30 '18 at 22:57




















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Mathematica Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f188605%2fis-there-a-difference-between-replace-with-parameter-all-and-replaceall%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

          ComboBox Display Member on multiple fields

          Is it possible to collect Nectar points via Trainline?