<div dir="ltr">Simon, <div><br></div><div>Back to your original questions:</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">1. I think we should probably use a superclass instead of a type synonym<br> <br>class (Data p, ForallX Data p, ....) => DataId p where {}<br> <br>Why?  Only one argument to pass, and to pass on to successive calls.  I see no downside.</blockquote></div><div><br></div><div>Sounds good to me. I have not experimented with it yet, but I see no downside as well.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Shall we treat Outputable like Data?  (I.e. make an abbreviation for a long list of Outputable instances and use it everywhere)</blockquote><div><br></div><div>Besides, the above point about semantics and reusing it as classical pretty-printer, I suggest a bit more fine-grained abbreviations, if we are going along this path:</div><div> we define the abbreviations per datatype (as opposed to all), we define `ForallXNAME :: constraint -> *` (as in Section 3.7 of the paper) where `NAME` is name of the datatype.</div><div><br></div><div>However, we do NOT need Trees that Grow in its full generality: as far as I understand, we do not have GADTs or existentials in GHC ASTs.</div><div>This means we can use the simpler design of Trees that Grow that all extension families had the same arity and kind, then we could factor them all into one type family dispatching on some unique identifier.</div><div>(we used type-level strings, or promoted datatypes for annotations.)</div><div><br></div><div>For example, the following in absence of existentials</div><div><br></div><div><font face="monospace, monospace">> type family XVar x a</font></div><div><font face="monospace, monospace">> type family XApp x a</font></div><div><font face="monospace, monospace">> type family XAbs x a</font></div><div><font face="monospace, monospace">> data Exp x a </font></div><div><font face="monospace, monospace">>  = Var (XVar x a) a</font></div><div><font face="monospace, monospace">>  | Abs (XAbs x a) a (Exp x a)</font></div><div><font face="monospace, monospace">>  | App (XApp x a) (Exp x a) (Exp x a)</font></div><div> </div><div>is as good as (one of our very first extensible encodings)</div><div><br></div><div><div><font face="monospace, monospace">> type family XDispatch name x a</font></div><div><div><font face="monospace, monospace">> data Lbl = VarL | AbsL | AppL</font></div></div><div><span style="font-family:monospace,monospace">> data Exp x a </span><br></div><div><font face="monospace, monospace">>  = Var (</font><span style="font-family:monospace,monospace">XDispatch VarL</span><span style="font-family:monospace,monospace"> x a) a</span></div><div><font face="monospace, monospace">>  | Abs (XDispatch AbsL x a) a (Exp x a)</font></div><div><font face="monospace, monospace">>  | App (XDispatch AppL x a) (Exp x a) (Exp x a)</font></div></div><div><font face="monospace, monospace"><br></font></div><div><font face="arial, helvetica, sans-serif">We could do the same with promoted datatypes as annotations (instead of type-level strings).</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">The advantage of the simpler encoding is that now, in theory, we can define</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">> ForallXExp (c :: Constraint) x a = forall l. c (XDispatch l x a)</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">Which gives us for example `</font><span style="font-family:arial,helvetica,sans-serif">ForallXExp Outputable x a `.</span></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">Is this encoding faster, in comparison? </span><span style="font-family:arial,helvetica,sans-serif">Does it help?</span></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">/Shayan</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jul 28, 2017 at 10:11 PM, Shayan Najd <span dir="ltr"><<a href="mailto:sh.najd@gmail.com" target="_blank">sh.najd@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><span style="font-size:12.8px">MarLinn,</span><br></div>   Thanks for correcting me, and spelling this out. <div>   I did mean what Alan mentioned: "re-parsing a pretty printed parse tree gives you back a parse tree identical to the original (ignoring SrcSpans)".<div><div>   As I recall, we had to go a bit further to give 'Something' some more structure to take into account things like "(ignoring SrcSpans)" (e.g., to define exact-printers, etc).</div><div>   Provided I have failed twice to properly recall the invariant, I refrain from trying to recall the rest tonight :) </div><div><br></div><div>Not diverging from my point above, as far as I understand, an ideal `Outputable` machinery is going to be a bit different from the traditional pretty printers.</div><div>I believe with a proper design we can even reuse `Outputable` machinery and provide it as a pretty printer for Haskell terms.</div><div>It resembles the scenario in Section 3.7 compared to Section 3.6 of Trees that Grow [1].     </div><div> </div><div>Having said all these, we ARE diverging from the original thread, and Simon's questions. </div><div><br></div><div>How about taking printer-design related discussion to the following wiki page (and/or a new ghc-dev thread if needed):</div><div>  <a href="https://ghc.haskell.org/trac/ghc/wiki/HaskellSyntaxPrinters" target="_blank">https://ghc.haskell.org/<wbr>trac/ghc/wiki/<wbr>HaskellSyntaxPrinters</a> </div><div><br></div><div>Cheers,</div><div>  Shayan</div><div><br></div><div>[1] <a href="http://www.jucs.org/jucs_23_1/trees_that_grow/jucs_23_01_0042_0062_najd.pdf" target="_blank">http://www.jucs.org/jucs_<wbr>23_1/trees_that_grow/jucs_23_<wbr>01_0042_0062_najd.pdf</a></div><div><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jul 28, 2017 at 8:43 PM, Alan & Kim Zimmerman <span dir="ltr"><<a href="mailto:alan.zimm@gmail.com" target="_blank">alan.zimm@gmail.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 dir="ltr"><div><div>I agree. 4 is the current GHC invariant.<br><br></div>i.e., re-parsing a pretty printed parse tree gives you back a parse tree identical to the original (ignoring SrcSpans)<br><br></div>Alan<br></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="m_3003089608480862801gmail-m_6977670093198868773h5">On 28 July 2017 at 20:34, MarLinn <span dir="ltr"><<a href="mailto:monkleyon@gmail.com" target="_blank">monkleyon@gmail.com</a>></span> wrote:<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"><div><div class="m_3003089608480862801gmail-m_6977670093198868773h5">
  
    
  
  <div bgcolor="#FFFFFF"><span>
    <blockquote type="cite">
      <p>by</p>
      <blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
        <pre> (parser . prettyPrint . parser) = id  </pre>
      </blockquote>
      <p>I meant </p>
      <pre>(prettyPrint . parser . prettyPrint) = id</pre>
      <p>for a valid input.</p>
    </blockquote>
    </span><p>Simplifying, <tt>(parser ∷ String → something)</tt>, and <tt>(prettyPrint
        ∷ something → String)</tt>.</p>
    <p>Therefore, <tt>(parser . prettyPrint . parser ∷ String →
        something)</tt> and <tt>(prettyPrint . parser . prettyPrint ∷
        something → String)</tt>.</p>
    <p>Therefore, both criteria could only apply for <tt>(something ~
        String)</tt>. But as pretty printing adds quotation marks, not
      even that is true.</p>
    <p>There are four formulations that might be applicable:</p>
    <ol>
      <li>
        <p> <tt>parser . prettyPrint ≍ id <br>
          </tt></p>
      </li>
      <li>
        <p><tt>prettyPrint . parser </tt><tt><tt>≍</tt> id -- ∷ String
            → String, useless here<br>
          </tt></p>
      </li>
      <li>
        <p> <tt>prettyPrint . parser . </tt><tt><tt>prettyPrint</tt> </tt><tt><tt>≍</tt>
          </tt><tt>prettyPrint</tt></p>
      </li>
      <li>
        <p><tt>parser . prettyPrint . parser </tt><tt><tt>≍</tt> </tt><tt>parser</tt></p>
      </li>
      <li>Well, you could go beyond to <tt>(</tt><tt>prettyPrint .
          parser . </tt><tt>prettyPrint</tt><tt> . pa</tt><tt>rser </tt><tt>≍</tt><tt>
        </tt><tt>prettyPrint</tt><tt> . </tt><tt>parser</tt><tt>)</tt>
        etc…<br>
      </li>
    </ol>
    <p>I don't think 1 (or 2) follow from one of the last two. But 1
      does imply them. So it is a stronger criterion than both, and
      therefore probably not the one to choose. Assuming the parser is
      internally consistent, 3 just says something about the internal
      consistency of the pretty printer, while 4 says something about
      the relationship of the pretty printer to the parser. Thus 4 looks
      like the best candidate for a criterion. Possibly with 3 as a
      secondary target.</p>
    <p>Cheers,<br>
      MarLinn</p>
  </div>

<br></div></div>______________________________<wbr>_________________<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-bi<wbr>n/mailman/listinfo/ghc-devs</a><br>
<br></blockquote></div><br></div>
<br>______________________________<wbr>_________________<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-bi<wbr>n/mailman/listinfo/ghc-devs</a><br>
<br></blockquote></div><br></div></div></div></div></div></div>
</blockquote></div><br></div>