You can't solve technical debt, you can only hope to contain it

Staring Down Technical Debt:

Technical Debt is an interesting phrase.   We all have a sense of what it is instinctively, but we rarely want to think about it.  If we think about it too hard, we feel somewhat oppressed by entropy.  All systems tend to toward disorder and software systems are no different. The big question that we all face is what to do about it. 

Systems tends toward disorder. Disorder is hard to reason about and risky to deal with, i.e. you’re likely to avoid dealing with it at all. But, most successful products have a system with more technical debt than you’d like at its center.

Increasingly, I think that the only way to confront technical debt and complexity is to contain it. Languages and tools only seem to help at the margin. Rigorously splitting large, complex, debt-filled systems into smaller, proportionally complex and debt-filled systems is the way to gain traction.

You can’t solve technical debt or essential complexity; you can only hope to contain it.


Needs better words

How much easier would Haskell be if its vocabulary wasn’t so deeply rooted in abstract mathematics? How many more people would immediately understand Cassandra if it just adopted the vernacular of row-oriented databases instead of overriding it with column-oriented semantics? Wouldn’t the programming world be better if every language didn’t call itself object-oriented?

So many programmer-facing things could be better if they had better names for concepts. The power of good naming:

Characters are cheap, confusion is costly. Let’s not make things harder for the programmers who come after us. Remember, this is just as likely to be ourselves in a few months. Let’s avoid using a name like prj when project is only four characters more typing. Anything that reduces reading friction in our code is a good thing.

The cynical view is, we are actively confusing and inhibiting ourselves when we use names that are too short, not clear, or outright wrong. The optimistic view is that there’s a progression we can take from not knowing what something should be named, to giving it an acceptable name, to using the naming process to discover better structures.

If you ever hear me say something “needs better words”, it means that I think the idea is right but the labels are wrong. A philosophical dialog may ensue, where I struggle to discover what the essence of the idea is. The end goal is a word that is concise, has the right connotation, and whose meaning is obvious and accessible to as many audiences as possible.

I love naming things.


The qualities of better code

What is 'better' code? Dave Copeland on the qualities readable, changeable code exhibits. Of the attributes he identifies, I think number of paths (ABC complexity) is the most important for reading code and fan-in/out is the most important thing to manage for easily changed code.


Gimme clarity

Wise pal Brain Bailey, along the way to writing about Woody Allen, perfectly articulates my challenge in thinking about how a team should work:

The combination of clarity and freedom is what makes work a joy; one without the other is where you find frustration. When you have great freedom, but an incomplete understanding of the goal, you’re likely to invest hours of effort in a futile attempt to hit a target you can’t see. You know this is the case when you see revisions requested again and again, or products that are perpetually delayed.

On the other hand, a clear goal with little freedom in how to achieve it produces uninspired work by dispirited people. The lack of freedom is experienced as a lack of trust and confidence. People in these environments will eventually seek out new places to work.

Personally, I oscillate between attributing failed projects to too much freedom or not enough freedom. It’s not about that at all. It’s about the balance of that freedom and clarity. If I’m given freedom without clarity, I run off and invent something interesting but impractical. If I’m given over-constrained clarity, I get discouraged.

(Freedom is a funny thing on teams and projects. I have a lot more freedom than I usually think, but I’m still very conservative in acting on that freedom.)

I recently asked my team lead to give the team I’m on a stronger direction in which to go. We already had most of the freedom we needed. We talked over how we could proceed as a team and came up with a direction that was useful for the other teams around us and not so far afield from our current momentum as to discourage us. My morale immediately doubled and I think our team did some good excellent work once we had that strong direction.

Whether you’re managing yourself, managing a team, or managing your manager, asking for clarity is a thing I you should do!


The feel of a commented program

Opening a nicely documented source file is like opening a well-designed, nicely printed book. The main text is obvious, but the side-notes are there to help you when you aren’t quite catching where the author goes or when the author wants you to go read up on something else for context.

Opening a file that needs few comments is like opening a notebook. It’s the raw form of an idea. A few people can pull this off, distilling a program down to its essence.

Both are charming in their own way. The challenge is to know when you’re producing a book and when you’re writing in your notebook. Write for yourself first, then edit it up or down for the reader.


Some productivity winners

Three things that are making me more productive lately:

  • Pick a thing and do it. Whatever you want to accomplish today, do it immediately after you wake up. No social media, no food, nothing. Work on it for 30-60 minutes and then get on with your day. I’d mentioned this before, but I fell off the horse and needed to get back on.
  • No visible clocks. Not in menubars, not in toolbars, not on walls, not on screens. I totally perceive time in a different way when I’m don’t perceive each minute as it passes.
  • Pre-work pep talk. Before I sit down to do something, I talk myself through how I’m going to solve the problem, what the scope of this session is, or think through how I want to structure the thing I’m making. If I do this, I’m much more likely to stay on task, shrug off roadblocks, and avoid distracting myself.

