Engineering with Empathy: how do we decide when to fix?


It’s a sappy title, but bear with me. I’m wondering if the best lessons of diversity and inclusion can be applied to software development? For example, if something is offensive to others, then it’s worth looking for an alternative — even if I’m not personally offended.

I witnessed an interesting disagreement on a software project: Some developers joined a project with a large codebase which had been up and running for a while. They stumbled upon an aspect that made it harder for them to understand. These new-to-the-project devs proposed a small change:

Why is this named Dwankie? It keeps tripping us up. Can we rename it to ApplicationConfig? It’d be a lot clearer.

The group’s current decision-making process: Is no clear majority dissatisfied? Then keep the status quo.

The long-time devs disagreed with the change. They acknowledged that it would do no harm. But in their view, the code was understandable enough as is. Interestingly, every dev who was unbothered by the odd naming advocated keeping it. They also argued that this wasn’t an important issue. I saw this argument boiling down to, “we don’t think it’s a problem”. This struck me as analogous to “I don’t find it offensive” in the context of inclusion. And so I’m thinking it’d be similarly invalid. The change was disallowed.

A better way to decide: Is a significant group dissatisfied? Then we allow change.

Thinking about it, “But is a different group of people ok with things as they are?” is not a good guideline. Instead, we should use a rule of thumb based on empathy when deciding whether to act: A sizeable group of people who are dissatisfied with the status quo is enough reason to support change. We shouldn’t require a unanimous or even a majority vote. rabbit

Why I don’t use let/let! in my RSpec

At work, we’re deciding on our test-writing style: let/let! blocks like let(:arg) { 5 } vs. instance variables defined in a setup method like @arg = 5.

  • I’ve found no advantage to let; but I have experienced disadvantages.
  • I’ve found no disadvantages to instance variables.

And so, 👍 for instance variables.

I’ve written many specs and have read the rspec docs, many times.

I don’t use let/let! because

  • the purported advantage of lazy evaluation is never actually realized. I’m most always running all the tests in a file, and so there’s no time efficiency gain;
  • the API [let and let!] and their magic increase the code’s complexity and so must be balanced out by some other advantage;
  • Let introduces magic and apparently nondeterministic behavior which has broken my tests, and I’ve only been able to fix by converting to easy-to-understand @- variable instantiations.
  • Let has the problem of introducing non-ruby syntax — something that looks like an automatic variable isn’t one anymore.

So for me, let is fixing a problem I don’t have, and in doing so, introduces new problems.

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) }

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. 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.