Wow, it’s gotten really hard to find time to post to this blog. 2014 was a pretty interesting year for me, but I really didn’t have time to document much of it here. The reasons are manifold:

Anonymity Concerns

I’ve tried to keep this blog quasi-anonymous so that I can be honest and unmerciful in my writing without offending anybody—particularly the folks that make it possible for me to pay my rent. ‘Evade Flow’ is an anagram of my real name, and I scrupulously avoid mentioning past or present employers in my blog; however, enough people now know who evadeflow is that I feel the need to be more circumspect in what I choose to post publicly.

As an example: in 2014, for the first time ever, I was on the bad side of a massive layoff. Surprisingly, it turned out to be a really great experience overall. But not every aspect of it was so great, and it was tempting at times to ‘blog in anger’. I’m glad I resisted, because I’m so happy with where I landed just six weeks later. Despite anything negative I might have been tempted to say about the company that precipitated my having to scramble for a new job—during the peak of holiday season, no less—I truly wouldn’t have it any other way now. (Funny what a difference just a couple of months can make!)

Better Documentation Tools

One of the biggest reasons I started this blog was the sheer volume of ‘stuff’ one needs to remember to survive as a software developer, and the relative dearth of places to put it. In this era where all jobs are temporary, it’s important to me that hard-won knowledge remain with me when I move on to the next opportunity. A lot of company-sponsored documentation repositories I’ve worked with in the past have been ‘input only’, meaning: it was easy to put stuff into the system, but getting it back out later, in a form that’s still useful, was either difficult or impossible. All that changed in my last job where we used Confluence, which supports the notion of personal pages and has an Export to PDF feature. This was great, because I could put general purpose programming tips and techniques in my Confluence personal pages and share it with my peers, but still keep PDF copies for myself.

NOTE:  I was permitted to archive these documents because:

  1. They contained zero proprietary information or trade secrets. They were just things like, How to Use pymox for Unit-Testing in Python, and How to Configure a Local Jenkins Server for Running Custom Pre-commit Hooks.
  2. I got permission to do this before accepting the job, as a pre-condition of my employment. (Copying company documents without prior authorization is not something I would recommend to anyone.)

Anyway, I discovered that making my ‘cheat sheets’ available to colleagues had some nice benefits. In many cases, I could answer a question sent via an email or IM message with a URL rather than a multi-paragraph exposition. This freed up time for me to do more useful work, which was nice. But the most surprising aspect of using the company documentation repo for personal notes was: some of them started to ‘go viral’ within the organization. Before I knew it, links to my pages were showing up all over the place, and a few of the personal practices I’d written about began being touted as ‘best practices’ in official company documents! This was eye-opening. I mean, all I did was write stuff down. I didn’t do any heavy-handed evangelization or schedule meetings to talk about any of it, but I still managed to achieve outcomes that would have required mounting a whole campaign in some of my previous jobs. I’m probably vainer than I like to admit, but… this was pretty gratifying.

I’m a More Experienced Engineer Now

I started this blog almost seven years ago, just after the first iPhone was released. Obviously, a lot has changed in the tech world since then.  But the biggest change has been: myself. I thought I was pretty hot shit back then, but now I just laugh at how wet behind the ears I was. And still am. And always will be.

I approach software development with much more humility than I used to. My attempt to learn ‘everything’ has failed so miserably that I’m less concerned than ever before about capturing What I Know in blog form. Instead, I try to craft software that is almost boring due to its lack of complexity. The one lesson I’ve learned after more than 15 years in this racket is: complexity is the enemy! For me, blogging was an attempt to do battle with the complexity all around me by creating some kind of structured narrative out of it—my own person bible of ‘What I Believe’. As a coping mechanism, it helped, but… in the end, it’s pretty ineffectual compared to other techniques for managing complexity.

