<div dir="ltr"><div><font face="arial, helvetica, sans-serif"><div>Before all this, we may need to discuss a bit about the intended semantics of</div><div>`Outputable`: does it need to print `PostRn`, or `PostTc` fields; or `Out`</div><div>suffixed constructors?  If not, then we only need to write a set of instances</div><div>for the base growable AST, once and for all.  Such instances will be polymorphic</div><div>on the extension descriptor `p`, and do not need to mention the constraints like</div><div>`(PostRn p (IdP p)`, since these are just extensions and not part of the base</div><div>growable AST.  Or, am I missing something about the intended semantics of</div><div>`Outputable`?</div><div style="font-size:12px"><br></div></font></div><div><font face="arial, helvetica, sans-serif">You write</font></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">So today we never print these annotations, to avoid bloating the instance contexts, which can be painful. <br></blockquote></div><div><font face="Courier New"><span style="font-size:12px"><br></span></font></div><div><span style="font-size:12px"><font face="arial, helvetica, sans-serif">I have been under the impression that we don't even want to print those.</font></span></div><div><br></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px">Of course, there are scenarios (like `Show` instances) where we do want to write </span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px">compositional / generic functions that take into account the extensions.</span><br></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px">Here is my abstract overview of the scenario, that may help the discussion.</span></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12px">Consider </span></font><span style="font-family:arial,helvetica,sans-serif;font-size:12px">data types `A`, `B`, and `C` (say, one AST datatype per compiler phase) that</span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px"> are defined as extensions to a base datatype `T`:</span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px"><br></span></div><div><span style="font-size:12px"><font face="monospace, monospace">> A = T XA</font></span></div><div><span style="font-size:12px"><font face="monospace, monospace">> B = T XB</font></span></div><div><span style="font-size:12px"><font face="monospace, monospace">> C = T XC</font></span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px">where `</span><span style="font-size:12px"><font face="monospace, monospace">X*</font></span><span style="font-family:arial,helvetica,sans-serif;font-size:12px">`s are extension descriptors.</span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px">Now, say we want to a define functions `</span><span style="font-size:12px"><font face="monospace, monospace">f_A</font></span><span style="font-family:arial,helvetica,sans-serif;font-size:12px">`, `</span><span style="font-size:12px"><font face="monospace, monospace">f_B</font></span><span style="font-family:arial,helvetica,sans-serif;font-size:12px">`, and `</span><span style="font-size:12px"><font face="monospace, monospace">f_C</font></span><span style="font-family:arial,helvetica,sans-serif;font-size:12px">` over `</span><span style="font-size:12px"><font face="monospace, monospace">A</font></span><span style="font-family:arial,helvetica,sans-serif;font-size:12px">`, `</span><span style="font-size:12px"><font face="monospace, monospace">B</font></span><span style="font-family:arial,helvetica,sans-serif;font-size:12px">`, and `</span><span style="font-size:12px"><font face="monospace, monospace">C</font></span><span style="font-family:arial,helvetica,sans-serif;font-size:12px">`.</span></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12px">We have two main alternatives: </span></font></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12px">(a) either we write these  (</span></font><span style="font-family:arial,helvetica,sans-serif;font-size:12px">manually </span><span style="font-size:12px;font-family:arial,helvetica,sans-serif">or using the deriving mechanism</span><span style="font-size:12px;font-family:arial,helvetica,sans-serif">) separately</span></div><div><span style="font-size:12px;font-family:arial,helvetica,sans-serif">(b) or we write a generic / parametric function `</span><span style="font-size:12px"><font face="monospace, monospace">g</font></span><span style="font-size:12px;font-family:arial,helvetica,sans-serif">` over `</span><span style="font-size:12px"><font face="monospace, monospace">T</font></span><span style="font-size:12px;font-family:arial,helvetica,sans-serif">`, and reuse that to define `</span><span style="font-size:12px"><font face="monospace, monospace">f_*</font></span><span style="font-size:12px;font-family:arial,helvetica,sans-serif">`s</span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px">Of course, (b) is preferable </span><span style="font-family:arial,helvetica,sans-serif;font-size:12px">in theory</span><span style="font-family:arial,helvetica,sans-serif;font-size:12px"> </span><span style="font-family:arial,helvetica,sans-serif;font-size:12px">, but not always possible or preferable in practice.</span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px">In which case, we can always resort to (a).</span></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12px">The more varying are the definitions of `f_A`, `f_B`, and `f_C` the more parametric should </span></font></div><div><font face="arial, helvetica, sans-serif"><span style="font-size:12px">`g` get, as this is the case for any generic function.</span></font></div><div><br></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px">With a correct design, I believe, these are all independent of Trees that Grow story itself:</span><span style="font-family:arial,helvetica,sans-serif;font-size:12px"> </span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px">we are now not only trying to reuse data types, and functions agnostic towards extensions</span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px">(pretty printers in my view of their semantics), but also reuse functions with </span><span style="font-family:arial,helvetica,sans-serif;font-size:12px">parametric / </span></div><div><span style="font-family:arial,helvetica,sans-serif;font-size:12px">varying behaviour with respect to extensions. </span></div><div><br></div><div>/Shayan</div><div><font face="Courier New"><span style="font-size:12px"><br></span></font></div><div><font face="Courier New"><span style="font-size:12px"><br></span></font></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jul 28, 2017 at 10:18 AM, 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div lang="EN-GB" link="#0563C1" vlink="#954F72">
<div class="m_-525007982728833755WordSection1">
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">Devs,<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">Shayan is working away on “Trees that grow”… do keep it on your radar:<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" style="margin-left:36.0pt"><b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif">To:</span></b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif"> ghc-devs
<br>
<b>Sent:</b> 25 May 2017 23:49<br>
<br>
</span><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><u></u><u></u></span></p>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">Do take a look at this:<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="m_-525007982728833755MsoListParagraph" style="margin-left:72.0pt">
<u></u><span style="font-size:11.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">We propose to re-engineer HsSyn itself.  This will touch a
<b>lot</b> of code.<u></u><u></u></span></p>
<p class="m_-525007982728833755MsoListParagraph" style="margin-left:72.0pt">
<u></u><span style="font-size:11.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">But it’s very neat, and will bring big long-term advantages<u></u><u></u></span></p>
<p class="m_-525007982728833755MsoListParagraph" style="margin-left:72.0pt">
<u></u><span style="font-size:11.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">And we can do it a bit at a time<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">The wiki page
</span><a href="https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow" target="_blank">https://ghc.haskell.org/trac/<wbr>ghc/wiki/<wbr>ImplementingTreesThatGrow</a>
<span style="font-size:11.0pt;font-family:"Calibri",sans-serif">
has the details.</span>  <a name="m_-525007982728833755__MailEndCompose">I</a><span><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">t’s entirely an internal change, not a change to GHC’s specification,
 so it’s independent of the GHC proposals process.  But I’d value the opinion of other GHC devs</span></span><u></u><u></u></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">Meanwhile I have a question. When pretty-printing HsSyn we often have a situation like this:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="m_-525007982728833755Code">  data Pass = Parsed | Renamed | Typechecked<u></u><u></u></p>
