Book Review: Learn You a Haskell for Great Good!

No Starch Press was kind enough to mail me a review copy of Learn You a Haskell for Great Good!.

Rating: 10/10

Miran Lipovaca has done a fantastic job of writing a book aimed at beginning Haskell programmers. I like his very straightforward writing style of introducing each topic with the minimum of complexity.

As you probably already know the book is available online for free at so the question becomes why purchase the dead tree copy? To be honest I don’t recommend buying a dead tree copy if you have a Kindle.

To summarize there are three ways to read the book:

  • Dead tree
  • EBook
  • Online

My preference in order is the e-book on the Kindle, the dead tree version, and finally the online version. For some reason I don’t like the formatting of the online version as much as either the dead tree version or the ebook. It’s partly because I have a harder time reading books on the computer than either on the Kindle or in paper back.
No Starch did a great job of printing “Learn You a Haskell for Great Good!” on quality paper and the binding is excellent. As with all previous No Starch books I’ve purchased the physical layout and ink quality of the book are both excellent.

The table of contents is:

  • 1. Introduction
  • 2. Starting Out
  • 3. Types and Typeclasses
  • 4. Syntax in Functions
  • 5. Recursion
  • 6. Higher Order Functions
  • 7. Modules
  • 8. Making Our Own Types and Typeclasses
  • 9. Input and Output
  • 10. Functionally Solving Problems
  • 11. Functors, Applicative Functors and Monoids
  • 12. A Fistful of Monads
  • 13. For a Few Monads More
  • 14. Zippers

Miran does an amazing job of keeping each chapter short and interspersing lighthearted comments. The table of contents should be self explanatory, as you can see he covers mostly just the fundamentals of Haskell and ends with Monads. There is the extra chapter on zippers which seems like an afterthought.

Comparing this book to Real World Haskell, they serve slightly different purposes. “Real World Haskell” assumes that you are already reasonably proficient as a programmer whereas this book introduces each topic without assuming much programming background knowledge. Also “Learn You a Haskell for Great Good!” is meant less as a reference text and more for reading from start to end. They are both fantastic books and I highly recommend reading both of them. “Learn You a Haskell for Great Good!” is a gentler introduction to Haskell and I recommend reading it first.


2010 in Review

I got this kinda of cool email about my blog stats.

The stats helper monkeys at mulled over how this blog did in 2010, and here’s a high level summary of its overall blog health:

Healthy blog!

The Blog-Health-o-Meter™ reads Wow.

Crunchy numbers

Featured image

A helper monkey made this abstract painting, inspired by your stats.

The average container ship can carry about 4,500 containers. This blog was viewed about 18,000 times in 2010. If each view were a shipping container, your blog would have filled about 4 fully loaded ships.

In 2010, there were 16 new posts, growing the total archive of this blog to 74 posts.

The busiest day of the year was January 20th with 673 views. The most popular post that day was Writing A Compiler In Haskell (Compiler Series Part I).

Where did they come from?

The top referring sites in 2010 were,,,, and

Some visitors came searching, mostly for line segment intersection, writing a compiler in haskell, nginx, nginx mono, and mono nginx.

Attractions in 2010

These are the posts and pages that got the most views in 2010.


Writing A Compiler In Haskell (Compiler Series Part I) January 2010


Line Segment Intersection May 2009


Having Fun with Happy (Compiler Series Part III) April 2010


Configuring Mono and ASP.Net on Nginx February 2009


Playing with Alex (Compiler Series Part II) January 2010

Operating Systems Project Postmortem

I finished an operating systems course a couple weeks ago. The main component of the course was the group project. The course project was to implement the following (which I copied from the syllabus):

The system is designed to remotely monitor and control the servers deployed in the ECS (our school’s computer science network) local area network. It
is expected to have the following features:

• A Web interface to enable the IT administrator to remotely manage the Linux and the Windows servers in real time;

• The management interface enables both performance monitoring and system control.

• The Performance monitoring component collects, manipulates, and displays statistics of a server and its applications such as CPU, memory, disk, and network utilization.

• The system control component enables the IT administrator to remotely execute commands against the managed servers, e.g. login, shutdown, restart, basic file management, etc.

The below diagram shows the system outline:

The class was organized into three teams (1) Windows agent, (2) Linux agent and the managing server, (3) Web server.

I was the team lead for team (2). The timeline of the project was the beginning of September through the first week of December. Which gave us a little more than 3 months. Our professor Dr. Ouyang had us give a sequence of demos during the three months and then submit a working system at the end.

What We Did Right
As the team lead for my team I instituted use of for revision control. was a great choice, it’s an amazing site. The source code is available at

The web team used Dropbox for source code collaboration. Dropbox was a reasonable choice but they had to track revisions of the software manually so they ended up with directory names like “Website V017”. The Windows team was a mess they didn’t have any centralized collaboration system until the end where google code was used,

Another thing we did right was that my teammate Vinit Azad did a great job of specifying the interface between the agents and the managing server. This made it much easier to split the work up and have individuals program to the interface.

