Perform localized, evaluation-leak free replacements












9














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





























    9














    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



























      9












      9








      9


      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 yesterday









      Kuba

      103k12201517




      103k12201517










      asked 2 days ago









      Lukas LangLukas Lang

      6,4401929




      6,4401929






















          3 Answers
          3






          active

          oldest

          votes


















          10














          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














            [Edit: For most situations, @Kuba's answer is better]



            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



















            • 2




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



















            6














            Alternatively:



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


            We can safely perform the second replacement because we just wrapped every f[..] with Hold.






            share|improve this answer























            • +1 - In general, this is definitely better than my solution - the only potential issue is the fact that the pattern _f has to be written twice - so for complex patterns, this might lead to some code-duplication/performance cost
              – Lukas Lang
              yesterday










            • @LukasLang yes, consider this a quick solution to a specific problem. In general something like b3m2a1 shows is needed or a dummy vanishing head.
              – Kuba
              yesterday











            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









            10














            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


























              10














              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
























                10












                10








                10






                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 2 days ago









                b3m2a1b3m2a1

                26.9k257156




                26.9k257156























                    8














                    [Edit: For most situations, @Kuba's answer is better]



                    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



















                    • 2




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
















                    8














                    [Edit: For most situations, @Kuba's answer is better]



                    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



















                    • 2




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














                    8












                    8








                    8






                    [Edit: For most situations, @Kuba's answer is better]



                    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














                    [Edit: For most situations, @Kuba's answer is better]



                    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








                    edited yesterday

























                    answered 2 days ago









                    Lukas LangLukas Lang

                    6,4401929




                    6,4401929








                    • 2




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














                    • 2




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








                    2




                    2




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




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











                    6














                    Alternatively:



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


                    We can safely perform the second replacement because we just wrapped every f[..] with Hold.






                    share|improve this answer























                    • +1 - In general, this is definitely better than my solution - the only potential issue is the fact that the pattern _f has to be written twice - so for complex patterns, this might lead to some code-duplication/performance cost
                      – Lukas Lang
                      yesterday










                    • @LukasLang yes, consider this a quick solution to a specific problem. In general something like b3m2a1 shows is needed or a dummy vanishing head.
                      – Kuba
                      yesterday
















                    6














                    Alternatively:



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


                    We can safely perform the second replacement because we just wrapped every f[..] with Hold.






                    share|improve this answer























                    • +1 - In general, this is definitely better than my solution - the only potential issue is the fact that the pattern _f has to be written twice - so for complex patterns, this might lead to some code-duplication/performance cost
                      – Lukas Lang
                      yesterday










                    • @LukasLang yes, consider this a quick solution to a specific problem. In general something like b3m2a1 shows is needed or a dummy vanishing head.
                      – Kuba
                      yesterday














                    6












                    6








                    6






                    Alternatively:



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


                    We can safely perform the second replacement because we just wrapped every f[..] with Hold.






                    share|improve this answer














                    Alternatively:



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


                    We can safely perform the second replacement because we just wrapped every f[..] with Hold.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited yesterday

























                    answered yesterday









                    KubaKuba

                    103k12201517




                    103k12201517












                    • +1 - In general, this is definitely better than my solution - the only potential issue is the fact that the pattern _f has to be written twice - so for complex patterns, this might lead to some code-duplication/performance cost
                      – Lukas Lang
                      yesterday










                    • @LukasLang yes, consider this a quick solution to a specific problem. In general something like b3m2a1 shows is needed or a dummy vanishing head.
                      – Kuba
                      yesterday


















                    • +1 - In general, this is definitely better than my solution - the only potential issue is the fact that the pattern _f has to be written twice - so for complex patterns, this might lead to some code-duplication/performance cost
                      – Lukas Lang
                      yesterday










                    • @LukasLang yes, consider this a quick solution to a specific problem. In general something like b3m2a1 shows is needed or a dummy vanishing head.
                      – Kuba
                      yesterday
















                    +1 - In general, this is definitely better than my solution - the only potential issue is the fact that the pattern _f has to be written twice - so for complex patterns, this might lead to some code-duplication/performance cost
                    – Lukas Lang
                    yesterday




                    +1 - In general, this is definitely better than my solution - the only potential issue is the fact that the pattern _f has to be written twice - so for complex patterns, this might lead to some code-duplication/performance cost
                    – Lukas Lang
                    yesterday












                    @LukasLang yes, consider this a quick solution to a specific problem. In general something like b3m2a1 shows is needed or a dummy vanishing head.
                    – Kuba
                    yesterday




                    @LukasLang yes, consider this a quick solution to a specific problem. In general something like b3m2a1 shows is needed or a dummy vanishing head.
                    – Kuba
                    yesterday


















                    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

                    Mario Kart Wii

                    The Binding of Isaac: Rebirth/Afterbirth

                    What does “Dominus providebit” mean?