Don’t Be Surprised That Programmers Don’t Act Like Engineers

It’s obviously true that software is terrible. But we shouldn’t be surprised that software development doesn’t live up to the ideals of engineering when we don’t treat it with the same respect we afford to other engineering professions.

Bogost writes that “methodologies like Scrum never allow that infrastructure to stabilize.” This misses the point.

First, it confuses two different meanings of the word “stability”. Things built by Real Engineers are iterated upon over time too. They just typically don’t catastrophically fail in the process.

But even apart from that gripe, it gets the causation backwards. Software isn’t constantly-evolving (read: breaking) because a bunch of hippies signed the Agile Manifesto and invented Scrum. They created Scrum because their customers’ requirements were changing on a weekly or daily basis, and the straw-man software engineering methodology that looks like what you’d expect a Real Engineer to do (see “Waterfall”) simply does not work in software. Heck, I spent four years of my undergrad and two years of my Master’s program trying to help solve this problem.

So why is this such a unique problem to software? This article already argues why it’s the fault of programmers, so let me offer an alternative explanation.

Maybe businesses simply don’t respect this profession. I know Real Engineers are overworked and have incredibly stressful jobs, but I have a feeling they don’t have to put up with quite the shit software developers do in this area. I am doubtful that a business owner would ever tell an architectural engineer, “That’s a great proposal you have there, but could you construct the building in half the time and with half the concrete you suggested?”

Or that she would be asked to change the height and shape of the building halfway through construction.

Or that she would be asked to just work a few 70 hour weeks and get the building done by a deadline even if it’s missing a few support beams.

Or that a bunch of amateur engineers with no credentials would be hired to construct the building for dimes on the dollar, instead of a single experienced engineer, because they all end up building the same thing, right?

Leave programmers to do their own thing and they can create beautifully-designed, stable software. Sure, some programmers are awful, but not even the best of us are immune to the cut corners and errors that result from working for businesses who tacitly or even explicitly tell them they should cut those corners, because the software budget (you know, to pay for the construction of their entire product) is a fraction of what it should be.

Are those business owners wrong, though? No one will die because Facebook was down for an hour once, or because Twitter ate an AJAX error and didn’t really post a Tweet even though you thought it did. We moan when our computer, like, takes a second to open a thing, much like we moan about cramped seats and bad service on airplanes. But at the end of the day, we obviously prefer low prices to high quality, both when posting pictures of our cats to Facebook and when flying. As long as the plane itself is built by a Real Engineer.

How the Sum of the Natural Numbers Equals (and Does Not Equal) -1/12

You may have seen an episode of the Numberphile YouTube series which talks about how \(1 + 2 + 3 + … = -1/12\).

That episode has spawned an incredible number of discussions and flame wars about a mathematical claim that I haven’t seen since the age-old fight about whether \(0.99\overline{9} = 1\). (Yes, it does.) The nice thing about that debate is there there is an unambiguous, correct answer. Every reasonable way you can define “zero point nine repeating”, it is provably, definitely equal to the real number 1. All there is left to do is make a convincing argument aimed at a lay audience, using an incredibly basic mathematical toolset that doesn’t actually contain the tools you need to prove the claim.

This claim, on the other hand, is much more subtle.

Ember.js Recipes: Light-Weight Data Services Using Dependency Injection

Your application almost certainly uses some kind of data layer (whether it is Ember-Data, Emu, Ember-Model, Ember-Resource, or a solution you rolled yourself), but what do you do when you need to load some data asynchronously, when it isn’t quite important enough to be a model?

For example, when a user edits her profile, you may allow her to choose from a list of countries. This can be a rather long list that you’d rather not hard-code into your application. But it also may feel like overkill to create full-fledged models for this seldom-used, read-only list of data.

What can we do?

Ember.js Recipes: Checkboxable Index Pages Using itemController

A very common UI design pattern is to display an index of items with checkboxes beside them, so that we can select some items and (for example) delete them in bulk.

We may be tempted to implement our template like this:

1
2
3
4
5
<ul>
  {{#each}}
    <li>{{input type="checkbox" checked=selected}} {{name}}</li>
  {{/each}}
</ul>

This certainly works. Each item in the collection will get a selected boolean property, which we can use to filter the collection of selected items.

But there’s something about this that should make us feel gross: each item in the collection is likely a model record, which we are polluting with a new selected property. Suddenly the model layer cares about what is strictly a controller-layer concern. The selected property will persist on the records even when a user leaves the route and comes back to it later. Not only are we abusing the separation between controllers and models, but we are potentially adding nonlocal behaviour to our application.

Ember.js Recipes: On-Demand Record Details With Ember-Data

A common source of frustration in Ember-Data is the inability to load partial records. You probably have a model in your application that only needs a small subset of its attributes serialized in the index response, but which has details that are either data-heavy or expensive to compute, so you’d rather only return them as needed.

String#split and the Principle of Least Surprise

Designing APIs is a tricky business. On the one hand, you want to support common use cases via smart defaults. On the other hand, the API should generalize from the defaults in a sensical way. When it doesn’t, it violates the principle of least surprise and confuses people. Gary Bernhardt uses the word Wat to describe extreme cases of this. When the developers and users of such APIs defend such unintuitive, confusing behaviour, Zed Shaw draws an analogy to brain damage.

Consider Ruby’s String#split. Given a regular expression, it splits a string on matches of the expression. Given a string, it splits a string on occurrences of the string.

1
2
3
4
5
6
7
8
9
10
11
12
str = "Ruby
on Rails"
# => "Ruby\non Rails"

str.split(/ /)
# => ["Ruby\non", "Rails"]

str.split(/\n/)
# => ["Ruby", "on Rails"]

str.split("on")
# => ["Ruby\n", " Rails"]

Except when it doesn’t.

1
2
str.split(" ")
# => ["Ruby", "on", "Rails"]

Wat?

The Ruby docs explain:

If pattern is a single space, str is split on whitespace, with leading whitespace and runs of contiguous whitespace characters ignored.

Splitting a string on whitespace, (i.e. extracting its words) is a common use case, and so perhaps this should have been the behaviour of String#split when called with no arguments. But treating a non-zero-length string as a special case is confusing, surprising behaviour that is pretty much impossible to guess from the behaviour of the same method on any other input.

In other words,

Wat.