<div dir="ltr"><div>Alright, I opened an issue, <a href="https://gitlab.haskell.org/ghc/ghc/-/issues/20641">https://gitlab.haskell.org/ghc/ghc/-/issues/20641</a>, and I'll make an MR later.</div><div><br></div><div>Any objections if I change the implementation of<br></div><div><br></div><div>GHC.Core.Utils.eqExpr :: InScopeSet -> Expr -> Expr -> Bool</div><div><a href="https://gitlab.haskell.org/ghc/ghc/-/blob/master/compiler/GHC/Core/Utils.hs#L2124">https://gitlab.haskell.org/ghc/ghc/-/blob/master/compiler/GHC/Core/Utils.hs#L2124</a></div><div><br></div><div>to</div><div><br></div><div>eqExpr _ e1 e2 = deBruijnize e1 == deBruijnize e2</div><div><br></div><div>and at the same time mark it deprecated telling people to use deBruijnize?</div><div>(I don't want to remove it since GHC API users might be using it)<br></div><div><br></div><div>`eqExpr` also does alpha-equivalence on CoreExpr, and has the same mistake w.r.t. alpha-equivalence as the `Eq (DeBruijn CoreExpr)` instance</div><div><br></div><div>-- Christiaan<br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 8 Nov 2021 at 13:02, Simon Peyton Jones <<a href="mailto:simonpj@microsoft.com">simonpj@microsoft.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">





<div style="overflow-wrap: break-word;" lang="EN-GB">
<div class="gmail-m_-5516312183001425527WordSection1">
<p class="MsoNormal"><span>Huh!  Dead right!<u></u><u></u></span></p>
<p class="MsoNormal"><span><u></u> <u></u></span></p>
<p class="MsoNormal"><span>Would you like to:<u></u><u></u></span></p>
<ul style="margin-top:0cm" type="disc">
<li class="gmail-m_-5516312183001425527MsoListParagraph" style="margin-left:0cm"><span>Open a ticket (you can use the text from this email)<u></u><u></u></span></li><li class="gmail-m_-5516312183001425527MsoListParagraph" style="margin-left:0cm"><span>Submit a MR?
<u></u><u></u></span></li></ul>
<p class="MsoNormal"><span><u></u> <u></u></span></p>
<p class="MsoNormal"><span>On the MR,<u></u><u></u></span></p>
<ul style="margin-top:0cm" type="disc">
<li class="gmail-m_-5516312183001425527MsoListParagraph" style="margin-left:0cm"><span>Add a Note that again gives your killer example; and mention why we don’t need the check for NonRec<u></u><u></u></span></li><li class="gmail-m_-5516312183001425527MsoListParagraph" style="margin-left:0cm"><span>Worth also pointing out that letrec { x = e1; y = e2 } in b is NOT considered equal to letrec { y = e1; x = e1 } in b.   Nor are let x=e1 in
 let y = e2 in b   considered equal to  let y = e1 in let x = e1 in b.   This is fine; but worth pointing out.<u></u><u></u></span></li></ul>
<p class="MsoNormal"><span><u></u> <u></u></span></p>
<p class="MsoNormal"><span>Thanks for pointing this out!<u></u><u></u></span></p>
<p class="MsoNormal"><span><u></u> <u></u></span></p>
<p class="MsoNormal"><span>Simon<u></u><u></u></span></p>
<p class="MsoNormal"><span><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:8pt">PS: I am leaving Microsoft at the end of November 2021, at which point
<a href="mailto:simonpj@microsoft.com" target="_blank"><span style="color:rgb(5,99,193)">simonpj@microsoft.com</span></a> will cease to work.  Use
<a href="mailto:simon.peytonjones@gmail.com" target="_blank"><span style="color:rgb(5,99,193)">simon.peytonjones@gmail.com</span></a> instead.  (For now, it just forwards to <a href="mailto:simonpj@microsoft.com" target="_blank">simonpj@microsoft.com</a>.)<u></u><u></u></span></p>
<p class="MsoNormal"><span><u></u> <u></u></span></p>
<div style="border-color:currentcolor currentcolor currentcolor blue;border-style:none none none solid;border-width:medium medium medium 1.5pt;padding:0cm 0cm 0cm 4pt">
<div>
<div style="border-color:rgb(225,225,225) currentcolor currentcolor;border-style:solid none none;border-width:1pt medium medium;padding:3pt 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US">From:</span></b><span lang="EN-US"> ghc-devs <<a href="mailto:ghc-devs-bounces@haskell.org" target="_blank">ghc-devs-bounces@haskell.org</a>>
<b>On Behalf Of </b>Christiaan Baaij<br>
<b>Sent:</b> 07 November 2021 21:08<br>
<b>To:</b> ghc-devs <<a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a>><br>
<b>Subject:</b> Alpha-equivalence for recursive let-bindings<u></u><u></u></span></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
Hi list,<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
<u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
I was looking at the `Eq (DeBruijn CoreExpr)` instance and I noticed that the types of recursive let-bindings aren't checked for alpha-equivalence:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
<u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
<a href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.haskell.org%2Fghc%2Fghc%2F-%2Fblob%2Fmaster%2Fcompiler%2FGHC%2FCore%2FMap%2FExpr.hs%23L166-174&data=04%7C01%7Csimonpj%40microsoft.com%7C4e4f1afdc4d64d66f2ef08d9a232bca8%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637719161836942634%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=6TGl3MHDSGLyUFjfMwce13K%2FVprCl7YRMQnRGrJj%2BAI%3D&reserved=0" target="_blank">https://gitlab.haskell.org/ghc/ghc/-/blob/master/compiler/GHC/Core/Map/Expr.hs#L166-174</a><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
<u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
    go (Let (Rec ps1) e1) (Let (Rec ps2) e2)<br>
      = equalLength ps1 ps2<br>
      && D env1' rs1 == D env2' rs2<br>
      && D env1' e1  == D env2' e2<br>
      where<br>
        (bs1,rs1) = unzip ps1<br>
        (bs2,rs2) = unzip ps2<br>
        env1' = extendCMEs env1 bs1<br>
        env2' = extendCMEs env2 bs2<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
<u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:12pt;margin-left:0cm">
But doesn't that mean that:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:12pt;margin-left:0cm">
let (x :: Int) = x in x <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:12pt;margin-left:0cm">
and <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:12pt;margin-left:0cm">
let (y :: Bool) = y in y<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
are considered alpha-equivalent?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
If that is the case, then I think that's wrong. Agree?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
I understand that you don't have to check types for non-recursive let-bindings: when the RHSs match, the types must be the same.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
<u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
-- Christiaan<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
<u></u> <u></u></p>
</div>
</div>
</div>
</div>
</div>

</blockquote></div>