[Haskell-cafe] [ANN] IHaskell -- Haskell for Interactive Computing (via IPython)

Andrew Gibiansky andrew.gibiansky at gmail.com
Tue Oct 22 16:56:26 UTC 2013


Hey Conrad!

You're right and sorry I wasn't quite clear - this has approximately
nothing to do with Python itself. IPython provides a language-agnostic way
to use its interfaces, without ever dealing with Python, so really the only
thing this project has to do with Python is that the frontends for IPython
are implemented in it. The two IPython frontends that this has been tested
with are the simple console (just a normal terminal console) and the
notebook. The notebook is an interface modeled after Mathematica's notebook
style, with code cells which you can evaluate interspersed with text and
output. All of this is in a web browser, so anything that you can display
as HTML can be output - this means that if you can display your plot in
HTML, you can have the IPython notebook display it as output. (The HTML
even includes javascript, I believe, which means the output itself can be
interactive!)

The goal of IHaskell is exactly what you mention - plotting and viewing
complex data structures in a REPL. The way this works in IPython is as
follows:

1. IPython sends a "execute_request" message to the IHaskell kernel, which
says, "please execute this code".
2. IHaskell can reply with several messages as it processes the code, one
of which is called "display_data". This message encodes in it different
representations of the same data - for instance, we can display something
as plain text, or HTML, or SVG, or Latex, and the display_data message will
have essentially a dictionary that maps mimetype ("text/plain",
"text/latex", "text/html") to the actual data.
3. The IPython frontend gets the display_data message and decides the best
representation to use. So, if the frontend is a text console, it won't use
the HTML and image representations; however, if its the notebook console,
it'll always choose the richest display, whether it's LaTex or HTML or SVG
or anything else.

Thus, in order to display more complex data types, the IHaskell kernel has
to know about those data type. It has to encode them somehow into HTML or
Latex, and then send them in that form, and IHaskell notebook will display
them.

This mechanism is already implemented in IHaskell. You can see that in
action if you trigger an error or use a GHCi-style ":" directive. The ":"
directives are unimplemented, so it just echoes back a bit of HTML that
prints the directive in green. If you trigger an error, the error is
wrapped in a bit of styled HTML to make it red and italic. These two are
just "proof-of-concept" for the display_data communication - hopefully this
can soon be extended to more interesting things, such as plotting. (Another
example is JSON - if your output is a JSON string, it should be displayed
as nice syntax-highlighted JSON. The HTML can even include Javascript, so
the JSON output could have things fold and unfold or other interactive
features, and the plotting output could have some sort of nice plot editing
or animation via JS)

To give some code from IHaskell that might clarify some of these thoughts:

-- Interface to the code evaluator. Takes a code string, outputs different
data representations.
evaluate :: String -> [DisplayData]

-- Data for display: a string with associated MIME type.
data DisplayData = Display MimeType String

-- Possible MIME types for the display data.
-- Should eventually include latex, png, svg, etc.
data MimeType = PlainText | MimeHtml

-- The main evaluator which uses the GHC api (code simplified for
presentation purposes)
evalCommand (Statement stmt) = do
    -- Capture stdout from the code we're running
    (printed, result) <- capturedStatement stmt
    case result of
      RunOk boundNames ->
        -- On success, just return the printed text
        return [Display PlainText printed]
      RunException exception -> do
        -- On error, show the exception in red italics
        return [Display MimeHtml $ makeError $ show exception]

Note the "on success" bit, which returns just [Display PlainText printed].
We can use the GHC API here to look at the types and values of any bound
names, or potentially parse the stdout output, and then use those to
generate DisplayData values that are more useful than just the printed
plain text. This is where we can extend IHaskell greatly, and make it give
us *really* pretty output. I have not figured out exactly how to use the
GHC API to do all of this and how to make it modular, but that's the
ultimate goal. (Hopefully, I can figure out some way such that if you
install a package - say, "ihaskell-repa" - which includes some typeclass
instances that we use for converting to DisplayData, IHaskell will
automatically detect and use the installed package. This might involve even
more GHC hackery and dynamic linking, though, but I think it should be
possible.)

Hope this clarified things. Let me know if you have any more questions :)
-- Andrew


On Mon, Oct 21, 2013 at 4:08 PM, Conrad Parker <conrad at metadecks.org> wrote:

>
> On 22 October 2013 08:32, Andrew Gibiansky <andrew.gibiansky at gmail.com>wrote:
>
>> Hey everyone!
>>
>> I'm excited to announce the initial release of IHaskell, a Haskell
>> language kernel for IPython:
>>
>> http://gibiansky.github.io/IHaskell
>>
>> IHaskell allows IPython to communicate with the kernel and evaluate
>> Haskell code. This enables using IPython interfaces such as console,
>> qtconsole, and most importantly, IPython notebook with Haskell. The IPython
>> Notebook supports image, HTML, and LaTeX output, which enables things such
>> as Javascript viewers for complex data structures or embedded graphs and
>> makes it a great platform for interactive computing.
>>
>> You can take a look at the code and install instructions here:
>>
>> https://github.com/gibiansky/IHaskell
>>
>> A general overview of the architecture is available as well:
>>
>> http://andrew.gibiansky.com/blog/ipython/ipython-kernels/
>>
>> Contributing: IHaskell is a very young project, but one that I think
>> would make a great contribution to the Haskell community. There's still
>> tons and tons left to do before it's on par with what IPython notebook is
>> capable of, so if you're at all interested in contributing, please get in
>> touch! I've tried to keep everything well-documented and readable, but I
>> will also be happy to answer questions about the code myself.
>>
>> If you find any bugs or edge cases or installation difficulties, please
>> send me an email or create a Github issue for it!
>>
>
> Hi Andrew,
>
>  this looks very cool! At first I was a bit wary of the "python" aspects
> of it, but I dug around a bit in the links you provided, and it seems:
>
>   * IHaskell is implemented purely in Haskell
>   * the communication with IPython is via ZeroMQ sockets
>   * once you throw data over the wall (through ZeroMQ) it gets routed via
> python to whatever backend (web, LaTeX etc.)
>
> One thing there has been a lot of demand for in the Haskell community is
> plotting from a repl. It looks like IHaskell could solve that well, given
> that all the plumbing already exists. How would you go about displaying,
> say, a Vector Double?
>
> I assume displaying more complex types would require some custom code. Do
> you have any examples of how you would use IHaskell to display a data
> structure in a web browser?
>
> Conrad.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20131022/f3be7429/attachment.html>


More information about the Haskell-Cafe mailing list