What techniques, you ask?

  1. Do the ‘done’ thing. Don’t chase after the latest-and-greatest who-sie-mah-what’s-it tools and frameworks, or—worse—use existing tools in some bizarre way, whether through ignorance or arrogance. We all have a deep-seated need to believe that what we’re working on is somehow ‘special’, and requires more mental acuity to write than “some shopping cart app”. For most of us, this simply isn’t true. Don’t complicate things unnecessarily by writing ‘clever’ code (“for efficiency”) that flies in the face of the conventions of whatever language you’re working in. In the end, this is neither clever nor efficient. It’s just plain dumb. If you ‘do the done thing’, your code doesn’t need a lot of exposition.
  2. Have automated tests. This is the thing that most changed my life as a developer. For the first ten years of my career, I tested my code by running the host application, observing the side effects it had on the world, and trying to decide, based on those observations, whether it was correct. You can develop significant applications this way (lots of people/companies still do), but I now see it as arrogant and wasteful. All developers test their code—somehow—before they commit.  A developer that doesn’t run each potential change through some sort of confidence-building regimen before committing won’t survive in this industry. But there are still too many good developers who vet their commits using an ad hoc, unstructured process whose artifacts are largely hidden from their peers. In contrast, unit tests are an executable encoding of  a confidence-building regimen that travels along with the code and is available to the whole team. I often hear programmers invoke the DRY principle with statements like: “This is getting out of hand—we have to use a templating engine or code generator to eliminate this duplication!” Routines for vetting the code’s health are no different: they should not be duplicated on a per-developer basis, where each developer has a pet pre-commit ritual that’s slightly different than every other developer’s.
  3. Do not worship the False God of Code Reuse. I can’t count how many times I’ve seen this scenario play out: “Hey, we keep needing to do ‘X’ in our code. Why don’t we make a library for doing ‘X’ and just have all our teams use that? If we structure it right, it could even become a new product!” Just because I, personally, have never seen this work out as intended doesn’t mean that it can’t. It’s just a really low-probability scenario. Writing code is difficult in general. Despite the titles of some popular books on the subject, programming isn’t something that ‘dummies’ can ‘learn in 24 hours’. And if writing end-user apps is hard, writing generic, reusable code components is, like, really hard. Ninja-level hard. The number of hardware/OS combinations your ‘reusable’ component needs to support suddenly becomes unbounded. And the the home-grown deployment process you were using to get the component into your own applications isn’t likely to sit well with would-be customers, so you have to create installers for each OS you intend to support. Sure, this is doable, but… if your current business model is one where your revenue primarily comes from sales of purpose-built, end-user software, you may be in for a rough ride. It will most likely require expertise that your company currently lacks, so be prepared to invest significant resources into any code reuse effort before seeing even a nickel’s worth of revenue. And if your teams aren’t unit testing the code they’re already writing… well, maybe your organization isn’t in the best position to author The Great American Framework just yet. Perhaps your investment dollars would be better spent on some in-house training.

Frameworks Are Becoming More Prevalent

The last reason I’m blogging less is that software companies are increasingly splitting into two categories:

  1. Independent software vendors (ISVs) selling end-user software, and:
  2. Companies that create the platforms/frameworks used by ISVs.

The quality of the frameworks put out by the latter group have been getting steadily better. Most of today’s  frameworks have outstanding documentation, and the vast majority of them follow some form of the Hollywood Principle—that is, they expect to call into ISV code rather than the other way around. Software development has, in large part, become a process of selecting an appropriate framework and ‘seasoning to taste’ by sprinkling in custom, domain-specific code in the form of callbacks or configuration parameters.

I suspect frameworks have grown so much in popularity due to the difficulty of writing reusable libraries. Every application has a set of ‘rules’ that the code added to it must follow. And frameworks generally get to make those rules. Shared libraries, on the other hand, get inserted into ecosystems that already have a set of  rules governing their components. Even the finest minds in the software industry have a hard time creating libraries of generic code that can be inserted into systems whose threading, scheduling and prioritization mechanisms can’t be known in advance. Frameworks ‘flip the script’ by dictating many of these basic considerations that have traditionally been left up to app designers.