Go forth and crush it.


Sit on the fence between abstraction and practice

Theory and Practice is about a fence. It’s tempting to steer all the way towards the abstract, academic side, or all the way towards cutthroat practical side. Some of the most intriguing, productive people I’ve known sit on either side. Both sides like to accuse the other of not producing results, but that’s subjective. An academic’s results are wholly different from a practitioner’s results.

On occasion, you’ll run into someone who can actually explain complicated theory stuff to you in an accessible way. If you find someone like this, make sure to hold onto them closely, as they’re really rare. But they can help provide you with some insight that will really boost your productivity, without having to invest all the time in figuring out all that wankery that the priests of theory love.

This is a really nice way of explaining why someone like Richard Feynman is awesome. He was equal parts discoverer and explainer (plus another equal part mischief). This is exactly the thing I aim to achieve when I write here, make code, or present at conferences. There’s a whole bunch of ideas that aren’t in practice but, presented and packaged properly, can help move a lot of practitioners forward while recognizing the work of academics and nudging them to keep working in that area.

A lot of good things come out of connecting the people on opposite sides of the fence. Sitting on a fence isn’t exactly graceful, but sometimes it’s the only way to move ideas along. Don’t be afraid to eschew purity or pride for progress.


Get in my ears, you dissonant chord

Petrushka chord. Two major chords played a half-tone apart. So, it sounds good, except it sounds grating. It's a motif throughout Stravinsky's ballet Petrouchka. Ergo, like everything Stravinsky, get in my ears! Listen to it and learn more about the chord from the awesome "Feynman of classical music" (I just made that up) Leonard Bernstein.


Dustin Curtis' recipe for doing

Do. Your short, sharp inspirational mantras for the week.


RubyConf 2012 notes

My notes, in a somewhat sketch-esque fashion, from RubyConf 2012. I hope they’re useful and/or amusing to you!

[gallery link=“file”]


Pop discovery/rediscovery

Programming is like pop culture in the sense that Blondie gets reinvented every decade and every decade client-server computing is rediscovered. But it’s also like pop culture in that every once in a while something radically new, like hip-hop or STM, appears and eventually is absorbed into the mainstream of the pop culture. I’m ok with that.


Marginal pennies and dollars

The give a penny, take a penny jar is a logical conundrum. It is not, on its surface, a rational thing. I have no data, but I suspect very few people who put money into them are doing so because they plan on taking money out later. A bank is different from a give/take a penny jar.

Personally, I put money in because I can and because I fancy myself not a jerk. The latter is what makes more rational sense. I put money in because it’s utility to me is marginal, but the utility of feeling better about myself is non-marginal.

In My Blue Heaven, Steve Martin plays a semi-reformed mobster in the witness protection program. He starts compiling a book of his truisms for living life. One is “it’s not so much tipping I believe in as over-tipping.” His character does this partially because he’s a little flashy, and partially, I think, because he has to be a likable protagonist.

I’d like to be a likable protagonist too, but I like over-tipping whenever possible for another reason. Pretty much anyone who works for tips is working really hard for every dollar they make. An extra dollar here or there is trivial to someone with a desk-job like myself, but less trivial to tip-earners who are technically paid less than minimum wage. An extra five or ten percent on a single tip won’t change their life, but it probably doesn’t hurt either.

I like making people’s day better with laughs and smiles, but I’m not above buying a tiny fraction of a better day for someone else. Marginal pennies and dollars add up.


Ruthlessness and fighting for it

You Are Not Ruthless Enough:

Being ruthless to yourself means every time you say “oh, I’ll just open up this internal bit over here…” use that moment to give yourself whatever negative feedback you need to go back and write the correct interface. Imagine the bugs you’ll get later. Give yourself a 12 volt shock through your chair. Picture the sleepless nights chasing down an issue that only happens for that one guy but it’s the guy who signs your paycheck.

I dropped this in my drafts folder months ago and came back to it today. It’s still something I need to hear. Get it working, and then ruthlessly edit and refactor until it’s code that won’t cause you to cringe when others bring it up.

In improv and code, I’ve recently come across the notion that there are things we need to fight for. Fight, not in the sense of conflict, but in the sense that there is an easy or natural way to do something, and then there is the way that maintains our sense of pride and quality. Not necessarily the “right” or high-minded way to do something, but the way that does not leave us feeling compromised as a creative person.

