The Benefits (not features!) of Programming with Haskell

I’m just a couple of months in, and have written my first production Haskell app, a PDF parser for Oregon laws. Programming it feels different, in a good way. Looking over the list below, two themes — easy and fast — stand out. Compared to OO languages:

  • It’s easy to jump back in to previous work;
  • easy to test my code;
  • easy to refactor;
  • easy to code in a familiar style;
  • the programs are lightning fast;
  • I’m delivering features faster;
  • I can use Atom as an IDE;
  • it’s simple to develop on a Mac and deploy on Linux,
  • it’s easier to understand someone else’s code.

Plus, I just subjectively look forward to it. I think this all adds up to a low mental burden, yet the language is very stimulating.

I decided to focus on “benefits” because really, that’s what we’re all after. This may sound controversial, but I don’t think anybody “wants” referential transparency. That’d be like wanting a regular cleaning service. Instead, what we do want is the benefit; a clean home. Or in programming terms, a clean codebase. So let’s talk about those features now:

The features that enable those benefits

I thought a lot about why I’m seeing these benefits. Here’s a quasi root-cause analysis for them:

Easy to come back to a project and do a little work on it, because of low cognitive load, because everything I need to understand a chunk of code is on the screen in front of me, because of pure functions which have very clear input and output, and because my text editor (Atom) acts as a full IDE showing me the types of every variable and signatures of every function.

Easy to refactor, because I can simply cut and paste functions from one file to another, because there are no globals, only constants, and because the functions — pure and impure — are easy to compose. Also because I can change my data structures and the compiler shows necessary changes in the code, e.g. forcing that every property is set, and to the correct type. Because I can rename anything and the compiler shows every reference needing updating.

Easy to code in a familiar style, because new functions can be composed from others, and new operators can be defined — without sacrificing the other benefits.

I can develop on OS X and deploy on Linux, because the libraries are cross-platform.

The programs are lightning fast, because they’re compiled and because Haskell has lots of optimizations, like laziness.

I’m delivering features faster, because I’m writing much less code, and because I don’t need to write many tests. In Ruby, my test suites are perhaps 2-3x the size of my code base. In Haskell, I’m only TDD’ing and testing particular pieces which can be tricky to get right, like regex-based parsing functions. The compiler tests the rest for me automatically. I’m also writing fewer tests because the code itself is declarative (as well as type-checked). In other words, it reads like a test already, and so a test would only be redundant.

Based on my experience so far, Haskell’s my current language of choice for new server-side code.


I’ve decided to make this the first part in a series about my real-world experience of using Haskell for application programming. I’ll follow up with a post on some of the rough edges in the ecosystem to be aware of, and the best path I’ve found for learning Haskell.

Wifi LAN Performance Test comparing 3 routers and 6 computers

In the past year, I noticed that my wifi had gotten too slow to smoothly ssh from one computer to another. Screen sharing was also very rocky. I began to suspect that either my Macs or my Apple router were seriously under-performing.

Ping times are a great performance indicator for the apps that I use as a software developer: screen sharing, ssh, and file browsing in the Finder. So I bought a couple of new routers, and spent the weekend testing every device in every combination:

Wifi LAN Ping Tests

From my Google Spreadsheet – feel free to comment on it or here.

I set my threshold for excellent performance at 10 ms because that just seems reasonable. And I set my acceptable performance threshold at 30 ms because I can ping from servers in California from my apartment in Portland in that time. So, I thought, I sure as hell ought to be able to send a packet across the room in less time than that.

Crowded Wifi Neighborhood (1)I picked up the two routers at Costco: The Linksys was $70, and the Netgear was $140. The test environment is a 700 sq. foot 1 bedroom apartment. The computers are in a semi-circle around the router location, all at roughly the same distance. The iMac is the oldest. The Macbook Pro 13 is hooked up to an external monitor and its lid is closed. I think it’s logical that those two scored the worst You can see that the network neighborhood is pretty much a worst case scenario.

I see some surprising results:

  • The Mac computers are an order of magnitude (or two!) slower responding to pings.  Interestingly, they have no problems when originating a ping. I haven’t found much online, but this is strong evidence of a problem somewhere in their network stack. These results correspond to my subjective experience connecting to these machines.
  • The Linksys significantly outperformed the Netgear at half the price.
  • It really pays to periodically check your performance and upgrade if necessary. In my case, my newer computers support faster wifi speeds than my old router could support.
  • The newer router doesn’t solve the Mac device problem, but it significantly reduces it. These data don’t show it, but there are now fewer dropped packets, and the variance is ping times is much lower as well.
  • The cheapest, “slowest” computer is the fastest. That’s the Chromebook 14 q010nr, which I bought three years ago for around $250. It’s a fantastic machine in many ways.