<p class="m_-525007982728833755Code"><u></u> <u></u></p>
<p class="m_-525007982728833755Code">  data HsExpr (p :: Pass) = HsVar (IdP p) | ....<u></u><u></u></p>
<p class="m_-525007982728833755Code"><u></u> <u></u></p>
<p class="m_-525007982728833755Code">  type famliy IdP p where<u></u><u></u></p>
<p class="m_-525007982728833755Code">     IdP Parsed      = RdrName<u></u><u></u></p>
<p class="m_-525007982728833755Code">     IdP Renamed     = Name<u></u><u></u></p>
<p class="m_-525007982728833755Code">     IdP Typechecked = Id<u></u><u></u></p>
<p class="m_-525007982728833755Code"><u></u> <u></u></p>
<p class="m_-525007982728833755Code">  instance (Outputable (IdP p)) => Outputable (HsExpr p) where<u></u><u></u></p>
<p class="m_-525007982728833755Code">     ppr (HsVar v) = ppr v<u></u><u></u></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">The (ppr v) requires (Outputable (IdP p)), hence the context.<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">Moreover, and more seriously, there are things we just can't pretty-print<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">right now.  For example, HsExpr has this data constructor:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="m_-525007982728833755Code">  data HsExpr p = ...<u></u><u></u></p>
<p class="m_-525007982728833755Code">    | OpApp       (LHsExpr p)<u></u><u></u></p>
<p class="m_-525007982728833755Code">                  (LHsExpr p)<u></u><u></u></p>
<p class="m_-525007982728833755Code">                  (PostRn p Fixity)<u></u><u></u></p>
<p class="m_-525007982728833755Code">                  (LHsExpr p)<u></u><u></u></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">To pretty-print the third argument, we'd need to add<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="m_-525007982728833755Code">  instance (Outputable (IdP p),<u></u><u></u></p>
<p class="m_-525007982728833755Code">            Outputable (PostRn p Fixity))   -- New<u></u><u></u></p>
<p class="m_-525007982728833755Code">        => Outputable (HsExpr p) where<u></u><u></u></p>
<p class="m_-525007982728833755Code">     ppr (HsVar v) = ppr v<u></u><u></u></p>
<p class="m_-525007982728833755Code"><u></u> <u></u></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">and that gets onerous. 
<i>So today we never print these annotations</i>, to avoid bloating the instance contexts, which can be painful.  It bit me yesterday.<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">We have bitten that bullet for the Data class: look at HsExtension.DataId, which abbreviates the long list of dictionaries:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="m_-525007982728833755Code">  type DataId p =<u></u><u></u></p>
<p class="m_-525007982728833755Code">    ( Data p<u></u><u></u></p>
<p class="m_-525007982728833755Code">    , ForallX Data p<u></u><u></u></p>
<p class="m_-525007982728833755Code">    , Data (NameOrRdrName (IdP p))<u></u><u></u></p>
<p class="m_-525007982728833755Code">    , Data (IdP p)<u></u><u></u></p>
<p class="m_-525007982728833755Code">    , Data (PostRn p (IdP p))<u></u><u></u></p>
<p class="m_-525007982728833755Code">    , Data (PostRn p (Located Name))<u></u><u></u></p>
<p class="m_-525007982728833755Code">    , Data (PostRn p Bool)<u></u><u></u></p>
<p class="m_-525007982728833755Code">    , Data (PostRn p Fixity)<u></u><u></u></p>
<p class="m_-525007982728833755Code">     ,..and nine more... )<u></u><u></u></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">Let me note in passing that [<a href="https://ghc.haskell.org/trac/ghc/wiki/QuantifiedContexts" target="_blank">wiki:QuantifiedContexts</a>] would make this somewhat shorter<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="m_-525007982728833755Code">  type DataId p =<u></u><u></u></p>
<p class="m_-525007982728833755Code">    ( Data p<u></u><u></u></p>
<p class="m_-525007982728833755Code">    , ForallX Data p<u></u><u></u></p>
<p class="m_-525007982728833755Code">    , Data (NameOrRdrName (IdP p))<u></u><u></u></p>
<p class="m_-525007982728833755Code">    , Data (IdP p)<u></u><u></u></p>
<p class="m_-525007982728833755Code">    , forall t. Data t => Data (PostRn p t))<u></u><u></u></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">But we still need one item in this list for each type function,<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">and I am worried about how this scales to the<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">[<a href="https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow" target="_blank">wiki:<wbr>ImplementingTreesThatGrow</a>] story, when we have a type<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">function for each data constructor -- and there are a
<b>lot</b> of data<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">constructors.<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"><b><span style="font-family:"Calibri",sans-serif">So I have four questions<u></u><u></u></span></b></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<ol style="margin-top:0cm" start="1" type="1">
<li class="m_-525007982728833755MsoListParagraph" style="margin-left:0cm"><span style="font-family:"Calibri",sans-serif">I think we should probably use a superclass instead of a type synonym<u></u><u></u></span></li></ol>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="m_-525007982728833755Code">class (Data p, ForallX Data p, ....) => DataId p where {}<u></u><u></u></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="m_-525007982728833755MsoListParagraph"><span style="font-family:"Calibri",sans-serif">Why?  Only one argument to pass, and to pass on to successive calls.  I see no downside.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<ol style="margin-top:0cm" start="2" type="1">
<li class="m_-525007982728833755MsoListParagraph" style="margin-left:0cm"><span style="font-family:"Calibri",sans-serif">Shall we treat Outputable like Data?  (I.e. make an abbreviation for a long list of Outputable instances and use it everywhere)<br>
<br>
<u></u><u></u></span></li><li class="m_-525007982728833755MsoListParagraph" style="margin-left:0cm"><span style="font-family:"Calibri",sans-serif">I thought of another way to do it (pass a token); see below<u></u><u></u></span></li></ol>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<ol style="margin-top:0cm" start="4" type="1">
<li class="m_-525007982728833755MsoListParagraph" style="margin-left:0cm"><span style="font-family:"Calibri",sans-serif">Are there any other ways?<u></u><u></u></span></li></ol>
<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"><u></u> <u></u></span></p>
<p class="MsoNormal"><b><span style="font-family:"Calibri",sans-serif">Token passing idea.<u></u><u></u></span></b></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">Perhaps instead of passing lots of functions, we pass a singleton token<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">that encodes the pass, like this:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="m_-525007982728833755Code">  instance (PassC p) => Outputable (HsExpr p) where<u></u><u></u></p>
<p class="m_-525007982728833755Code">     ppr (HsVar v) = case getPass :: IsPass p of<u></u><u></u></p>
<p class="m_-525007982728833755Code">                       IsParsed      -> ppr v<u></u><u></u></p>
<p class="m_-525007982728833755Code">                       <wbr>IsRenamed     -> ppr v<u></u><u></u></p>
<p class="m_-525007982728833755Code">                       IsTypechecked -> ppr v<u></u><u></u></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">The three ppr's are at different types, of course; that's the point.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">The infrastructure is something like<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif"><u></u> <u></u></span></p>
<p class="m_-525007982728833755Code">  class PassC p where<u></u><u></u></p>
<p class="m_-525007982728833755Code">    getPass :: IsPass p<u></u><u></u></p>
<p class="m_-525007982728833755Code"><u></u> <u></u></p>
<p class="m_-525007982728833755Code">  data IsPass p where<u></u><u></u></p>
<p class="m_-525007982728833755Code">    IsParsed      :: IsPass Parsed<u></u><u></u></p>
<p class="m_-525007982728833755Code">    IsRenamed     :: IsParsed Renamed<u></u><u></u></p>
<p class="m_-525007982728833755Code">    IsTypechecked :: IsParsed Typechecked<u></u><u></u></p>
<p class="m_-525007982728833755Code"><u></u> <u></u></p>
<p class="m_-525007982728833755Code">  instance PassC Parsed where getPass = IsParsed<u></u><u></u></p>
<p class="m_-525007982728833755Code">    ...etc...<u></u><u></u></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">Now we could sweep away all those OutputableX classes,<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">replacing them with dynamic tests on the singletons IsParsed etc.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">This would have advantages:<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">- Probably faster: there's a dynamic test, but many fewer dictionary<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">  arguments and higher-order function dispatch<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">- Only one dictionary to pass; programming is easier.<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">The big downside is that it's not extensible: it works only because<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">we know the three cases.  But the "Trees that Grow" story really doesn't<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif">scale well to pretty-printing: so maybe we should just give up on that?<u></u><u></u></span></p>
</div>
</div>

</blockquote></div><br></div>