Great software teaches

Great software solves a problem that you have — plus problems you didn’t know you had.

Here’s an example: today on Twitter, a friend let me know about a broken link to one of my old posts:

The broken link lives in someone else’s blog post, so I can’t update the source. It looks like the link has been broken since I migrated from Blogger to some months ago. Darn!

Ideally, the old link would redirect to the correct one, the one Gary found after a bunch of looking. This would fix the internet (just a tiny bit).

How hard is it to make that work?

Look at this beautiful plugin that appears right at the top when I search for “redirect”:

Redirection plugin. It has a million zillion installations

Perfect. I installed it (thanks to $23/month to for my business site) and entered the two URLs and poof, the redirect worked. That took under 10 minutes.

But wait! There’s more!

During the installation it asked me whether I wanted logs of 301s (requests to my site that got redirected to the right place) and 404s (requests to my site for a page that is not found). Yeah, sure.

After entering the one redirect I knew about, I saw it work in the log of 301s. Then I clicked on the 404 report, and in that couple minutes it had already noticed two more broken requests!

part of the 404 report. It shows the link I just fixed plus two others I did not expect

So I fixed those too! Hovering over the link in the report even gives an “Add redirect” option that populates half of it for me. Amazing.

This Redirection plugin is great software. It worked to solve my specific problem. It teaches me more about the wider problems I’m having, and helps me solve those too. Brilliant.

Rebase on the World: personal shell choice

“Why use bash when you have PowerShell?” <– words I did not expect to hear from my own mouth.

Over the past few weeks I’ve begun learning PowerShell, and it’s an improvement over the UNIX (and family) shells, bash and ksh etc.

PowerShell is newer. It builds on what those shells did right, and then gets it more right.

The UNIX-y shell commands have this magical power of composition: you can pipe the output of one to the input of another, and chain these to build tiny programs right on your command line. One sends text to STDOUT, the next reads it on STDIN.

PowerShell does this piping, except with objects instead of lines of text. The data is structured and interrogable (I can ask it what fields it has). In bash, you output your data as text, and the next program parses that text.

Here’s an example from Chapter 1 of PowerShell in Action. In bash, the sort command can parse the piped text and sort on it. You can specify numeric sorting.

ls -l | sort -k 5 -r -n

In PowerShell, the sort command works on named properties of the piped object. And it knows the type of the property, so nobody has to tell it what’s a number.

ls | sort -Property length -Descending

More: PowerShell standardizes parsing of command-line arguments. This gives me consistency when I use the command, and saves painful work when I write a command.

More: PowerShell gives me multiple output paths, one for data (to the next program) and another to the user who typed the command. In bash, commands like git abuse STDERR to send info back to the user.

When PowerShell was only for Windows, by far the most powerful command-line shell for me was bash (or fish or zsh, pick your favorite). Bash worked in the worlds I lived in, and that matters most. Now that PowerShell runs on Mac and Linux, it is the most powerful command-line shell for me … except for one thing.

The biggest thing bash has on PowerShell is: I already know bash. I can type stuff there and it just works. With PowerShell I have to look things up all the time.

But every time I look something up, I increase my abilities. PowerShell raises the floor I build on, compared to bash.

It is always a tradeoff between sharpening the tools we have, vs trading them in for a better model. In this case, I’ll take some slowness in the beginning for a faster top speed.

By switching, I gain advantages that the software world has created since I started programming twenty years ago. I rebase myself on the latest version of the world.

Rebase on the World

We build our software in a particular world, a world of technologies that we link together. We choose a programming system (language, runtime, framework), libraries, and environment. We integrate components: databases, logging, and many different services.

Perhaps we built it on Java 8 running on VMs in our datacenter, connecting to a proprietary queuing service we bought years ago. We start with what is available and stable at the time.

But do we stay there?

The outside world moves capabilities toward commodity.

At some point, new businesses start building cloud applications instead of racking their servers.

