<div dir="ltr">Sorry I'm a bit late to the party, I'm a bit snowed under with some GHCJS refactoring work and the things I really need to do before the 7.10 merge window closes.<div><br></div><div>I think that exposing GHC's front end functionality through the library would be a good idea. Unfortunately it adds the haskeline dependency, so adding it to the `ghc` package wouldn't be ideal. On the other hand, if we exposed the GHC/GHCi modules as a library in a `ghc-bin` package, then we'd avoid this, and also address ghc-mod's problem of the terminfo dependency.</div><div><br></div><div>Unfortunately this part of GHC has never been written with use as a library in mind, so users would likely run into limitations at some point. For example, GHCJS has a complete copy - with some modifications - of the `ghc/Main.hs` module containing the command line parser and session setup code. Even if this module was exposed through the library, I wouldn't be able to use much of it, because of slight differences in command line options.</div><div><br></div><div>My approach/plan so far has been to first copy code from GHC to the GHCJS tree to make it work, and then make changes in the next major GHC version that'd let me remove most of the lower level (and most likely to be version specific) code from my copy. It would probably take a few iterations to satisfy all the needs of ghc-mod/ghc-server/GHCJS and others, but the result, a library, would be more flexible than a JSON API for GHCi (which would still be useful by itself).</div><div><br></div><div>If stability/segfaults are a major factor in choosing to communicate with the GHCi program, rather than using GHC as a library, then this really should be addressed directly. Has anyone done investigation of the situations that make ghc-mod/ghc-server, but not GHCi, crash?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 20, 2014 at 3:07 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div lang="EN-GB" link="blue" vlink="purple">
<div>
<p class="MsoNormal"><span style="font-family:"Calibri","sans-serif"">Christopher<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"">You are doing very cool things.  Thank you.<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"">What I’m puzzled about is this: the GHC API *<b>is</b>* a programmatic interface to GHC.  Why not just use it?<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-family:"Calibri","sans-serif"">I can think of some reasons:<u></u><u></u></span></p>
<p style="margin-right:0cm;margin-bottom:6.0pt;margin-left:36.0pt">
<u></u><span style="font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u><span style="font-family:"Calibri","sans-serif"">It’s not very clear just what’s in the GHC API and what isn’t, since you have access to all of GHC’s internals if you use –package ghc.  And the API isn’t
 very well designed.   (Answer: could you help make it better?)<u></u><u></u></span></p>
<p style="margin-right:0cm;margin-bottom:6.0pt;margin-left:36.0pt">
<u></u><span style="font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u><span style="font-family:"Calibri","sans-serif"">You want some functionality that is currently in GHCi, rather than in the ‘ghc’ package.  (Answer: maybe we should move that functionality into the ‘ghc’
 package and make it part of the GHC API?)<u></u><u></u></span></p>
<p style="margin-right:0cm;margin-bottom:6.0pt;margin-left:36.0pt">
<u></u><span style="font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u><span style="font-family:"Calibri","sans-serif"">You have to be writing in Haskell to use the GHC API, whereas you want a separate process you connect to via a socket.  (Answer: Excellent: write a server
 wrapper around the GHC API that offers a JSON interface, or whatever the right vocabulary is.  Sounds as if you have more  or less done this.)<u></u><u></u></span></p>
<p style="margin-right:0cm;margin-bottom:6.0pt;margin-left:36.0pt">
<u></u><span style="font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u><span style="font-family:"Calibri","sans-serif"">Moreover, the API changes pretty regularly, and you want multi-compiler support.  (No answer: I don’t know how to simultaneously give access to new stuff
 without risking breaking old stuff.)<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-family:"Calibri","sans-serif"">My meta-point is this: GHC is wide open to people like you building a consensus about how GHC’s basic functionality should be wrapped up and exposed to clients.  (Luite is another person
 who has led in this space, via GHCJS.)   So please do go ahead and lay out the way it *<b>should</b>* be done, think about migration paths, build a consensus etc.  Much better that than do fragile screen-scraping on GHCi’s textual output.<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-family:"Calibri","sans-serif"">Thanks for what you are doing here.<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<span style="font-family:"Calibri","sans-serif"">Simon<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:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #e1e1e1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri","sans-serif"">From:</span></b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri","sans-serif""> ghc-devs [mailto:<a href="mailto:ghc-devs-bounces@haskell.org" target="_blank">ghc-devs-bounces@haskell.org</a>]
