Perform localized, evaluation-leak free replacements












8














Consider the following expression:



expr = Hold[
{
f[
{1, {Print@1}}
],
g[
{{{Print@1}}}
]
}
];


I'm looking for a way to apply a replacement rule to the contents of all expressions with head f. To give a more concrete example, let's say I want to replace Print by Echo, but only inside f.



Restrictions: I have no knowledge about the exact structure around and inside f - there could be more or less nesting going on. This means the replacement rule can't capture the wrapper with Hold attribute, nor can it capture the individual parts of f[…]. (And the evaluation of Print should be prevented of course)










share|improve this question





























    8














    Consider the following expression:



    expr = Hold[
    {
    f[
    {1, {Print@1}}
    ],
    g[
    {{{Print@1}}}
    ]
    }
    ];


    I'm looking for a way to apply a replacement rule to the contents of all expressions with head f. To give a more concrete example, let's say I want to replace Print by Echo, but only inside f.



    Restrictions: I have no knowledge about the exact structure around and inside f - there could be more or less nesting going on. This means the replacement rule can't capture the wrapper with Hold attribute, nor can it capture the individual parts of f[…]. (And the evaluation of Print should be prevented of course)










    share|improve this question



























      8












      8








      8


      1





      Consider the following expression:



      expr = Hold[
      {
      f[
      {1, {Print@1}}
      ],
      g[
      {{{Print@1}}}
      ]
      }
      ];


      I'm looking for a way to apply a replacement rule to the contents of all expressions with head f. To give a more concrete example, let's say I want to replace Print by Echo, but only inside f.



      Restrictions: I have no knowledge about the exact structure around and inside f - there could be more or less nesting going on. This means the replacement rule can't capture the wrapper with Hold attribute, nor can it capture the individual parts of f[…]. (And the evaluation of Print should be prevented of course)










      share|improve this question















      Consider the following expression:



      expr = Hold[
      {
      f[
      {1, {Print@1}}
      ],
      g[
      {{{Print@1}}}
      ]
      }
      ];


      I'm looking for a way to apply a replacement rule to the contents of all expressions with head f. To give a more concrete example, let's say I want to replace Print by Echo, but only inside f.



      Restrictions: I have no knowledge about the exact structure around and inside f - there could be more or less nesting going on. This means the replacement rule can't capture the wrapper with Hold attribute, nor can it capture the individual parts of f[…]. (And the evaluation of Print should be prevented of course)







      evaluation replacement hold






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 10 hours ago









      Kuba

      103k12201516




      103k12201516










      asked yesterday









      Lukas Lang

      6,4351929




      6,4351929






















          3 Answers
          3






          active

          oldest

          votes


















          9














          Here's a way making use of Block to cause f to be inert:



          Block[{f},
          SetAttributes[f, HoldAllComplete];
          expr /. f[args__] :>
          RuleCondition[f[args] /. Print -> Echo]
          ]

          Hold[{f[{1, {Echo[1]}}], g[{{{Print[1]}}}]}]


          Note of course that this only works if you have a pattern of the form _Symbol[...]






          share|improve this answer





























            8














            I can think of one (ugly) way to do it:



            Attributes[myHold] = {HoldAll};

            expr /.
            f[args__] :> With[
            {res = myHold[args] /. Print -> Echo},
            f @@ res /; True
            ] /.
            HoldPattern[f_ @@ myHold[args__]] :> f[args]
            (* Hold[{f[{1, {Echo[1]}}], g[{{{Print[1]}}}]}] *)


            The idea is to wrap the contents of f inside a function with HoldAll attribute (not Hold, to be able to identify it uniquely later on). In a first step, the expression is returned with myHold[…] still in place. In a second round of replacements, myHold is stripped out again.






            share|improve this answer

















            • 1




              +1. If we use the vanishing macro defined in (43096), we can write vanishing[{h}, expr /. x_f :> RuleCondition[h[x] /. Print -> Echo]].
              – WReach
              yesterday



















            2














            Alternatively:



            expr /. 
            foo_f :> RuleCondition[Hold[foo] /. Print -> Echo] /.
            Hold[foo_f] :> foo





            share|improve this answer





















              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%2f188887%2fperform-localized-evaluation-leak-free-replacements%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              9














              Here's a way making use of Block to cause f to be inert:



              Block[{f},
              SetAttributes[f, HoldAllComplete];
              expr /. f[args__] :>
              RuleCondition[f[args] /. Print -> Echo]
              ]

              Hold[{f[{1, {Echo[1]}}], g[{{{Print[1]}}}]}]


              Note of course that this only works if you have a pattern of the form _Symbol[...]






              share|improve this answer


























                9














                Here's a way making use of Block to cause f to be inert:



                Block[{f},
                SetAttributes[f, HoldAllComplete];
                expr /. f[args__] :>
                RuleCondition[f[args] /. Print -> Echo]
                ]

                Hold[{f[{1, {Echo[1]}}], g[{{{Print[1]}}}]}]


                Note of course that this only works if you have a pattern of the form _Symbol[...]






                share|improve this answer
























                  9












                  9








                  9






                  Here's a way making use of Block to cause f to be inert:



                  Block[{f},
                  SetAttributes[f, HoldAllComplete];
                  expr /. f[args__] :>
                  RuleCondition[f[args] /. Print -> Echo]
                  ]

                  Hold[{f[{1, {Echo[1]}}], g[{{{Print[1]}}}]}]


                  Note of course that this only works if you have a pattern of the form _Symbol[...]






                  share|improve this answer












                  Here's a way making use of Block to cause f to be inert:



                  Block[{f},
                  SetAttributes[f, HoldAllComplete];
                  expr /. f[args__] :>
                  RuleCondition[f[args] /. Print -> Echo]
                  ]

                  Hold[{f[{1, {Echo[1]}}], g[{{{Print[1]}}}]}]


                  Note of course that this only works if you have a pattern of the form _Symbol[...]







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered yesterday









                  b3m2a1

                  26.9k257154




                  26.9k257154























                      8














                      I can think of one (ugly) way to do it:



                      Attributes[myHold] = {HoldAll};

                      expr /.
                      f[args__] :> With[
                      {res = myHold[args] /. Print -> Echo},
                      f @@ res /; True
                      ] /.
                      HoldPattern[f_ @@ myHold[args__]] :> f[args]
                      (* Hold[{f[{1, {Echo[1]}}], g[{{{Print[1]}}}]}] *)


                      The idea is to wrap the contents of f inside a function with HoldAll attribute (not Hold, to be able to identify it uniquely later on). In a first step, the expression is returned with myHold[…] still in place. In a second round of replacements, myHold is stripped out again.






                      share|improve this answer

















                      • 1




                        +1. If we use the vanishing macro defined in (43096), we can write vanishing[{h}, expr /. x_f :> RuleCondition[h[x] /. Print -> Echo]].
                        – WReach
                        yesterday
















                      8














                      I can think of one (ugly) way to do it:



                      Attributes[myHold] = {HoldAll};

                      expr /.
                      f[args__] :> With[
                      {res = myHold[args] /. Print -> Echo},
                      f @@ res /; True
                      ] /.
                      HoldPattern[f_ @@ myHold[args__]] :> f[args]
                      (* Hold[{f[{1, {Echo[1]}}], g[{{{Print[1]}}}]}] *)


                      The idea is to wrap the contents of f inside a function with HoldAll attribute (not Hold, to be able to identify it uniquely later on). In a first step, the expression is returned with myHold[…] still in place. In a second round of replacements, myHold is stripped out again.






                      share|improve this answer

















                      • 1




                        +1. If we use the vanishing macro defined in (43096), we can write vanishing[{h}, expr /. x_f :> RuleCondition[h[x] /. Print -> Echo]].
                        – WReach
                        yesterday














                      8












                      8








                      8






                      I can think of one (ugly) way to do it:



                      Attributes[myHold] = {HoldAll};

                      expr /.
                      f[args__] :> With[
                      {res = myHold[args] /. Print -> Echo},
                      f @@ res /; True
                      ] /.
                      HoldPattern[f_ @@ myHold[args__]] :> f[args]
                      (* Hold[{f[{1, {Echo[1]}}], g[{{{Print[1]}}}]}] *)


                      The idea is to wrap the contents of f inside a function with HoldAll attribute (not Hold, to be able to identify it uniquely later on). In a first step, the expression is returned with myHold[…] still in place. In a second round of replacements, myHold is stripped out again.






                      share|improve this answer












                      I can think of one (ugly) way to do it:



                      Attributes[myHold] = {HoldAll};

                      expr /.
                      f[args__] :> With[
                      {res = myHold[args] /. Print -> Echo},
                      f @@ res /; True
                      ] /.
                      HoldPattern[f_ @@ myHold[args__]] :> f[args]
                      (* Hold[{f[{1, {Echo[1]}}], g[{{{Print[1]}}}]}] *)


                      The idea is to wrap the contents of f inside a function with HoldAll attribute (not Hold, to be able to identify it uniquely later on). In a first step, the expression is returned with myHold[…] still in place. In a second round of replacements, myHold is stripped out again.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered yesterday









                      Lukas Lang

                      6,4351929




                      6,4351929








                      • 1




                        +1. If we use the vanishing macro defined in (43096), we can write vanishing[{h}, expr /. x_f :> RuleCondition[h[x] /. Print -> Echo]].
                        – WReach
                        yesterday














                      • 1




                        +1. If we use the vanishing macro defined in (43096), we can write vanishing[{h}, expr /. x_f :> RuleCondition[h[x] /. Print -> Echo]].
                        – WReach
                        yesterday








                      1




                      1




                      +1. If we use the vanishing macro defined in (43096), we can write vanishing[{h}, expr /. x_f :> RuleCondition[h[x] /. Print -> Echo]].
                      – WReach
                      yesterday




                      +1. If we use the vanishing macro defined in (43096), we can write vanishing[{h}, expr /. x_f :> RuleCondition[h[x] /. Print -> Echo]].
                      – WReach
                      yesterday











                      2














                      Alternatively:



                      expr /. 
                      foo_f :> RuleCondition[Hold[foo] /. Print -> Echo] /.
                      Hold[foo_f] :> foo





                      share|improve this answer


























                        2














                        Alternatively:



                        expr /. 
                        foo_f :> RuleCondition[Hold[foo] /. Print -> Echo] /.
                        Hold[foo_f] :> foo





                        share|improve this answer
























                          2












                          2








                          2






                          Alternatively:



                          expr /. 
                          foo_f :> RuleCondition[Hold[foo] /. Print -> Echo] /.
                          Hold[foo_f] :> foo





                          share|improve this answer












                          Alternatively:



                          expr /. 
                          foo_f :> RuleCondition[Hold[foo] /. Print -> Echo] /.
                          Hold[foo_f] :> foo






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered 10 hours ago









                          Kuba

                          103k12201516




                          103k12201516






























                              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%2f188887%2fperform-localized-evaluation-leak-free-replacements%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

                              How to make a Squid Proxy server?

                              Is this a new Fibonacci Identity?

                              19世紀