
Haskell for Web Developers - rwosync
http://www.stephendiehl.com/posts/haskell_web.html
======
Chris_Newton
You might not need a deep understanding of category theory to write useful
programs in Haskell, but the downsides of relying on those explicit monads to
control state and interactions still show through in practical code.

Here’s an early example from the article:

    
    
        import Control.Monad.State
    
        type Interact a = StateT Int IO a
    
        repl :: Interact ()
        repl = forever $ do
          val   <- liftIO readLn
          state <- get
          liftIO $ putStr "Total: "
          liftIO $ print (val + state)
          put val
    
        main = runStateT repl 0
    

Here’s something with similar behaviour written in Python, an imperative
language with a reputation for being easy to read:

    
    
        total = 0
        while True:
            total += input()
            print "Total:", total
    

The difference is striking. The latter is obviously much more concise.
Ironically, it also seems clearer about how the state is used, having the
initialization, reading and writing of that state all kept together. It’s
worth considering that the stateful logic is relatively kind here, too,
because there’s only a single value that needs to be maintained via StateT in
the Haskell version.

The Python code has the added advantage of actually being correct, assuming
that the intended behaviour really is to add up the total of all entered
numbers over time as the output suggests.

I think this example is instructive in terms of advancing industrial practice
rather than the theoretical state of the art. Haskell demonstrates a lot of
nice features that mainstream industrial languages lack today, but as soon as
any sort of state or effects enter the picture, it becomes absurdly
complicated to describe even simple systems. I would love to have future
languages incorporate some of the safety that Haskell offers, but I think to
catch on with working programmers they will have to hide away a lot of the
state/effect details where they aren’t needed, just as tools like type
inference have hidden away their own form of boilerplate. It’s not just about
not needing to be an expert on category theory, it’s about not having to be
aware of it at all.

~~~
runT1ME
>The Python code has the added advantage of actually being correct, assuming
that the intended behaviour really is to add up the total of all entered
numbers over time as the output suggests.

Only in a single threaded environment. However, concurrently, the Haskell code
_stays_ correct in a concurrent environment while your python code has bugs.

Extrapolate a bit, and think about how many python functions may be slightly
less trivial than yours and yet still have the same concurrency issues...

~~~
Chris_Newton
Contrary to the hype, I think plenty of useful code _does_ still run in a
single-threaded environment, so I find your argument unconvincing.

That said, even in an environment with concurrency, I’m not advocating
uncontrolled state changes as typified by current imperative programming
languages. I’m arguing that we could benefit from the robust theory underlying
languages like Haskell, but used more transparently so the developer only has
to worry about it when it matters.

For example, you could be running a second thread in parallel with the one
we’re looking at here, but if its effects are constrained to replying to a
network-supplied request for the current time and reading the system’s clock,
it doesn’t matter at all that our interactive adder is running at the same
time. These effects affect different, independent resources and will never
interact, so there is no benefit to cluttering either code path with extra
details.

What I’d really like to see is a language that could understand those
resources and how they are affected by each thread in terms of reads and
updates. I want it to stop me from modifying the code later so that it
accidentally becomes vulnerable to interactions that I’m not fully
controlling. I want it to provide me with tools to specify how potential
interactions should be handled, in a way that is systematic and robust but
otherwise as simple as possible, and that can be applied at whatever level of
my design makes the most sense.

Research into type and effect systems is addressing challenges like these, but
I’m hoping that when the dust settles, the final version will look a lot more
like Python with a few strategically placed annotations than Haskell where
these implementation details are in your face all the time (even if most of
the time you don’t actually need to worry about them).

~~~
runT1ME
>I want it to stop me from modifying the code later so that it accidentally
becomes vulnerable to interactions that I’m not fully controlling. I want it
to provide me with tools to specify how potential interactions should be
handled, in a way that is systematic and robust but otherwise as simple as
possible, and that can be applied at whatever level of my design makes the
most sense.

