Friday, November 20, 2015

Why Haskell?

I'm finally at a point in my life where I begin work on a legitimate side project.  It will be a web app (of course), and the back end will be in Haskell.  This probably seems like an odd choice being that I have very limited Haskell experience, and its reputation for being difficult to learn.

Because I will be the only one that's working on the project, I have my pick of any technology I want to use.  There are a large number of obvious choices I passed over in favor of Haskell.

1. JavaScript:  I have extensive experience building services on top of Node.  I use it every day at work.  Its performance is more than adequate for what I am trying to do, I'm familiar with the technology, and it would be a really good choice if I wanted to get my project up and running as quickly as possible.

I don't actually hate on JavaScript in the way I hear a lot of people doing.  It supports lexical closures, first class functions, and has a lot of neat reflection stuff that lets you do some really cool things.   The ecosystem is huge, and most of the things I will be doing are already solved by somebody else.  Overall I think it's a solid choice, but... I use it every day.  I might as well try something new if I am going to work on something in my spare time.  In addition, there are some other issues with JavaScript that make it less than ideal for my purposes.

It's incredibly dynamic.  It will let you do pretty much anything and not fuss at you.  While this is good, it means all the cognitive load for ensuring program correctness falls on your shoulders.  You have to be way more vigilant for bad data at every point in your program. JavaScript has a ton of edge cases.

In addition, having a solid test suite is not optional.  It's the only way to ensure you are able to extend and refactor without breaking stuff.  This adds another maintenance burden, as well as making it harder to add new features.  I want something that gives me a little more confidence when I need to go in and replace the guts of something.

2. Python: I also have a lot of Python experience.  It has some solid web frameworks, and good libraries.  Once again we have some very cool language features that make programming in it very nice.  Python pretty much makes everything easy.  It also has stronger types (though still dynamic) and isn't as loose about what you're allowed to do.

However... as I've evolved as a programmer, I've found that Python doesn't always support the style of programming I like to do.  It can be strict in the wrong places, and relies heavily on constructs that I don't really like using (e.g. for loops everywhere).  Python's design isn't well suited to functional programming, even though it's features technically support it.  It feels strained.  It also has the same issues of cognitive load that JS has (though slightly mitigated).

3. Ruby: I could learn Ruby, but what's the point.  Although I could be convinced otherwise, it seems very similar to Python and JS.  It's a dynamically typed, object oriented scripting language and comes with the benefits and drawbacks associated with that.

4. Java: I know it's really popular, but I'm really just not interested in learning Java until I need to pick it up.  Plus, it just isn't a fun enough language for me to dedicate my free time to right now.  Working in Java every night would feel too much like work.

5. Scala / Elixir: These are the two other languages I seriously considered besides Haskell.  I think either could have been a good choice, but my existing experience in Haskell really drew me in that direction.

So in the end, with all that out of the way, why Haskell?  Well, for all the same reasons most people say they like Haskell of course.

1. Its Type System: Having a strong and flexible type system can really cut down on the amount you need to think about when writing code.  You can define exactly what you will be getting, and what you will be returning, and the compiler will keep you honest.  In addition, having the type signatures there is just plain helpful when reading and using code.  It acts as basic documentation that must be kept up to date for your code to compile.  Servant anyone?

2. Its Purity: Again, this should be obvious.  If I'm going to choose Haskell, I probably like that it's pure.  But seriously, purity is incredibly helpful.  It makes your code easier to reason about, it allows for more code reuse, and it lets you build your code base with minimal complexity.  It can feel restricting, but it helps avoid breaking the principal of least astonishment.

3. Refactoring: Seriously, refactoring Haskell code is a joy that must be experienced to be understood.  This really is a consequence of #1 and #2 above.  I almost always refactor my Haskell code as soon as I write it, once I see the patterns I'm using.  I'll probably do a post on refactoring after this one, but the bottom line is that refactoring can be done constantly without worrying about breaking your code.  The safety and ease in refactoring will be incredibly helpful as I am building out and maintaining a large system.

4: It's Fun:  Writing Haskell is an enjoyable experience.  The syntax is clean and elegant, the idioms make sense, and your code ends up looking like a description of what your program does, rather than just a series of steps to be performed.

I'm looking forward to learning more about Haskell as I build out my system. It's a very deep language, and so far I've only scratched the surface.