What We Did Wrong

  • We didn’t impose hard deadlines. This caused portions of the project to be pushed later and later. At the end this caused integration issues where we were working on the managing server and the webserver while we were trying to integrate them.
  • I didn’t fully specify the interface between the managing server and the web server. This caused problems when we integrated the two. It would have been much easier for the website team if I had specified a complete interface to the managing server that they could have programed against. This would have made integration significantly easier.

I would recommend setting a weekly schedule upfront with very specific milestones for each week with each milestone a portion of the project grade. The milestones should not be verbal confirmation that the milestone goals have been finished. Instead each team would email the professor their code with instructions on how to run it. With the code the professor can independently decide what part of the milestone goals have been finished. It is important that the team leads are not the ones to determine if the milestone goals have been completed because they are not independent evaluators.

The results of our class project were mixed. I could have done a much better job with specifying the interface between the managing server and web server. I didn’t realize until the end the importance of first specifying the interface and then coding to the interface. Given the constraints that it was a class project –so most of the team members had only had about one day per week to work on it– I believe a well defined schedule is very important to determine if the teams are falling behind and if so in exactly what areas.

Reasons to Keep a Blog and How to Get Beta Users

Number one, if you like to write and I do, then it’s fun. But as Steve Yegge outlines in his post “You Should Write Blogs” it’s also good for you. I won’t repeat Steve’s points but I do want to add one point and that is a blog is a very easy way to keep track of little tidbits of information that could otherwise be hard to refind. As an example all my posts on mono, nginx,, and mvc were written purely because I did not want have to try and find the information again or try and dredge it up from my poor memory. Instead I wrote the posts and now whenever I need to reconfigure a server to use nginx with mono and I can easily find the information on my blog. In a way it’s an extension of your memory, it’s a permanent easily searchable record of what you have done.

In that spirit I’m linking to Patrick Swieskowski and Sascha Kuzins’ post, How we got 18,000 beta users in 4 weeks. Now when I need to look up how to get beta users I can simply search my blog and find this article.

Multiple Ways to Do It

By do it I do not mean sex! What dirty dirty minds you all have. Infact I want to talk about the dual of limiting user choice. My post on limiting the number of choices a user has to make, has an obvious corollary in that you want to give the user multiple ways to accomplish a task.

A classic example are the cut-copy-paste operations. Windows/Linux/Apple all have three distinct ways to cut/copy/paste.

1. Select the text and goto the edit menu and select the cut/copy operations. Similarly goto the edit menu to paste.

2. Select the text and then use the right click menu to select the cut/copy operations, ditto for paste.

3. Use the keyboard shortcuts for the cut/copy/paste operations.

There are the three different ways to cut/copy/paste because, depending on the user they will prefer one way or another. Also if there was only one way to cut/copy/paste many users would never figure out how to cut/copy/paste.

Also the keyboard shortcuts are for power users (you can see this by observing run of the mill users who almost never use the keyboard shortcuts).

I want to make clear that the purpose of having multiple ways to do a task is to allow for the variance in how the users of your application think. As designers we want our application to be appealing to all of its users. This implies that we must have multiple ways to accomplish tasks because our users have different mental models of how the components of our application fit together. For example in Firefox you can create a new tab by (1) File-> New Tab menu, (2) Ctl-T Keyboard, (3) right click on link and click New Tab. Firefox needs all of these different ways to create new tabs because some users want to use the File menu, some want to use the keyboard and some want to right click. Any one of these ways is the “right-way” but the only way to keep our users happy is to include all three.

This post is almost the dual of the my post on limiting user choice. A big part of creating a good user interface is in finding the best balance between limiting choices and having multiple ways for users to accomplish their tasks.

Database Wrapper Objects

It’s common to use small wrapper objects around database tables. One object represents one row in the database table. For the sake of clarity the following is a simple example:

Database: Documents table, with columns (Id, FileName, Data). Where Id is an identifier for the object, I use a <a href=””>Guid</a&gt;.

A simple wrapper object for the Documents table would have the following pseudo code

class Document {
property Id
prpoerty FileName
property Data

The only issues are how to create new Document objects, how to save Document objects, and how to retrieve Document objects.

Since I’m young and stupid I had the wrong solution for all three problems.
First I created a separate Database class with static methods for Retrieving, Adding, & Updating Document objects. This becomes unmanageable when the number of wrapper objects for the database gets above 10.

The correct solution is to
1. Create a Save() method for the Document class that intelligently either adds the document to the database or updates the existing document in the database. Thus the user of the document class doesn’t need to remember if they’re updating an existing document or creating a new document.

2. Have a single constructor for the Document class that accepts an Id. This constructor then creates a new Document object if that Id does not exist in the database or retrieves the existing Document object from the database if that Id is in the database.

By doing the above the creation and saving of Document objects is entirely consistent. This reduces the cognitively load on users of the Document class so they don’t have to think about the details of how Document objects are created and stored, instead they can concentrate their effort on other things.