That's...the state monad. The compiler tells you when you try to access it in
a way that is not allowed.

You have to be explicit with sharing.

~~~
Chris_Newton
_That 's...the state monad. The compiler tells you when you try to access it
in a way that is not allowed._

But the price for that is that I _always_ have to access it in a cumbersome
way, even when being so explicit makes no useful difference to the correctness
of my code.

 _You have to be explicit with sharing._

I don’t _want_ to be explicit with sharing.

I want to be explicit with sharing _when it matters_ , and otherwise not to
worry about it, safe in the knowledge that the language will warn me if I try
to do something later that invalidates any assumptions I’m making now.

------
agentultra
I don't think you're going to convince existing web developers to adopt
Haskell.

The second example from the article uses 8-lines of Haskell, a hand-waving
explanation of a state transformer monad, composition, and a state transition
diagram to demonstrate how easy it is to write trivial Haskell programs. The
program in question takes a number from stdin, adds it to a counter, and
prints the result.

"Web developers," being those who have experience building applications using
web-based technologies, have a plethora of tools and languages at their
disposal that don't require the up-front investment of learning Haskell.

Haskell has a lot to offer but I suspect the only people interested in using
Haskell in their web application projects are Haskell developers or people
who've been convinced that they will be smarter if they learn Haskell.

~~~
asdasf
I've had the opposite experience. Everyone I know who does web development is
frustrated by the poor quality of work they produce, and how hard it is to
maintain the projects they've done. Re-writing a project from scratch every ~5
years is essentially normal development practice. I learned haskell just for
web development. I am not smarter as a result, I just have a better tool now
that helps me produce better results. My wife then decided to learn haskell
for web development too. Neither of us have a background in computer science,
or even a degree at all. We learned haskell for purely practical reasons, and
we keep using it for those purely practical reasons.

~~~
agentultra
ymmv; I hate web development but maintainability is the least of my concerns.
I have frameworks for that.

~~~
asdasf
What framework, and what is it doing to help with maintenance? My experience
has been that typical RoRish frameworks are so heavily concerned with trying
to make the initial writing of the app easier that they actually hinder long
term maintenance.

~~~
agentultra
Pick a framework, I've probably worked on an application that used it.

 _what is it doing to help with maintenance?_

What frameworks do: impose structure and convention on the design of programs.

In the case of web frameworks you provide some data, map URLs to functions,
and hook into some helpers for managing sessions, caching, and the like.

Haskell has them too.

 _...they actually hinder long term maintenance._

I've found the opposite to be true in the general case.

Disqus is probably the largest Django application out there that I know of
(and note I have never worked there). From their technical talks and
contributions to Django over the years it seems to me that Django has been a
net-win for them, maintenance wise, over the years. I can't say what it's like
maintaining a Django application like Disqus but it doesn't sound to me from
what I know that Django is any hindrance to them.

~~~
asdasf
>What frameworks do: impose structure and convention on the design of
programs.

So, nothing? Convention doesn't prevent things from breaking when you make
changes.

>Haskell has them too

I know, I use two of them. And I haven't found any benefits to maintenance
from them. I've found huge benefits to maintenance from haskell though.

>it seems to me that Django has been a net-win for them

Compared to what though? I didn't say frameworks are useless, I said they
don't appear to do anything to aid in maintenance.

~~~
agentultra
_So, nothing? Convention doesn 't prevent things from breaking when you make
changes._

No, not nothing. Exactly what it says on the tin.

Without a web framework what do you get? A few buffers to read/write some
bytes to. Have fun writing your parsers, dispatchers, database connection pool
handling, object relational mapper, etc, etc, etc... and especially have fun
_maintaining_ all of that.

If you used a framework though, _you wouldn 't have to_. It's already there
and there's a community of people who work on that stuff for you. Awesome.

First rule of maintenance: _the code you don 't write is the code you don't
have to maintain_.

I don't see what Haskell is winning here in terms of maintenance. Without
Yesod or any other framework you're in the same boat as someone starting with
plain Java or Tcl or something.