Your homework is to write down the qualities important to you, the ones that make you proud of your work and happy to share it. Then work from this checklist every day:

  1. Write the code, rehearse the scene, play the song, etc.
  2. <li>Decide whether it expresses your qualities.</li>
    
    <li>If it does, ship it. If it doesn't, edit ruthlessly until it does.</li>
    

Rinse/repeat/tell everyone about it.


Working with Ruby's GVL

Visualising the Ruby Global VM Lock. A nice commit-by-commit look at how extensions for Ruby 1.9 work with the GVL, what that looks like as tests run, and how to release the GVL to allow for better parallelism.


A pithy take on development vs. operations

The essential, face-palming difference between too many development teams and too many operations teams is thus:

Development: “I know how it works, but I don’t know how to make it work”

Operations: “I know how to make it work, but I don’t know how it works”

Be the solution, friends.


How Ruby IO is formed

Ruby's IO Buffering And You! Jesse Storimer screencasts his way through what happens when you read and write to files and sockets in Ruby, explaining the behavior and spelunking through Rubinius' implementation of IO. You'll learn stuff. If you want to learn even more stuff, check out Jesse's new book Working with TCP Sockets. Jesse is fantastic at describing Unixy things concisely; you'll like it.


Follow the smells

It’s handy to know a lot about programming langauges, patterns, “best” practices, and anecdotal experience in applying those ideas. But premature application of ideas can lead to its own bad experiences and new anecdotal evidence. How can you apply ideas without falling into the premature architecture/optimization trap?

Follow the smells.

You know what a bad method looks like. You know what slow code looks like and how to find it. You can tell when a class is doing too many things. Follow those smells.

Once you’ve smelled it, you’ve dealt it. Kidding!

Once you’ve found a culprit that is imminently making your life as a developer harder, you have to explain it to someone else. Tell them why it’s slow, badly coupled, or too much architecture. Once they’re convinced, then you can reach into that deep knowledge of languages, patterns, practices, and experience to fix the problem.

You commit the code, push it to production, and do a happy dance. You’re not done.

Now you need to share it. Write down what you did and share it with your team, lest the problem happen again. Show your co-workers how to find the problem elsewhere and quickly dispatch it.

If you do it this way, you’re helping yourself three times:

  1. You fixed the original problem
  2. You showed your colleagues how to fix the problem or how to avoid creating the problem
  3. You showed your colleagues how to make measurable, if minor, progress in making your application better without the need for drastic projects

Follow the smells. Fix the smell. Put the fix in everyone else’s brain. Repeat.


A handful of useful project mantras

You could do a lot worse than following the heuristics set out by this Software Architecture cheat sheet. The tip I need to follow more often is "Is There Another Way"; I frequently get way too caught up in my first idea, which is usually too simplistic or requires too much architecture. The tip I often try to guide people towards is "What If I Didn't Have This Problem?"; routing around problems or trying to reduce them to problems that require less code is a super-powerful judo chop.


Know a little hardware

Consider:

  1. Google's intricate and massive data center operations, wherein Google is not only leading the pack in building distributed computing and database infrastructure, but building massive operations to run those systems.
  2. <li>"People who are really serious about software should make their own hardware." Alan Kay, creator of Smalltalk, object-oriented programming, and many other things that are good in your software development life, said that.</li>
    

I think Alan Kay’s quote could be rewritten for modern times to say, “Those who are really serious about large applications should make their own datacenters”. Assembling hardware, putting it into racks, putting the racks into data centers, and building out your own data centers are the analog of building your own hardware for software service companies these days.

You probably don’t need expert-level knowledge of these disciplines to write software today (e.g. I know diddly-squat about how packets find their way through the modern internet). You will, however, have a leg up if you’re aware of the possibilities and know how to take advantage of them. Even if you’re building applications with modest capacity needs, knowing how to set up a failover database and when to pay for physical hardware instead of virtualized hosts is a thing that will make your customers and clients happy.

More concisely: when it comes to running your software on hardware, one size does not fit all; know how and when to tailor your application to the hardware, no matter what size your application wears.


A kingdom of concerns

When doing object-oriented programming and following SOLID principles, there is sometimes a concern that classes will proliferate and you end up with a Kingdom of Nouns.

I find it more concerning when there is a proliferation of concepts. Too many layers, too many patterns, too many frameworks. The best designs I’ve seen provide just one or two concepts that manage to tie everything together without breaking orthogonality.

The great thing about Rails and Sinatra was that they boiled previously conceptually heavy domains down to a simpler, better set of ideas. In doing so, they move you up the hierarchy of needs, so to speak, and you still end up inventing your own concepts and nouns. More on that soon!