[Haskell-cafe] Parallel Haskell stories

Christopher Done chrisdone at googlemail.com
Wed Mar 9 18:50:39 CET 2011


On 9 March 2011 17:18, Simon Peyton-Jones <simonpj at microsoft.com> wrote:

> I can't say a lot about any one example, obviously, but what would be great
> would be
>        - an idea of how Haskell helped (esp if you have a head to head
> comparison)
>        - code snippets that illustrate how lovely it all is
>        - brief performance indicators
> *Insight* is the key word.  I don't just want to say "Company X used
> Haskell to do Y" because that doesn't convey any re-usable insights or
> ideas.  What is the essence?
>

For what it's worth… (I imagine you're looking for more speed-intensive
projects, but I like talking about Haskell, so here goes) my pet project
IRCd called Hulk[1]. I whipped up a simple IRCd in an evening, and then the
next day we (the dev team where I work[4]) were using it!

Each client runs as a lightweight thread. The initial version used MVars all
over the place, basically imperative, typical sloppy "getting it done
quickly" code. I rewrote it a couple days later so that only the code that
accepts connections and responds on the sockets is impure (100~ lines), and
all the main code is totally pure (700~ lines), written in a monad stack of
reader (connection information), writer (replies) and state (user details)
(I abuse them[2]). I wrote about 500 lines of the pure stuff before even
running it, and it just worked.

There is one MVar in the project, that holds a pure value of all the state,
this along with totally pure code, which has the obvious benefits;
testability, a kind of "transactional" isolation. Some things (like checking
against a SHA1 encrypted password file) require IO, so I have a
MonadProvider class[3], with methods for *providing* values that will be
impurely-acquired in the real server, but while testing I can provide my own
values in a pure Reader or whatnot (HUnit and even QuickCheck spring to
mind).

One benefit, which didn't occur to me until asked about it, is that I didn't
have to think much about choosing to have a separate thread per client
because threads are so light-weight, my (Common Lisper) colleague was taken
aback, being used to only "expensive" OS threads. The process been running
for the past three weeks and we use it for all our dev discussion and for
displaying things from feeds with rss2irc like commits, service events,
support tickets, etc. Not bad for a few evenings of hacking!

Insights: (1) It's nice and actually practical to make everything pure apart
from the truly non-pure things, the monad of which can be parametrized. (2)
Use of light-weight threads feels very natural, letting you think as if
you're working in a single thread (with, e.g. blocking sockets), with no
real cost. (3) Rapid prototyping in Haskell is actually very easy and
effective.

[1]: https://github.com/chrisdone/hulk
[2]:

class Monad m => MonadProvider m where

  providePreface   :: m (Maybe String)

  provideMotd      :: m (Maybe String)

  provideKey       :: m String

  providePasswords :: m String

[3]: I could stick all these in the StateT, but I think Reader and Writer
are like nice, statically-enforced documentation.

newtype IRC m a = IRC {

    runIRC :: ReaderT (UTCTime,Conn) (WriterT [Reply] (StateT Env m)) a

  }

  deriving (Monad

           ,Functor

           ,MonadWriter [Reply]

           ,MonadState Env

           ,MonadReader (UTCTime,Conn))

[4]: FWIW, the development section of CREATE-NET, a research centre in
Italy. We are hiring Haskellers for application dev…
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110309/59fce8a4/attachment.htm>


More information about the Haskell-Cafe mailing list