DigBang: Safely unsafe Ruby hash traversal

Here’s Hash#dig!, a handy little piece of code I wrote for a project. It’s similar to Ruby 2.3’s Hash#dig, but raises an exception instead of returning nil when a key isn’t found.

places = { world: { uk: true } }

places.dig  :world, :uk # true
places.dig! :world, :uk # true

places.dig  :world, :uk, :bvi # nil
places.dig! :world, :uk, :bvi # KeyError:
                              #   Key not found: :bvi

#dig is to #[] as #dig! is to #fetch

Ruby 2.3 introduces the new Hash#dig method for safe extraction of a nested value. It’s the equivalent of a safely repeated Hash#[].

#dig!, on the other hand, is the equivalent of a safely repeated Hash#fetch. It’s “safely unsafe”😉 raising the appropriate KeyError anywhere down the line, or returning the value if it exists. This turns out to be very easy to implement in the functional style:

def dig!(*keys)
  keys.reduce(self) { |a, e| a.fetch(e) }
end

The full source code

Comparing Kanban apps with GitHub integration

I’m working on this for a client: Comparing Kanban project management apps that have very good GitHub integration. So far I’ve looked at Huboard, Waffle, Zenhub, and Blossom.

Blossom.io is the strongest for our needs due to the detailed cycle time reporting, showing where cards are spending their time. It also has some very useful project management features like marking an issue as “blocked” or “ready” for moving to the next stage.

Screen Shot 2016-01-08 at 12.25.23 AM

Online at Google Docs

Web Framework Comparison Matrix

web framework comparison keyThis is how I evaluate frameworks for clients and my own projects. I’m doing my best to be:

  • opinionated about which features matter
  • unopinionated about the actual frameworks

So you’ll be most likely to find this helpful if you value the same things I do: good CRUD support, good deployment and testing support, and an open and friendly community. Here’s the current matrix, and a link to the spreadsheet online. Help me fill in the remaining items by leaving comments.

web framework comparison matrix 1

web framework comparison matrix 2

I’m thinking about how to preserve the sources and reasoning for each score.

Goodbye “X for Y”: the cryptic Ruby error is becoming friendlier

Anyone who’s used Ruby has seen this message:

r.rb:1:in `name': wrong number of arguments (3 for 2) (ArgumentError)

This particular error has been driving me nuts for years. It’s just so unnecessarily difficult to interpret — especially if Ruby’s not the only language you use. I never remember which number is which.

Compare to Python:

TypeError: name() takes exactly 2 arguments (3 given)

This is better in several ways. The unambiguity; the tone (no “wrong”); the lack of line-noise characters; the plain-English sentence. Note also that the numbers are presented in the opposite order from Ruby. Not a problem in itself, but it makes the Ruby equivalent especially hard to interpret because it requires memorizing the difference.

Potentially as soon as Christmas, though, Ruby’s output look will look like this:

r.rb:1:in `name': wrong number of arguments (given 3, expected 2) (ArgumentError)

This is a great step in the right direction.

It turns out that the issue had been raised two years ago. I gave the topic a bump, and Martin Dürst quickly commited the improved code. I am incredibly appreciative, and happy to see that core Ruby developers value improvements like these. In fact, there’s an open Request for Comments on improvements to Ruby’s error messages.

Infographic: OS X El Capitan License in Plain English

Shortly after I posted OS X El Capitan License in Plain English, I received an email from Bogdan Rauta, a Romanian infographic designer. He volunteered to create an infographic as part of a new project, Infographic Monster News. His idea is to report current news stories in the form of infographics. I’d say he’s off to a good start:

OS X El Capitan License Infographic

Follow my Patreon project for news about upcoming In Plain English posts.

OS X El Capitan License: in Plain English

I decided to upgrade my Mac to El Capitan, but my computer said, on one condition: I must “carefully” read and agree with something. It even provided a tiny cozy display window for viewing it:

OS X El Capitan License dialog

And so I did what anyone else would: I cleared my afternoon schedule and got right down to business; reading, carefully, the entire document. It turns out that I was much too pessimistic! I needed only 33 minutes.