Anyway, in a world where high-quality frameworks abound, I feel less inclined to document my ‘discoveries’ about any given framework. I might feel like documenting a quirk that represents a particularly rough edge, but… chances are that time would be better spent checking to see whether a bug/issue has been filed for it, and creating a ticket if one doesn’t already exist. The rough edges in frameworks tend to get sanded down over time, so today’s annoyance may go away completely in the next release. I’ve seen this happen often enough that it blunts any desire to blog about frameworks—unless it’s to vent about one that’s particularly awful. For the most part, though, I’m happy to write Flask apps, or Qt apps, or Django apps—whatever—and Read The Fine Manuals.


Bookmark this one, too:

I came across it while looking for ways to mock Boost.Asio classes. This was the SO post that led me to it:

Looks like a tightly targeted duplication assassin, and a nice alternative to, which I’ve used a few times to good effect.


Python Unit-testing Notes

December 17, 2014

For awhile now, I’ve been meaning to write a tutorial on unit testing in Python aimed at experienced devs who already know why they should be doing it, and just need to know how to go about it in Python.  This document is as far as I got; it gives a passable overview of how […]

Read the full article →

Comments Not Displaying in WordPress 4.0 with Thesis 1.7

December 17, 2014

Sometime after upgrading to WordPress 4.0, I discovered that comments were no longer showing up on my blog. This is a Note To Self™ regarding what I did to fix it. This page described exactly the problem I was seeing, but I’m using an even older version of Thesis. Fortunately, the same fix worked, with […]

Read the full article →

Apple’s Christmas present to me

December 13, 2014

Ermagherd!! I stupidly decided to update my MB Air to Yosemite yesterday and it broke everything I care about  (Qt Creator, Vim, VMWare Fusion, XCode and homebrew) while adding a bunch of annoying pfaff I’ll never use. (I can now sign PDF’s by scrawling on the trackpad? Seriously? ’Cause that looks awesome.) As a developer […]

Read the full article →

Stupid Vim Tricks Volume XXX

December 1, 2014

Some more esoteric Vim commands I’ve recently learned: CTRL-Y duplicates the previous line, column-by-column CTRL-E duplicates the next line, column-by-column CTRL-A inserts again the previously-inserted text CTRL-R= evaluates an expression typed by the user and inserts the result I knew about the normal mode behavior of CTRL-Y and CTRL-E, but didn’t know they could be […]

Read the full article →

kdbus Update

November 26, 2014

I’ve written about this before (here and here), but the situation with respect to D-Bus latency has evolved quite a bit since then. The first and second salvoes of kdbus patches have been submitted, and it looks more and more likely that  D-Bus support will—in one form or another—make its way into the Linux kernel. […]

Read the full article →

GSL for Code Generation—and more!

February 15, 2014

UPDATE: February 21st, 2014 — I happened across another solution to the same problem: It also looks quite interesting, but may be intended for a narrower set of use cases… I ran across the GSL project today and fell heavily in like.  I’m starting to get really interested in code generation as a master-level […]

Read the full article →

Overcommit and OOM on Embedded Linux

November 8, 2013

We have a lot of code at work that checks the return value of malloc() for NULL, but I’ve come across a fair number of posts claiming that this is pointless on most Linux systems because the return value of malloc() is very often a lie (due to overcommit being enabled). This article explains the […]

Read the full article →

Static analysis with clang/scan-build

November 6, 2013

My buddy Jim-James asked me how to get CMake to use clang today, and we wound up figuring out that this works: cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ .. Well, it works if you do this first: sudo apt-get install clang Anyway,  the cool thing is, clang’s diagnostic output is much more verbose/helpful than gcc’s. I knew this […]

Read the full article →