Code that resists

Kellan Elliott-McCrea, on the way towards an understanding of technical debt, catalogs the ways we end up with code that resists our efforts to change it:

Therefore the second common meaning of “technical debt” is the features of the codebase we encounter in our work that make it resist change. Examples of features that can make a codebase resist change include: poor modularization, poor documentation or poor test coverage. Just as easily though an abundance of modularization (and complexity) or an abundance documentation, and tests encoding the now the incorrect old behavior can apply a strong downward pressure on change.

A little discussed and poorly understood design goal for code is disposability. Given change, what design patterns can we follow that allow us to quickly expunge incorrect behavior from our codebase? Interestingly it is a much more tractable metric for measuring as opposed to more popular criteria like “elegance”. (a post for another day)

Put that in your thinker. Does something like Strategy or Adapter let you throw out whole classes when they prove unnecessary? Or is that so only when you luck out and chose the exact right axes of disposability? Does a microservice really let you discard codebases wholesale? Can maps and functions free you from intertwingled state and behavior or does it move the resistance somewhere else?

Grumpy, opinionated answers: possibly! Even more possibly! Meh. Very meh.

The future of programming is design, teaching, and empathy

The Future Programming Manifesto starts with this header:

Inessential complexity is the root of all evil

OK, I’m on board!

We should measure complexity as the cumulative cognitive effort to learn a technology from novice all the way to expert. One simple surrogate measure is the size of the documentation.

Perhaps we could describe the complexity of a technology in “bookshelves”? For example, in my second internship I met a CleearCase administrator whose office bookcase had one shelf devoted to SunOS, one shelf to Oracle, and the final shelf dedicated to ClearCase itself. How many bookcases for Ruby, Rails, JS, CSS, a database, and all the other stuff you need to know to put a CRUD app in your browser (not even deploy it to the web!)

  • Maintaining compatibility increases complexity.
  • Technical debt increases complexity.
  • Most R&D is incremental: it adds features and tools and layers. Simplification requires that we throw things away.
  • Computer Science rejects simplification as a result because it is subjective.
  • The Curse of Knowledge: experts are blind to the complexity they have laboriously mastered.
  • Rewarding programmers for their ability to handle complexity selects for those who love it.
  • Our gold-rush economy encourages greed and haste.

A weird thing about programmer is that those that rant endlessly about someone else’s complexity, layers, and haste are almost completely blind to the complexity, layers, and haste they make in an effort to set the world just so.

We should work for end-users disenfranchised by lack of programming expertise. We should concentrate on their modest but ubiquitous needs rather than the high-end specialized problems addressed by most R&D. We should take inspiration from end-user tools like spreadsheets and HyperCard. We should avoid the trap of designing for ourselves.

What if more of programming was accessible as data manipulation (cf. spreadsheets, data files, JSX templates) instead of as logic and behavior (i.e. almost every programming language)?

We are doing Design: using experience and judgement to make complex tradeoffs in order to satisfy qualitative human needs.

This reminds me of Developer Experience. “Developer experience” is a weird word right now, but it’s becoming table stakes for success. It’s a design discipline. It’s considering the form and function of code. It’s the opposite of attempting to learn C ;)

Long story short: we’re gonna need more empathy, more design skills, and more teaching skills to reach the next level of great programming languages and tools.

Multiplication over management

When a developer becomes a manager, It’s not a promotion, it’s a career change:

If you want to do your leadership job effectively, you will be exercising a vastly different set of skills on a daily basis to what you are exercising as an engineer. Skills you likely haven’t developed and are unaware of.

Your job is not to be an engineer. Your job is not to be a manager. Your job is to be a multiplier.

Don’t miss the section on how we undervalue non-technical skills. It’s not unlike developing software, it’s just that your levers are people and processes instead of software and data centers. See also, Managing Humans.

The wolf moves fast…

The Wolf:

The Wolf moves fast because he or she is able to avoid the encumbering necessities of a group of people building at scale. This avoidance of most things process related combined with exceptional engineering ability allows them to move at speed which makes them unusually productive. It’s this productivity that the rest of the team can… smell. It’s this scent of pure productivity that allows them to further skirt documentation, meetings, and annual reviews.

See also, The Grinder.

Put. The phone. Down.

Nick Quaranto has Too many streams:

There’s just too many things to pay attention to. I get questioned pretty frequently about this: how do you pay attention to nearly 1,500 people on your Twitter timeline? Here’s an easy answer:

I don’t.

Nick’s conclusion, in short, is to put the phone down. There will always be too many things seeking your attention. You can never Read the Whole Internet. You can only hope to mark it as unread and go on with your life. Hence, just put the phone down.

I came across this little trick where you get all the stuff you tinker with off your phone’s home screen. All functional apps, no social networks, no web, no mail, nothing that’s going to grab your attention. Software calmness, per se. I’ve done it for a week and love it so far. I highly recommend it, if you have the means.

Conservation of complexity

You can’t fight the Law of conservation of complexity:

The law of conservation of complexity in human–computer interaction states that every application has an inherent amount of complexity that cannot be removed or hidden. Instead, it must be dealt with, either in product development or in user interaction.

Turns out one of my criticisms of microservices and microlibraries is a law. A LAW PEOPLE, YOUR ARGUMENT IS INVALID. Hilarious narcissism aside, keep an eye out for practices whose tradeoffs don't fit inside the depth of reasoning a blog post (like this one!) afford. Turning monoliths into services begets operational challenges. Microlibraries beget choices and wiring things up. Maybe the former is your thing, maybe it's the latter. Tradeoffs happen!

Executables deciphered

What's inside a compiled Hello, World program? Julia Evans is on that. How to read an executable:

Executable file formats are regular file formats that you can understand. I’ll explain some simple tools to start! We’ll working on Linux, with ELF binaries. (binaries are kind of the definition of platform-specific, so this is all platform-specific.)

I thought I had a rough grasp of how executables worked, and I still learned things. I love this format too. Julia Evans writes these fearless, curious posts about the deeply mysterious underpinnings of our computers and I learn a lot every time. More like this, please!

Make systems from goals

Use systems to get where you’re going, not goals:

My problem with goals is that they are limiting. Granted, if you focus on one particular goal, your odds of achieving it are better than if you have no goal. But you also miss out on opportunities that might have been far better than your goal. Systems, however, simply move you from a game with low odds to a game with better odds. With a system you are less likely to miss one opportunity because you were too focused on another. With a system, you are always scanning for any opportunity.

Applies to personal life, biz, programming, hobby, whatever. Use goals to figure out what systems you need in place, then get habits and systems going to make those goals, or something better, happen.

Yet another way you can use your skills as a developer to construct a system that really solves the problem, and not a symptom of the problem!