My Functional Programming Story

Posted on January 29, 2014
The most honest thing I can say about my dabbling with functional programming is that it was all spawned out of boredom.  Towards the end of last year, I was getting very rapidly bored of the computer science curriculum at my previous school, which I had been following for the preceding two years.  Java is (compared to many) an inherently boring language, and progress in both classes I had taken in it was slow.  I decided that I had had enough of that, and started to search for something more interesting.  A close friend recommended I work through MIT’s Structure and Interpretation of Computer Programs, aka SICP.  I started it, and quickly became obsessed.  You see, SICP is a book written for learning Scheme, a LISP dialect and a functional programming language.

The difference was profound.  I was used to specifying algorithms as a sequence of instructions.  I would try to generalize, as that instinct had been pushed thoroughly into my brain earlier on through some means I don’t quite know.  But there was always something missing.  Object orientation did lots, but getting globs of code to fit together the right way was still arduous, and I always had to be careful that I didn’t mess up some fact of the global state in setting it up.

What’s more, there was recursion.  I was an absolute novice in the world of recursion.  Having only seen recursion in a world without first class functions or tail call optimization, it seemed to me to simply be a memory-expensive way to solve problems that probably would be better solved by a well placed loop.  Functional programming was a breath of fresh air.

So I started working in Scheme, and I enjoyed it.  But, in the process of learning Scheme, I found myself reading a lot of blog/forum posts talking about functional programming and this weird other language called “Haskell”.  At first I dismissed it.  It reminded me too much of working with Java (static typing seemed arduous and horrible, and it had gasps SYNTAX).  When I started to reach a more stale part of SICP (dealing with mutable state), I found myself looking into tutorials for it and thought “eh, might as well give it a try”.  After a bit of trouble at the start, I actually found myself enjoying Haskell even more than I had enjoyed Scheme.  Typeclasses and the Hindley-Milner system made static typing less painful, and the difference in amount of testing required pushed it to being a net positive.

So I played around with Learn You a Haskell and a few other sources for practice problems, and before I knew it I was solving some relatively simple problems in Haskell.  But that wasn’t all.  I needed a project, something to work on for more than a few afternoons.  I was starting to get interested in compilers, but knew I was nowhere near ready for writing one of those, so I decided an interpreter was the next best thing to make.  And, whaddaya know, writing a Scheme interpreter turned out to be a common way of transitioning out of the beginner stage of Haskell development.  So that was fun.

So I guess this is the part where I compare my experience with Scheme and Haskell as forays into the functional.  I’m certainly glad I started with Scheme.  Sure, it’s not as “pure” but the lack of syntax allowed me to think only about the program logic, which was a big enough transition from the kind of reasoning I was used to doing while programming.  I’m not sure I’d have taken to Haskell anywhere near as readily at first.  In addition to that, Scheme has the advantage of being eagerly evaluated.  While I might prefer lazy evaluation now, it would have been yet another thing to understand before I could effectively reason about what was going on.  So I would definitely recommend learning Scheme or some other Lisp first.  That being said, if you want to get good at programming, here’s the most important part: make sure it never stops being fun.

Lastly, I feel this concept must be addressed in any discussion about learning Haskell: Monads.  I don’t really understand what all the hullabaloo is about.  They’re honestly not that difficult.  That moment when you really get monads is a fun one, and really changes the way you look at computing from then on, but it doesn’t seem like they really deserve the altogether nasty reputation they’ve gained.  I remember, when I was but a schemer and not a haskeller as well, thinking that Haskell was actively against being useful.  Why did I think this?  Because everyone I had ever heard writing about monads said they were silly constructs that just made everything more difficult.
Simon Peyton Jones often likes to say that the biggest mistake they made in developing monadic I/O was to use the word “monad”.  Taking terms from category theory leaves lots of people scared that they’ll have to understand difficult math to do anything useful in Haskell.  This isn’t true, and don’t let anyone trick you into thinking it is.  Understanding category theory will enrich your understanding of Haskell’s type system, but it certainly isn’t necessary!

Another thing worth noting is that Haskell is what really forced me to understand package managers and command line tools.  The lack of any serious IDE or similar batteries-included setup had me stuck wandering around trying to find different ways to fix everything as it broke.  I think I went through three different installs of the Haskell Platform.  If you’re on OS X, install it with Homebrew.  Seriously.  When you’re trying to fix whatever cabal-install broke this time, you’ll thank me.  It also forced me into using general purpose text editors like Sublime (my first editor) and later Vim.  If it weren’t for working in a language without an IDE, I might never have switched.  Boy, was I missing out.  Learning a general-purpose editor makes it so much easier to just take a language and go, whereas if you felt too bound to your IDE you might spend the first several days trying to find one that you considered satisfactory.

This is a story in progress, as I haven’t stopped coding and I don’t see myself abandoning functional languages anytime soon.  My most recent endeavor is to start playing around with making a (relatively rudimentary) computer algebra system.  Expect updates on that as I work more on it (and maybe even a bit of literate code!)