<div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">(1)-(3) appears to be three different approaches, but I don’t think that’s what you intend. I think there are only two: add the indirection layer or not?</blockquote><div><br></div><div>(1)-(3) are just steps when we do choose to add the indirection layer: add the layer, and do the changes when desired.<br></div><div>If we choose to not to add the indirection layer, nothing needs to be changed and the internals of the encoding (`PostTc`, place holders, etc) remain visible in the code.</div><div><br></div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Can you give an example function or two, and what it would look like under the different approaches. </blockquote></div><div> </div><div>For example, the function clause </div><div><br></div><div><div><font face="monospace, monospace">> rnExpr (HsMultiIf _ty alts)</font></div><div><font face="monospace, monospace">> = do { (alts', fvs) <- mapFvRn (rnGRHS IfAlt rnLExpr) alts</font></div><div><font face="monospace, monospace">> ; return (HsMultiIf placeHolderType alts', fvs) }</font><br></div></div><div><br></div><div>becomes</div><div><font face="monospace, monospace"><br></font></div><div><div><font face="monospace, monospace">> rnExpr (PsMultiIf alts)</font></div><div><font face="monospace, monospace">> = do { (alts', fvs) <- mapFvRn (rnGRHS IfAlt rnLExpr) alts</font></div><div><font face="monospace, monospace">> ; return (RnMultiIf alts', fvs) }</font><br></div></div><div><br></div><div>I hope it clarifies what I mean a bit.</div><div><br></div><div>There is always a choice between how distinct we want the phases to be. </div><div>The more distinct they are, the higher static guarantees. The code also gets more clear in a way, e.g. `RnMultiIf` is talking about a renamed expression, `PsMultiIf` about a parsed expression, while `HsMultiIf` is talking about an expression of any phase. </div><div>At the same, distinctness means more work for the programmer.</div><div>Also, such distinction sometimes implies a pedagogic burdon, as readers should now learn about more than one AST. However, this burden is very low here thanks to the prefixing convention: `PsMultiIf` and `RnMultiIf` are easily understood to represent the same thing in different phases.</div><div>Finally, such distinctions often lead to code duplication. But in our case, Trees that Grow machinery saves us from such duplication, e.g., we have the same base ASTs and we can write generic programmers over the bases ASTs anytime we want (point/step (3) above).</div><div><br></div><div>Thanks,</div><div> Shayan</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Aug 24, 2017 at 3:35 PM, Simon Peyton Jones <span dir="ltr"><<a href="mailto:simonpj@microsoft.com" target="_blank">simonpj@microsoft.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div lang="EN-GB">
<div class="gmail-m_-6189599188785556465WordSection1">
<p class="MsoNormal"><span style="font-family:Calibri,sans-serif">I’m keen NOT to introduce these layers of indirection. I think they make the code harder to understand.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:Calibri,sans-serif"><br>
Can you give an example function or two, and what it would look like under the different approaches.
<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-family:Calibri,sans-serif">(1)-(3) appears to be three different approaches, but I don’t think that’s what you intend. I think there are only two: add the indirection layer or not?<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-family:Calibri,sans-serif">S<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<div style="border-top:none;border-right:none;border-bottom:none;border-left:1.5pt solid blue;padding:0cm 0cm 0cm 4pt">
<div>
<div style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(225,225,225);padding:3pt 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US" style="font-size:11pt;font-family:Calibri,sans-serif">From:</span></b><span lang="EN-US" style="font-size:11pt;font-family:Calibri,sans-serif"> Shayan Najd [mailto:<a href="mailto:sh.najd@gmail.com" target="_blank">sh.najd@gmail.com</a>]
<br>
<b>Sent:</b> 23 August 2017 13:26<br>
<b>To:</b> <a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a><br>
<b>Cc:</b> Simon Peyton Jones <<a href="mailto:simonpj@microsoft.com" target="_blank">simonpj@microsoft.com</a>>; Alan & Kim Zimmerman <<a href="mailto:alan.zimm@gmail.com" target="_blank">alan.zimm@gmail.com</a>><br>
<b>Subject:</b> Discussion: Static Safety via Distinct Interfaces for HsSyn ASTs<u></u><u></u></span></p>
</div>
</div><div><div class="gmail-h5">
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
In this thread, I am going to raise a topic for discussion. Please share your opinions and related experiences.<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">
Evaluation of type families within HsSyn ASTs, such as `<span style="font-family:"Courier New"">PostTc</span>`, with a fixed phase index, such as `<span style="font-family:"Courier New"">GhcPs</span>`, gives us distinct ASTs at the *compile-time*.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
However, when programming with these ASTs, we use patterns, such as `<span style="font-family:"Courier New"">HsMultiIf :: PostTc p Type -> [LGRHS p (LHsExpr p)] -> HsExpr p</span>` that are shared among phases.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
We can <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
(1) introduce a layer of abstraction providing a set of type and pattern synonyms specific to each phase, such as `<span style="font-family:"Courier New"">PsMultiIf :: [LPsGRHS LPsExpr] -> PsExpr</span>`; and<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
(2) updating code working on ASTs of specific phase to use the interface specific to the phase, such as by changing prefixes from `Hs` to `Ps` and by removing unused variables and placeholders; and<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
(3) leaving untouched code working uniformly on ASTs of different phases (i.e., the generic functions in Trees that Grow terminology), such as the existing functions whose types are polymorphic on phase index. <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">
Some comments:<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">
- It can be done gradually and smoothly: we add three separate files in HsSyn (per each phase) containing the phase-specific interfaces, and gradually import them and do the changes per module.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
- Using the interfaces is optional: code using the current method (e.g., using `<span style="font-family:"Courier New"">HsMultiIf</span>`) should work just fine.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
- It introduces a layer of indirection and three more files to maintain. <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
- It makes code working on HsSyn ASTs, such as the renamer, appear cleaner as placeholders and similar machinery are abstracted away by the interfaces (e.g., no need to import bits and pieces of `<span style="font-family:"Courier New"">HsExtension</span>`)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
- In theory, there should be zero impact on GHC's runtime performance. <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 am myself undecided about its benefit-cost ratio, but willing to at least implement the phase-specific interfaces.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
For me, abstracting away all the `PostRn` stuff, `Out` prefixed constructors, and dummy placeholders from the front-end code is the most valuable.<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">
Yours, <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
Shayan<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">
<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">
<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">
<u></u> <u></u></p>
<div>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6pt;margin-left:0cm">
<u></u><u></u></p>
</div>
</div>
</div>
</div></div></div>
</div>
</div>
</blockquote></div><br></div></div>