I should note that I’m an attorney with a good understanding of license, trademark, and copyright law. I’m also a software developer with 20 years’ experience. So your own read-through may take more or less time, accordingly.

I thought it’d be a “fun” project to see what the “El Capitan License” actually says. Cool idea, huh? Kind of like spelunking through a cave that everyone says they’ve been through, but maybe no one really has. What will I find wedged in a wall or lurking in the dark around the next turn?

Update: Now in infographic form!
Update: Now as an infographic!
  1. I can’t use the Capitan with illegal copies of anyone’s stuff.
  2. Apple didn’t sell me this software. They still own it, in fact. I’m just borrowing it.
  3. If I install more Apple software, those are on loan as well.
  4. I can use the Capitan in two virtual Machines, and on one computer.
  5. But these VM’s cannot be used for business. The only exception is for software developers (I guess they wouldn’t follow this rule anyways.)
  6. I’ve got to read the separate rules that came with the fonts, and obey them. (I can only borrow those too.)
  7. Those cool voices for the clock? — no remixing!
  8. Slideshows made with Photo; same deal, don’t even think about using them for some commercial purpose.
  9. I can’t sell access to my Mac via any kind of screen sharing.
  10. I gotta run it on Apple hardware (no Hackintoshes).
  11. I can’t help anyone else do that.
  12. I can make one copy as a backup.
  13. I can’t try to figure out the source code to any of this.
  14. I gotta follow all my local laws while I’m using it. (!) (Really? Whereever I live?)
  15. can leave the software on the Mac if I sell it or give it away.
  16. I better not use anyone else’s hacked version.
  17. Apple isn’t responsible for my hurt feelings for anything I see on the web.
  18. If I break any of these rules, this deal is over and I must immediately delete everything.
  19. The Capitan comes as-is.
  20. I can’t send it to Sudan.
  21. I can’t operate a nuclear power plant with it.
  22. I cannot, don’t even think about it, just plain can’t, make money from MPEG/H.264/AVC videos I create. For that, I need to buy another something from somebody.

There you are. I took one for the team.

UPDATE: Thank you to everyone for the great positive response and encouragement to write more.

git commit –amend: Have Your Cake and Eat it Too

For a lot of us, version control does two things which are contradictory:

  • it keeps checkpoints as we work so we can easily roll back, and
  • wraps up our work into a tidy package for others to use.

git commit --amend is one tool that solves this. It will “open up” the previous commit, adding staged files and allowing you to re-edit the commit message.

  1. Make your “checkpoint” commit, e.g. with a failing spec.
  2. Get your specs working again.
  3. Stage your changes like you normally would using git add.
  4. Instead of git commit, do git commit --amend.
  5. Edit the message to describe the feature. This will be the commit’s new message, and it will contain all the changes.

A related command: git rebase -i  (“interactive”). If you didn’t use --amend, you can go back and condense commits together as if you had. With this command, you can interactively rebase, using the “squash” command to combine multiple commits together.

A Benefit of Rails: Surrogate Keys

Today I helped a client wrestle with a database task which concluded:

. . . We’ll have to watch out inventing new “fake” customers because one day there may be a real customer with our made up ID😦

This is a problem in lots of apps, but not in Rails.

Rails enforces the “best practice” of giving every table a primary key named id, which is an auto-incrementing integer. But many non-Rails apps do not do this. Instead, they use some real-world data as the primary key. This is called a natural primary key. E.g., a customer’s social security number. There are arguments for and against this. This is a good little wikipedia page about the differences.

One big problem with natural primary keys is that they often turn out to not be as unique as we think. Plus, then we’re put in the position of “faking” the SS number when we want to manually add customers who don’t have one, e.g. “999-….”. (I remember a college I attended which assigned 999- SS numbers to international students.) And this is the hack that the task description refers to.

In contrast to natural keys, the id field is a so-called surrogate key. It intentionally has no meaning in the real world, and so it has no reason to ever change. It doesn’t matter at all what an object’s id is, just so long as it’s unique. And since it gets set up as an auto-incrementing integer, that will be the case.

So, Rails is “opinionated software” and has made the decision for us. Every table will have;

  1. a surrogate key,
  2. named id,
  3. which is an auto-incrementing integer.

And in one swoop, a whole category of potential problems is eliminated. Secondly, this makes it very easy to get up to speed on a new Rails app.