Unless of course you're referring to its masochistic type system that
magically protects you from ever writing a bug ever. _Good luck with that_.

My point was, originally, that a web developer that doesn't already know
Haskell and hasn't convinced themselves to learn Haskell isn't going to look
at some Haskell code and be converted. They're going to see StateT and monad
combinators and the awful pain of IO in Haskell and go write their app in X.

~~~
asdasf
>Without a web framework what do you get? A few buffers to read/write some
bytes to. Have fun writing your parsers, dispatchers, database connection pool
handling, object relational mapper, etc, etc, etc... and especially have fun
maintaining all of that.

Why would I write all of that myself rather than use libraries? You do realize
that writing an application is not a binary choice between "use framework" and
"write everything from scratch" right?

>If you used a framework though, you wouldn't have to

I don't have to anyways, a framework has nothing to do with it.

>I don't see what Haskell is winning here in terms of maintenance

Type safety. I can change my code, and every single thing I just broke is now
specified for me, file and line, by the compiler. This is an absolutely
massive difference compared to trying to rely exclusively on unit tests. You
should really try it sometime.

>Unless of course you're referring to its masochistic type system that
magically protects you from ever writing a bug ever.

Really, you should try it sometime. Or at least take the ignorant nonsense to
reddit where it belongs.

>My point was, originally, that a web developer that doesn't already know
Haskell and hasn't convinced themselves to learn Haskell isn't going to look
at some Haskell code and be converted

And my point was that is exactly what happened with both me and my wife.

~~~
agentultra
_Really, you should try it sometime. Or at least take the ignorant nonsense to
reddit where it belongs._

I've read the papers and I've tried a bit of Haskell. I write lots of C++ too.
I've tried different flavours of typing. I still prefer dynamic, strong-typing
any day. Common Lisp or Python generally do the trick.

And I've been programming for > 10 years. I'd appreciate it if you wouldn't
assume I'm an ignorant dumbass because I don't agree with you.

 _And my point was that is exactly what happened with both me and my wife._

Does not imply it's true for everyone. Maybe I should quantify that my
original point with _most_ web developers using existing technologies aren't
going to hop over to Haskell because of state transformation and combinator
monads and strong typing.

~~~
asdasf
>I write lots of C++ too

I know, that's why you say completely backwards things like "masochistic type
system". You are ignorant of haskell, and instead apply your experience with
statically typed languages with inexpressive and awkward type systems to
haskell.

>And I've been programming for > 10 years. I'd appreciate it if you wouldn't
assume I'm an ignorant dumbass because I don't agree with you.

Ignorance has nothing to do with being a dumbass. You are ignorant. So am I.
So is everyone else. The fact that modern type systems is one of the areas
where you are ignorant does not make you stupid or a bad person. My suggestion
that gaining knowledge and experience in that area could be beneficial to you
is not an attack, it is a genuine suggestion. I used to be a programmer with
10 years experience who thought static typing was bad too.

>Does not imply it's true for everyone

I didn't claim it was. I pointed out that your broad claim is unsupported by
evidence, and that my personal experience was directly contradictory.

~~~
agentultra
_I know, that 's why you say completely backwards things like "masochistic
type system"._

I don't think disagreeing with you makes me ignorant or gives you any special
insight into my knowledge of type systems.

And my statement is only backwards from the perspective of developers who find
pleasure in working with such a compiler.

If you want to know the extent of my ignorance I've only used Haskell in so
far as to complete various programming exercises and inspecting the source
code to xMonad. I was interested enough at one point to find out what all the
hype was about. I've watched most of the seminal talks from Peyton-Jones and
I've read numerous papers on Hindley-Milner type inference, category theory,
monads... and perhaps countless more articles than I care to remember that
extoll the virtues of the pain of getting your types right (in fact I think
I've read it from numerous sources describing the experience as "pain," but
that, "it's worth it").

Weird.