<b>On Behalf Of </b>Christopher Done<br>
<b>Sent:</b> 18 October 2014 16:49<br>
<b>To:</b> <a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a><br>
<b>Subject:</b> Making GHCi awesomer?<u></u><u></u></span></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div><div><div class="h5">
<p>Good evening,<u></u><u></u></p>
<p style="margin:0px!important">So I’ve been working on Haskell user-facing tooling in general for<br>
some years. By that I mean the level of Emacs talking with Haskell<br>
tools.<u></u><u></u></p>
<p style="margin:0px!important">I wrote the interactive-haskell-mode (most functionality exists<br>
<a href="https://github.com/haskell/haskell-mode/blob/master/haskell-process.el#L1" target="_blank">in this file</a>).<br>
which launches a GHCi process in a pipe and tries very earnestly to<br>
handle input/output with the process reasonably.<u></u><u></u></p>
<p style="margin:0px!important">For Emacs fanciers: Written in Elisp, there’s a nice command queue<br>
that you put commands onto, they will all be run on a FIFO one-by-one<br>
order, and eventually you’ll get a result back. Initially it was just<br>
me using it, but with the help of Herbert Riedel it’s now a mode on<br>
equal footing with the venerable inferior-haskell-mode all ye Emacs<br>
users know and love. It’s part of haskell-mode and can be enabled by<br>
enabling the interactive-haskell-mode minor mode.<u></u><u></u></p>
<p style="margin:0px!important">For years I’ve been using GHCi as a base and it’s been very reliable<br>
for almost every project I’ve done (the only exceptions are things<br>
like SDL and OpenGL, which are well known to be difficult to load in<br>
GHCi, at least on Linux). I think we’ve built up<br>
<a href="https://github.com/haskell/haskell-mode/wiki/Haskell-Interactive-Mode" target="_blank">a good set of functionality</a><br>
purely based on asking GHCi things and getting it to do things.<u></u><u></u></p>
<p style="margin:0px!important">I literally use GHCi for everything. For type-checking, type info, I<br>
even send “:!cabal build” to it. Everything goes through it. I love my<br>
GHCi.<u></u><u></u></p>
<p style="margin:0px!important">Now, I’m sort of at the end of the line of where I can take GHCi. Here<br>
are the problems as I see them today:<u></u><u></u></p>
</div></div><p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span>1.<span style="font:7.0pt "Times New Roman"">     
</span></span><u></u>There is no programmatic means of communicating with the<span class=""><br>
process. I can’t send a command and get a result cleanly, I have to<br>
regex match on the prompt, and that is only so reliable. At the<br>
moment we solve this by using \4 (aka ‘END OF TRANSMISSION’). Also<br>
messages (warnings, errors, etc.) need to be parsed which is also<br>
icky, especially in the REPL when e.g. a defaulted Integer warning<br>
will mix with the output. Don’t get me started on handling<br>
multi-line prompts! Hehe.<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span>2.<span style="font:7.0pt "Times New Roman"">     
</span></span><u></u>GHCi, as a REPL, does not distinguish between stdout, stderr and<span class=""><br>
the result of your evaluation. This can be problematic for making a<br>
smooth REPL UI, your results can often (with threading) be<br>
interspersed in unkind ways. I cannot mitigate this with any kind<br>
of GHCi trickery.<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span>3.<span style="font:7.0pt "Times New Roman"">     
</span></span><u></u>It forgets information when you reload. (I know this is intentional.)<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span>4.<span style="font:7.0pt "Times New Roman"">     
</span></span><u></u>Not enough information is exposed to the user. (Is there ever? ;)<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span>5.<span style="font:7.0pt "Times New Roman"">     
</span></span><u></u>There is a time-to-market overhead of contributing to GHCi — if I<span class=""><br>
want a cool feature, I can write it on a locally compiled version<br>
of GHC. But for the work projects I have, I’m restricted to given<br>
GHC versions, as are other people. They have to wait to get the<br>
good features.<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span>6.<span style="font:7.0pt "Times New Roman"">     
</span></span><u></u>This is just a personal point — I’ve like to talk to GHCi over a</p><div><div class="h5"><br>
socket, so that I can run it on a remote machine. Those familiar<br>
with Common Lisp will be reminded of SLIME and Swank.<u></u><u></u></div></div><p></p><div><div class="h5">
<p style="margin:0px!important">Examples for point 4 are:<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span style="font-size:10.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u>Type of sub-expressions.<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span style="font-size:10.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u>Go to definition of thing at point (includes local scope).<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span style="font-size:10.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u>Local-scope completion.<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span style="font-size:10.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u>A hoogle-like query (as seen in Idris recently).<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span style="font-size:10.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u>Documentation lookup.<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span style="font-size:10.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u>Suggest imports for symbols.<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span style="font-size:10.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u>Show core for the current module.<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span style="font-size:10.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u>Show CMM for the current module, ASM, etc. SLIME can do this.<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span style="font-size:10.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u>Expand the template-haskell at point.<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span style="font-size:10.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u>The :i command is amazingly useful, but programmatic access would be<br>
even better.¹<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span style="font-size:10.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u>Case split anyone?<u></u><u></u></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span style="font-size:10.0pt;font-family:Symbol"><span>·<span style="font:7.0pt "Times New Roman"">        
</span></span></span><u></u>Etc.<u></u><u></u></p>
<p style="margin:0px!important">¹I’ve integrated with it in Emacs so that I can C-c C-i any identifier<br>
and it’ll popup a buffer with the :i result and then within that<br>
buffer I can drill down further with C-c C-i again. It makes for<br>
very natural exploration of a type.<u></u><u></u></p>
<p style="margin:0px!important">You’ve seen some of these features in GHC Mod, in hdevtools, in the FP Haskell<br>
Center, maybe some are in Yi, possibly also in Leksah (?).<u></u><u></u></p>
<p style="margin:0px!important">So in light of point (5), I thought: I’ve used the GHC API before, it<br>
can do interactive evaluation, why not write a project like<br>
“ghc-server” which encodes all these above ideas as a “drop-in”<br>
replacement for GHCi? After all I could work on my own without anybody<br>
getting my way over architecture decisions, etc.<u></u><u></u></p>
<p style="margin:0px!important">And that’s what I did. It’s<br>
<a href="https://github.com/chrisdone/ghc-server" target="_blank">here</a>. Surprisingly, it kind of works. You run it in your directoy like you would do “cabal repl”<br>
and it sets up all the extensions and package dependencies and starts<br>
accepting connections. It will compile across three major GHC<br>
versions. Hurray! Rub our hands together and call it done, right?<br>
Sadly not, the trouble is twofold:<u></u><u></u></p>
</div></div><p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span>1.<span style="font:7.0pt "Times New Roman"">     
</span></span><u></u>The first problem with this is that every three projects will<span class=""><br>
segfault or panic when trying to load in a project that GHCi will<br>
load in happily. The reasons are mysterious to me and I’ve already<br>
lugged over the GHC API to get to this point, so that kind of thing<br>
happening means that I have to fall back to my old GHCi-based<br>
setup, and is disappointing. People have similar complaints of GHC<br>
Mod & co. “Getting it to work” is a deterrant.<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span>2.<span style="font:7.0pt "Times New Roman"">     
</span></span><u></u>While this would be super beneficial for me, and has been a good<span class=""><br>
learning experience for “what works and what doesn’t”, we end up<br>
with yet another alternative tool, that only a few people are<br>
using.<u></u><u></u></span></p>
<p class="MsoNormal" style="margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<u></u><span>3.<span style="font:7.0pt "Times New Roman"">     
</span></span><u></u>There are just certain behaviours and fixes here and there that</p><div><div class="h5"><br>
GHCi does that take time to reproduce.<u></u><u></u></div></div><p></p><div><div class="h5">
<p style="margin:0px!important">So let’s go back to the GHCi question: is there still a development<br>
overhead for adding features to GHCi? Yes, new ideas need acceptance<br>
and people have to wait (potentially a year) for a new feature that<br>
they could be using right now.<u></u><u></u></p>
<p style="margin:0px!important">An alternative method is to do what Herbert did which is to release a<br>
<a href="http://hackage.haskell.org/package/ghci-ng" target="_blank">“ghci-ng”</a> which sports<br>
new shiny features that people (with the right GHC version) will be<br>
able to compile and use as a drop-in for GHCi. It’s the same codebase,<br>
but with more stuff! An example is the “:complete” command, this lets<br>
IDE implementers do completion at least at the REPL level. Remember<br>
the list of features earlier? Why are they not in GHCi?<u></u><u></u></p>
<p style="margin:0px!important">So, of course, this got me thinking that I could instead make<br>
ghc-server be based off of GHCi’s actual codebase. I could rebase upon<br>
the latest GHC release and maintain 2-3 GHC versions backwards. That’s<br>
certainly doable, it would essentially give me “GHCi++”. Good for me,<br>
I just piggy back on the GHCi goodness and then use the GHC API for<br>
additional things as I’m doing now.<u></u><u></u></p>
<p style="margin:0px!important">But is there a way I can get any of this into the official repo? For<br>
example, could I hack on this (perhaps with Herbert) as “ghci-ng”,<br>
provide an alternative JSON communication layer (e.g. via some<br>
—use-json flag) and and socket listener (—listen-on ), a way<br>
to distinguish stdout/stderr (possibly by forking a process, unsure at<br>
this stage), and then any of the above features (point 4) listed. I<br>
make sure that I’m rebasing upon HEAD, as if to say ghci-ng is a kind<br>
of submodule, and then when release time comes we merge back in any<br>
new stuff since the last release. Early adopters can use<br>
ghci-ng, and everyone benefits from official GHC releases.<u></u><u></u></p>
<p style="margin:0px!important">The only snag there is that, personally speaking, it would be better<br>
if ghci-ng would compile on older GHC versions. So if GHC 7.10 is the<br>
latest release, it would still be nice (and it <em>seems</em> pretty<br>
feasible) that GHC 7.8 users could still cabal install it without<br>
issue. People shouldn’t have to wait if they don’t have to.<u></u><u></u></p>
<p style="margin:0px!important">Well, that’s everything. Thoughts? <u></u><u></u></p>
<p style="margin:0px!important">Ciao!<u></u><u></u></p>
<div>
<p class="MsoNormal"><span style="font-size:1.0pt">​<u></u><u></u></span></p>
</div>
</div></div></div>
</div>
</div>
</div>
</div>

<br>_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/ghc-devs" target="_blank">http://www.haskell.org/mailman/listinfo/ghc-devs</a><br>
<br></blockquote></div><br></div>