Update: Dammit but that’s a great set of comments… Haskellers rock… I wrote this post fairly quickly and didn’t expect it to get quite the attention it got, so please read the comments. There’s a lot of good stuff in them.



Update #2: a comment over on Hacker News points out that the reasons I give are shallow… I agree. It works out that simple, shallow issues can become big issues over time and as a system grows larger and larger. That was exactly the reason I started with Haskell: to wear the hair shirt. As my systems got larger, the shirt just got too itchy.



I picked up Haskell during MIT’s IAP ’04 (during B-school…) figuring that I should learning a new language during the winter. I’m an experienced coder, didn’t need yet another object oriented programming language and couldn’t get OCaml to compile my “hello world” program. Haskell was the first challenging computer language I’d seen in a while and I was quickly addicted (though not quickly productive).

As might be obvious, I haven’t been able to spend much time on Turbinado over the past year. I have been able to spend a bit of time thinking about Haskell and I think that I’ve left the Haskell camp… Here’s why.

Things I Could Do Without

No subclassing of datatypes

In Turbinado I passed an Environment back through the function hierarchy and I wound up building the Environment out of a bunch of Maybe types that I would incrementally fill in.



data Environment = Environment { getCodeStore :: Maybe CodeStore, getRequest :: Maybe (HTTP.Request String), getResponse :: Maybe (HTTP.Response String) }

data Environment1 = Environment { getCodeStore :: CodeStore, getRequest :: HTTP.Request String }

data Environment2 = Environment { getCodeStore :: CodeStore, getRequest :: HTTP.Request String, getRequest :: HTTP.Request String }

data Environment1 = Environment { getCodeStore :: CodeStore, getRequest :: HTTP.Request String }

data Environment2 = Environment1 with { getResponse :: HTTP.Response String }

Yuck… What I really wanted to do was build a number of EnvironmentXs so that I could safely use EnvironmentX or EnvironmentY in a particular function. But I would have to define two separate data types in order to avoid the Maybes:What I really wanted to do is say that Environment2 is Environment1 with a bit more stuff, e.g.:(This has type system implications that I’m sure are more complicated than I’d understand…)

(I’m sure that there’s a monad that could solve this problem, but see below…)

Dependence on Monads is not a Good Thing

Monads are a brilliant idea… on paper. I’ll be the first to say that I think that my level of intelligence hampers my ability to really work with monads, but I’m a reasonably intelligent guy so I suspect that a lot of coders share this complaint. Lots of other functional-ish languages have added monad libraries, but I think that they’ve done so more because monads are useful for DSLs than because monads are a foundational building block for the language.

In the real world, monads seem quite constraining. Composing them is rough and the composed monads are difficult to understand. I’m ashamed to say that one of the first things I did in Turbinado was to tear down the complicated monads that I’d copied from HSP.

The IO Monad makes me unhappy

It’s something that’s been sitting in the back of my mind and I finally let it bubble up. I feel kinda dirty when I use the IO Monad, as though I’m cheating on the language. I understand that functional programs have to do IO and that the IO Monad is an elegant solution… but I’m still uncomfortable. The majority of the functions in Turbinado are in the IO Monad… and that bothers me. Half of my code looks like the following and that makes me unhappy because it isn’t functional-ish:



simpleFunction s = do i <- otherFunction s putStrLn i

Things I Loved

Functional Programming

Why don’t I just use a language that’s friendly to IO? My question exactly.

I’m sold. Seriously. That’s fantastic stuff right there. And without Haskell I would be trapped in Scala-land, writing syntax-sugared-Java, confused about why functional programming was so great…

Purity

Haskell is fantastic because it works as advertised. I considered learning other functional, but was struck by their functional impurity. Looking back on Haskell, I love the design of the language. It’s an architectural masterpiece and you gotta love that (though obviously I’ve decided not to live in it…).

Wearing the Hair Shirt

My hat is off to the Haskell community. SPJ and Wadler did the programming world a service by creating Haskell. Wearing the Hair is hard and it’s very worthwhile. It’s why I decided to learn Haskell and it made me a better, smarter developer.

The Community

Who doesn’t like working with people who’re smarter than they are?

So?

There’s probably more I love about Haskell and more that I could do without, but I think that I’m moving on to Clojure. Rich Hickey has a strong love for functional programming coupled with a good sense of the compromises that can be made for the language to be very productive. The JVM is great: it runs my Rails apps, is speedy, does great garbage collection, etc. I wish it had a dialect of ML or Haskell on it, but I’m going to try to teach myself to look past the parentheses and get back into LISP. It’s been 22 years since I typed a line of LISP, but this dog can learn new tricks… especially with the benefit of the last 5 mind-bending years with Haskell.

Truth be told I’m a little sad. I’ve kinda felt part of a secret society with Haskell and it’s a bummer to be leaving the secret Haskell society…