<div dir="ltr"><div class="gmail_default" style="font-family:tahoma,sans-serif">Consider</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">f x = letrec go y = case x of z { (a,b) -> ...(expensive z)... }</div><div class="gmail_default" style="font-family:tahoma,sans-serif">        in ...</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">If we do the reverse binder-swap we get</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">
<div class="gmail_default" style="font-family:tahoma,sans-serif">f x = letrec go y = case x of z { (a,b) -> ...(expensive x)... }</div><div class="gmail_default" style="font-family:tahoma,sans-serif">        in ...</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">and now we can float out:</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">
<div class="gmail_default" style="font-family:tahoma,sans-serif">f x = let t = expensive x</div><div class="gmail_default" style="font-family:tahoma,sans-serif">        in letrec go y = case x of z { (a,b) -> ...(t)... }</div><div class="gmail_default" style="font-family:tahoma,sans-serif">        in ...</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">Now (expensive x) is computed once, rather than once each time around the 'go' loop..</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">Would you like to elaborate the Note to explain this better?</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">Simon</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div>

</div>

</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 14 Jul 2023 at 16:30, Rodrigo Mesquita <<a href="mailto:rodrigo.m.mesquita@gmail.com">rodrigo.m.mesquita@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Dear GHC devs,<br>
<br>
I’m wondering about the reverse binder swap transformation, the one in which we substitute occurrences of the case binder by occurrences of the scrutinee (when the scrut. is a variable):<br>
<br>
        case x of z { r -> e }<br>
        ===><br>
        case x of z { r -> e[x/z] }<br>
<br>
My question is: why do we do this transformation? An example in which this transformation is beneficial would be great too.<br>
<br>
The Note I’ve found about it, Note [Binder-swap during float-out], wasn’t entirely clear to me:<br>
<br>
        4. Note [Binder-swap during float-out]<br>
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>
           In the expression<br>
                case x of wild { p -> ...wild... }<br>
           we substitute x for wild in the RHS of the case alternatives:<br>
                case x of wild { p -> ...x... }<br>
           This means that a sub-expression involving x is not "trapped" inside the RHS.<br>
           And it's not inconvenient because we already have a substitution.<br>
<br>
          Note that this is EXACTLY BACKWARDS from the what the simplifier does.<br>
          The simplifier tries to get rid of occurrences of x, in favour of wild,<br>
          in the hope that there will only be one remaining occurrence of x, namely<br>
          the scrutinee of the case, and we can inline it.<br>
<br>
Many thanks,<br>
Rodrigo<br>
<br>
_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br>
</blockquote></div>