In the end my conclusion, different and ignorant though it is, is that purity
is over-rated and not worth the trade-offs. I prefer languages that let me be
the judge of what is useful and avoid languages that make broad
generalizations about purity, mutability, and types.

 _I pointed out that your broad claim is unsupported by evidence, and that my
personal experience was directly contradictory._

And my experience is directly contradictory to yours. So what?

If we needed hard numbers to settle this I think we will find that the
majority of web applications in existence are not written in Haskell. And if
we take a survey of developers who build and maintain web applications about
whether they would consider switching to Haskell I imagine very few would
answer, "Yes." I think they will continue to maintain and develop new features
and applications without Haskell and the world will continue to turn.

Yes, as you've pointed out, there are other people out there like you. Sorry,
you're in the minority. The vast, vast minority.

There are a plethora of considerations to make when writing web application
software. I don't think I've ever stopped and said, "You know, I should wrap
all of this in a state transformation monad and combine it the an IO monad and
ensure that my entire program passes through my compiler's type-checker." And
I write large, eventually consistent data-stores without type checking... and
most of the time they work!

I just don't see why type checking up-front is such a huge deal. And believe
me or not, I've tried to convince myself.

------
venutip
One thing I haven't seen mentioned here is that web development is often not a
one-man endeavor. At its most basic, you commonly have separation between
front- and back-end. So unless you plan on doing it all yourself, you will
need to find a front-end developer who is either familiar with Clay, JMacro
and Fay; or who is willing to learn; and frankly, I don't think that's a very
likely scenario, given the scant usage of Haskell as a web development
language.

Also, the example of the compiled JavaScript from Fay is horribly obfuscated:

    
    
      return Fay$$_(Fay$$_(
                Fay$$cons)(i))(Fay$$_(
                Prelude$enumFrom)(
                Fay$$_(Fay$$_(
                    Fay$$add)(i))(1)
            ));
    

Oh, God, my eyes. Any idea at all what that does? I can tell you one thing: I
would not want to debug that on a Friday night. Or a Tuesday afternoon. Or
ever, really.

Kind of have to agree with a few of the other commenters here who are saying
things along the lines of "You can do anything with a hammer, if a hammer is
what you have."

Also: this reminds me of a "LISP for Web Development" talk I went to a few
years ago. The speaker was talking to a bunch of web devs about how LISP has
an undeserved reputation for being domain specific (academia, astronomy,
whatever). He then went on to explain how you could use it for calculating the
results of some kind of physics experiment and output it as an HTML table. Uh-
huh. My buddy and I walked out after about 25 minutes.

Am I being unfair?

>> As an example of we’ll use JMacro to implement a simple translator for the
untyped typed lambda calculus.

Nope.

~~~
gnuvince
> Oh, God, my eyes. Any idea at all what that does? I can tell you one thing:
> I would not want to debug that on a Friday night. Or a Tuesday afternoon. Or
> ever, really.

Do you often debug the assembler output of your compiler? Same thing; fix the
Fay code, not the Javascript that the compiler generates.

~~~
masklinn
I have source-level debuggers in other languages.

I'm not sure Fay now generates sourcemaps, and either way not all browsers
support them.

So it's pretty much guaranteed you'll have to debug generated javascript at
some point.

------
Arnor
I'm just getting started with Haskell and there will soon come a time where I
need to jump in the deep end. When I'm ready to learn Category theory, what
background will I need? Is elementary calculus and a little linear algebra
enough? Or am I going to need some more advanced math concepts? Once I've got
the right background, where should I go to learn Category theory?