An opportunity appears, and our enterprise can get out of the infrastructure business. When we shift our application onto AWS, there are whole areas of expertise we don’t need in-house. There are layers of infrastructure that Amazon maintains and upgrades, and we rarely even notice.

At some point, we integrate with new systems. They don’t speak our proprietary queuing protocol, so we move to Kafka, something that people and programs everywhere can understand. And at some point, new businesses don’t run Kafka; they rent it as a service.

When we move to SaaS, there’s a layer of expertise we don’t need to retain, pages we don’t have to answer, and upgrades we don’t have to manage. Or even better, maybe our needs have changed, or SQS has improved until it’s good enough. We get free integration with other AWS services and billing.

Is our software simpler? I don’t know, but it’s thinner. The layer we maintain is closer to the business logic, with integration code to link in SaaS solutions that other companies support.

All code is technical debt.

Every line of code written is in a context. Those contexts change, and expectations rise. New tools appear, and integrating them gives us unique abilities. Security vulnerabilities go noticed.

For the software we operate, we are responsible for upgrades. It is our job to keep libraries up to date, shift to modern infrastructure every few years, and add the features that everyone now expects.

What you get for operating custom software — you control the pace of change.  
What you pay  — you are responsible for the pace of change.

Maybe it’s authorization, or network configuration, or caching, or eventing. You wrote it back when your needs were exceptional, and now it’s your baby, and you’re changing its diapers. It takes effort to shift to anything else.

Incorporate the modern world into our software’s world.

When capabilities become commodities, it becomes cheaper to rent than to babysit them. It’s probably monetarily less expensive, and indeed, it’s less costly in knowledge. People and teams are limited by how much experience we can hold. We can only have current expertise in so many things.

On a development team, we can increase our impact by overseeing more and more business capabilities, but we can only operate so much software. If we thin that software by shifting our underpinnings to SaaS offerings, then we can keep up more of the software that matters to our particular business.

All code is technical debt. Let it be someone else’s technical debt. Move it off your balance sheet, to a company that specializes in this capability.

Rebase on the world

In git, sometimes I add some features in a branch, while other people improve the production branch. When I rebase, I put my changes on top of theirs, and remove any duplicate changes.

I want to do this with software infrastructure and capabilities. The outside world is the production branch. When I rebase my custom software on top of it, it takes work to reconcile similar capabilities. But it’s worth it.

When we rebase our software on the world, we get everything the world has improved since we started, we get integrations into other systems and tools, and we get learnings from experts in those capabilities. SaaS, in particular, has a bonus — we keep getting these things, for no extra work!

If we don’t rebase on the world, a startup will.

How can a scrappy little company defeat a powerful incumbent?

Every piece of software and infrastructure that the big company called a capital investment, that they value because they put money into it, that they keep using because it still technically works — all of this weight slows them down.

A startup builds on the latest that the whole world offers. They write minimum code on top of that to serve their customers. The less code they have, the faster they can change it.

In the 1990s, we built a big stack of custom work on top of a solid base. In the 2010s, we build less custom software to get the same business capabilities (with more reliability) because we’re building on various AWS services and many other tools and services.

This is not the only advantage a startup has, but it is a big one.

Software is never “done.”

Software is not bought, it is rented. (Regardless of how the accounting works.) It gives us capabilities as long as it keeps running, keeps meeting expectations, keeps fitting in with other elements of the world that need to integrate with it.

Keep evolving the software, infrastructure, and architecture. It is never going to be perfect, but we can keep it moving.

When I’m coding a feature, I rebase on the production branch every few hours. For software systems, try to rebase on the world every few months, bit by bit.

In an enterprise with a lot of code, this is an extra challenge. Change at that scale is always an evolution.

If you find yourself thinking, “we have so much code. How could we ever bring it all up to date?” then please check out Atomist’s Drift Management. Get visibility into what you have, and even automatic rebasing (of code, at least). There’s a service for this too.

A large amount of this information came out of a conversation with Zack Kanter, CEO of Stedi.