~~~
jcurbo
We had a discussion on this when Stephen's last post showed up here:
[https://news.ycombinator.com/item?id=6041726](https://news.ycombinator.com/item?id=6041726)

I've been looking into this myself and I have a similar background as you
(elementary calculus and linear algebra; I also took number theory as part of
a math minor). So far it looks like I should pick up a bit of abstract
algebra/topology (rings, fields, groups, etc) then I should be able to start
off on the shallow end of category theory and work from there. At the same
time I need to improve my understanding of how monads, monad transformers,
monoids, functors, etc work in Haskell from an operational standpoint; I have
a basic understanding now but I'd like to dig deeper.

The thread I linked above has a lot of links to books and stuff like Reddit's
r/haskell and other places, that you can sort through to see what works for
you. I have yet to make that determination for myself, but there's plenty to
choose from. I actually picked up a copy of Benjamin Pierce's "Basic Category
Theory for Computer Scientists" a few years ago based on someone's
recommendation, way before I got into Haskell, and didn't make the connection
until I picked up his book on type theory recently (while researching a paper
on FP) and thought his name looked familiar.

Ultimately I'm hoping to be able to get deep into type theory and go through
that Homotopy Type Theory book that came out recently.

~~~
davidcuddeback
Thanks for the response. I was interested in the answer to this question as
well. I read through the thread [1] that you linked to, and seems like the
consensus is the same thing you said: it's best to learn abstract algebra and
topology first. Does anyone know of some good sources for those topics? The
other threads are understandably focused on category theory.

As for category theory, after reading through that thread [1] and the Reddit
thread [2] that it links to, I think _Conceptual Mathematics: A First
Introduction to Categories_ [3] will be my first read on category theory (but
probably followed by the Rosetta Stone paper). That book receives some strong
recommendations as a first book in the Reddit thread [2].

[1]
[https://news.ycombinator.com/item?id=6041726](https://news.ycombinator.com/item?id=6041726)

[2]
[http://www.reddit.com/r/haskell/comments/1ht4mf/books_on_cat...](http://www.reddit.com/r/haskell/comments/1ht4mf/books_on_category_theory_for_beginners/)

[3] [http://www.amazon.com/Conceptual-Mathematics-First-
Introduct...](http://www.amazon.com/Conceptual-Mathematics-First-Introduction-
Categories/dp/052171916X)

~~~
jcurbo
Not a problem. I'm interested in the abstract algebra question too, as I
haven't actually done any research yet. Perhaps someone should start an
r/categorytheory. :)

~~~
davidcuddeback
Digging deeper into the HN thread that you linked to, I came across this
discussion [1] on Reddit which is focused more on the abstract algebra
question. They recommend _Algebra: Chapter 0_ by Aluffi (Amazon [2] or PDF
[3]).

[1]
[http://www.reddit.com/r/math/comments/1eiyid/category_theory...](http://www.reddit.com/r/math/comments/1eiyid/category_theory_prereqs_does_alg_geometry_come/)

[2] [http://www.amazon.com/Algebra-Chapter-Graduate-Studies-
Mathe...](http://www.amazon.com/Algebra-Chapter-Graduate-Studies-
Mathematics/dp/0821847813?tag=duckduckgo-d-20)

[3]
[http://www.mimuw.edu.pl/~jarekw/pdf/Algebra0TextboookAluffi....](http://www.mimuw.edu.pl/~jarekw/pdf/Algebra0TextboookAluffi.pdf)

~~~
Arnor
Thanks for the Algebra Chapter 0 link! I think that's my next math book :)

------
pestaa
My long term bet is Haskell, but boy do the examples look ugly. And most of
Haskell really is ugly. My mind just can't get around type names like "M a p f
b c => (a -> p) -> b -> c -> a" just yet. I know it's not hard to understand,
but it is hard to parse and build up context.

Looking forward to having 5+ years of experience in this brilliant language.

~~~
ExpiredLink
Why do you think a language that "really is ugly" and " is hard to parse"
_must_ be a "brilliant language"? Maybe the emperor has no clothes? Maybe
Haskell is just what you see: suitable for academic discourse, unusable for
real-wold programming.

~~~
pekk
Presumably he thinks that it is brilliant for reasons he already knows,
probably involving the type system, but also observes that it is aesthetically
ugly and difficult to read.

~~~
nightski
Aesthetics are purely subjective and rather useless. Hell even our own opinion
of them can change drastically over time. The other reasons are what matter. I
initially found Haskell quite ugly. But now that I understand the semantics
behind it the syntax is quite beautiful in my eyes.

------
egonschiele
I really like Stephen's writing style: no frills, concise, but he still spends
time explaining the hard things. Plus he usually writes about things I don't
understand so I come away having learned something.

------
Rickasaurus
In this blog post about how easy and non-academic Haskell is I'm going to
implement the lambda calculus as an example

------
malandrew
One of the most challenging things about Haskell tutorials is the difficulty
in determining the etymology of very terse function names.

For example, what does the M in _forM__ stand for? Monad? Something else? What
about _liftM_? Why is it called lifting? Is the M here the same as the M in
_forM__?

These are just a few examples from this tutorial, but I find that this is
pretty much common everywhere in the Haskell world, making it hard to parse
semantic meaning from function names if you aren't already immersed in the
language and community and well versed in the lingo.

One of the best things I've learned to break out of this is to search for
JavaScript implementations of many Haskell concepts when such a concept is
doable in JavaScript. It usually leads me to enough understanding of what some
function is trying to accomplish to proceed with whatever Haskell tutorial I
happen to be reading.

~~~
ufo
The positive news is that while it might take a while to learn the
conventions, usually the conventions are enforced all around. In your case,
the conventions are documented in the docs for Control.Monad, the library
those functions are from:

The functions in this library use the following naming conventions:

> A postfix 'M' always stands for a function in the Kleisli category: The
> monad type constructor m is added to function results (modulo currying) and
> nowhere else. So, for example,
    
    
       filter  ::              (a ->   Bool) -> [a] ->   [a]
       filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
    

> A postfix '_' changes the result type from (m a) to (m ()). Thus, for
> example:
    
    
        sequence  :: Monad m => [m a] -> m [a] 
        sequence_ :: Monad m => [m a] -> m () 
    

> A prefix 'm' generalizes an existing function to a monadic form. Thus, for
> example:
    
    
        sum  :: Num a       => [a]   -> a
        msum :: MonadPlus m => [m a] -> m a
    

[http://www.haskell.org/ghc/docs/latest/html/libraries/base/C...](http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-
Monad.html)

Personally, the things that I found hard were idioms (like learning that $ is
just avoiding parenthesis, "go" is for loops, etc) and how theres a lot of
libraries that make the code shorter at the expense of forcing you to be aware
of them (for example, applicatives <$> <*> look alien until you learn what
they are and monad transformers add a lot of "magic" to the code as well as
force you to use annoying lifts all over the place)

------
gtani
these "how to read _" posts are helpful mini- style guide/naming convention
roadmaps

[http://blog.ezyang.com/2011/11/how-to-read-
haskell/](http://blog.ezyang.com/2011/11/how-to-read-haskell/)

[http://www.haskell.org/haskellwiki/How_to_read_Haskell#What_...](http://www.haskell.org/haskellwiki/How_to_read_Haskell#What_does_this_function_do.3F)

------
coldcode
If you like hammers you can make them do anything. Or is the analogy nails? I
forget.

The real question is why use Haskell instead of something else that most
people generally consider targeted at the web?

~~~
dragonwriter
> The real question is why use Haskell instead of something else that most
> people generally consider targeted at the web?

An equally "real" question is why people think "the web" is special in such a
way that it requires a different programming language for back-end
applications than other server applications use.

~~~
SiVal
I would say that the difference is that the Web is almost entirely about I/O,
which Haskell treats as an unfortunate aspect of programming that is to be
made as unpleasant as possible so it will be avoided except where unavoidable.

There are many programs that run on servers, grinding away on deep questions
for extended periods with no more than the bare minimum of communication with
the rest of the universe---maybe just a terse "42" at the end of a long run.

But the Web is about talking to users thousands of times per second, sending
it all in a hurricane of streams to a database, fetching data for each of them
from various databases, streaming it out to a third-party credit card
processor, sending the results back to the users....

Haskell's ideal of minimal I/O isolated in a ghetto so the "real" work of the
program can remain unpolluted doesn't seem an ideal match for the case where
the real work is almost entirely about routing I/O streams.

~~~
dragonwriter
> I would say that the difference is that the Web is almost entirely about I/O

That's true in the trivial sense, in the same way that "the desktop" is about
i/o, or "the command line" is, in that all of those specify an i/o channel.

But web apps or services aren't all about i/o any more than any other
applications/services, they just differ in that the main user-facing i/o
channel is HTTP.

> Haskell's ideal of minimal I/O isolated in a ghetto so the "real" work of
> the program can remain unpolluted doesn't seem an ideal match for the case
> where the real work is almost entirely about routing I/O streams.

Monads aren't ghettos isolated from the real work of the program. Monads are
tools for _doing_ the real work of the program -- whether its i/o, or dealing
with mutable state in a transactional, concurrency-safe manner, or, well, lots
of other things.

~~~
asdasf
>That's true in the trivial sense

I think it is true in the actual real world practical sense too. Consider how
many web applications are just plumbing between a database and a browser. 95%
of my app is in a MonadIO.

------
themodelplumber
>Do I still need a graduate degree in category theory to write to a file?

No.

> Will I need a graduate degree in category theory to parse the next paragraph
> in this article?

Oh. Um wait, define web developer for me again?

------
gnuvince
In the second example, shouldn't it be `mapM_` instead of `forM_` with this
ordering of the arguments?

------
film42
I've been meaning to ask this for a while now: what's the appeal of Haskell?
It doesn't come off as a pleasure to program in. Could someone who knows the
language share their thoughts?

~~~
egonschiele
I _love_ programming in Haskell! Seriously, the reason it's on HN so much is
that Haskellers love the language. Here are some reasons:

* Types, types, types. You're probably sick of hearing about Haskell's type system, but it's amazing. Gives you almost all the flexibility of a language like Ruby, PLUS you can encode a lot of your assumptions in types...so if there's a bug you'll catch it at compile time. I like how I can just write a LOT of Haskell code without testing it, and then just compile my project and find all the issues I need to fix. It makes prototyping really easy and fast.

* Awesome abstractions. Functors, monads, first class functions: you know how java is verbose and you end up writing the same boilerplate over and over? Haskell is the opposite.

* Awesome syntax. I really love Haskell's syntax: super clean, and you can modify it however you like. I like writing very readable code (you read code way more often than you write it) and Haskell lets me write very readable code.

* Neat libraries! All that stuff other languages are trying to work around? Like concurrency, or sandboxing? Part of the standard library already. I had written this post a while back ([http://adit.io/posts/2012-03-10-building_a_concurrent_web_sc...](http://adit.io/posts/2012-03-10-building_a_concurrent_web_scraper_with_haskell.html)) that shows exactly how easy it is.

Seriously, if you're curious about languages at all, give Haskell a try.

~~~
tel
I think something that's hard to appreciate before you learn Haskell is that
while a lot of the abstractions used in the language are more complex and
abstract than you're used to using, it's because the language/types/compiler
help to lift an enormous mental burden you usually carry while reasoning about
code in most languages.

Purity is great not because you make fewer errors but because when writing
pure code you can focus on what needs to happen instead of worrying about
state/effects/control flow. While having to sprinkle `liftIO`s around your
imperative code sounds dreadful, it's quickly appreciated as a statically
checked marker for "code that you need to think harder about".

So what you end up with is a fantastic playground to use mental tools
unavailable in other languages due to the complexity overhead. You also have a
suite of abstractions that "almost never break" due to their invariants being
encoded into the type system and thus checked every single time you reload the
file.

People often compare this effect to having a large suite of automatically
generated test specs run on every compile. It's like that, yeah, but humans
can write tests this bulletproof and no suite runs this quickly.

I get jitters writing Ruby sometimes now because I know I'm fallible and I
have to store so much more in my mind in order to reason about it.

~~~
egonschiele
Agreed. Ruby used to be my go-to scripting language but I've switched over to
Haskell because it's much easier to reason about.

~~~
malandrew
Can you give examples of the scripting tasks you've used Haskell for? Are they
on your github?

~~~
egonschiele
All sorts of command line utilities. For example, here's a timer:

[https://gist.github.com/egonSchiele/6005209](https://gist.github.com/egonSchiele/6005209)

Here's a script that emails me when someone follows/unfollows me on Github:

[https://gist.github.com/egonSchiele/6091917](https://gist.github.com/egonSchiele/6091917)

------
ionelm
Set aside the small examples and theory about what's best, no argument beats a
real world example.

Are there any large opensource haskell web apps that one could read to see how
it really done ?

~~~
gtani
[http://www.joachim-breitner.de/blog/archives/606-Real-
World-...](http://www.joachim-breitner.de/blog/archives/606-Real-World-
Haskell-Applications.html)

[https://www.fpcomplete.com/page/case-
studies](https://www.fpcomplete.com/page/case-studies)

~~~
hbbio
So, the short answer is no.

And there are many reasons to that. One of them: Haskell developers tend to
love the technology and forget about the product.

~~~
asdasf
How do you come to that conclusion? I am all about the product, which is why
it isn't open source.

~~~
dllthomas
Well, I think there's clearly such a contingent, and I think it's more visible
because of Haskell's academic heritage; it may also be larger, but I am much
less confident in that - there are people who love pushing the tech in most
languages.

~~~
asdasf
I think it isn't more visible, it is just more talked about. There is a
perception, not a reality.

~~~
dllthomas
I don't think there's a difference between what you mean by "talked about" and
what I mean by "visible". I am convinced that the perception is there - I
perceive it. I am not convinced that the reality is present - though I am not
entirely convinced it's absent, either.

~~~
asdasf
There is a big difference. Visible means you can see that "contingent"
existing. Talked about means they don't actually exist, but people always
refer to them as though they do exist.

~~~
dllthomas
So you think there is _not_ a subset of Haskell developers who are more
interested in tweaky tech than in practical problems? If that's the case, then
it's true that I disagree with you - as well I should, having observed and
interacted with such people myself.

------
GeneralMayhem
Reminds me of "Step 2: Draw the rest of the fucking owl." It does not follow
that because Hello, World is easy, therefore IO in general is easy.

~~~
gnuvince
Can you explain what you feel is hard about IO in Haskell that isn't hard in
other languages? Sure, you need to get used to the different way of working
with IO (remembering to use <\- instead let, calling return to wrap the result
back into the IO type, etc.), but after some time, it's pretty much automatic.

------
ahawkins
I really need to learn Haskell. Thanks for this.

------
MatthewPhillips
All of the examples of aeson I've seen have been for very simple, flat, json
objects. What happens when you have json with nested objects. Do you have to
create types for each intermediate json object or can you pull the values out
into the top level type? If so how?

~~~
mxavier
When I code in Haskell, the first and most important step I make is to create
rich types for the domain I'm working in. If you disambiguate your types, your
code becomes more readable and the compiler is a lot better able to help you
out when you make a mistake.

For example, rather than having an Invoice with a status field of Text or
String, I have a type InvoiceStatus = Paid | Unpaid | Void. From there, you
can write a very precise parser that takes exactly what you want and nothing
else. When I apply this approach to each component of the thing I need to
parse (or do it generically even), I don't really find myself having to munge
javascript types into my data structures.

~~~
awj
To expand on that, these "custom" types are really the only time you have to
do any extra work for support with aeson. If you leave your status field as
Text or String it's implicitly supported.

That said, aeson support for nullary types (i.e. types that hold no "extra"
values, like InvoiceStatus above) is trivial and the types make a _huge_
difference in the rest of your code.

