The Tool is Right

July 10, 2021

Tooling to assist software development has never been more available or more advanced. Tools, both commercial and open source, have been purpose-built to identify code that is provably incorrect (and even code that might be incorrect). Some examples of C++ tooling available from LLVM:

This is a minuscule list in comparison to what’s available from LLVM and elsewhere. The problem is not, therefore, that the tools don’t exist. The problem is not that the tools don’t report any errors when used either.

The problem that I see more often than any other is that developers don’t believe what the tooling reports.

I don’t know why. Is it pressure to ignore all roadblocks in delivering a feature on a deadline? Is it hubris? Laziness? Is it some mistrust of the tooling itself?

I don’t suspect malice. But I don’t know the answer.

Is the tooling always perfect? Absolutely not. That doesn’t change the advice I’m going to offer:

Assume the tool is right.

If you dig into what’s being reported and believe you have a case where the tool is wrong, you should be able to completely explain why it’s a false positive. If you can’t confidently provide that explanation, check the error report again. At some point you will conclude that your code is at fault (almost always the case), the tool is pedantically correct about your code but the consequences are benign (fix it anyway to remove the noise), or the tool has a bug (which you should file).

And if you have a tool that’s consistently wrong, stop using that tool.

It’s all about perspective. A well-built code analysis tool is better than a human at detecting errors. For some, that’s hard to accept.

For others, myself included, we recognize that we need all the help we can get. Start by assuming the tool is on your side. That perspective will let you understand (and benefit from) what it’s telling you.

On Marshal Yanda

July 8, 2021

Robert Mays, in a 2017 profile of Marshal Yanda for The Ringer:

He also is a man of ingrained habits. To hear Wagner tell it, players don’t need a clock to know what time it is in the Ravens’ facility. All they have to do is locate Yanda at a given moment, and it’s obvious. “Hot tub, breakfast—it was the same thing every day,” Wagner says.

[…]

Listening to Yanda talk about the league’s best interior rushers, it’s clear that his homework goes beyond due diligence. It borders on obsession. Each week, Yanda downloads his upcoming opponent’s previous six games to his iPad. With no need for internet connection, he’s able to consume game tape anywhere. “In the corner of the hotel, or the training room, or at lunch, he always had that iPad,” Wagner says. Yanda’s favorite spot is the cloth recliner in his living room, where he takes in about a game a night while his wife, Shannon, watches Nashville from the couch after their three kids have been put to bed. “You never want to be surprised by a guy,” Yanda says. “I want to know every single move that he does. When it’s third down, and they’re down by seven points, and they need to win and get off the field, what is he doing to win? What has he naturally done his entire life?”

Let’s ignore the fact that Yanda played for a bitter rival of the Steelers.

A theme from it has stuck with me since reading it years ago: Yanda’s craftsmanship.

Yanda, now retired, was dedicated to being a great NFL guard. His discipline and his willingness to embrace the grind were exceptional. And while professional football is a wildly different career than software development, craftsmanship translates universally.

The craftsmanship ingredients are always the same: discipline, habits, and focus.

You’re Not Backing Up Enough

July 6, 2021

Jason Snell, at Six Colors:

I know you’ve heard it a million times before, so many times that you skim past it when you read it. And you’ll probably do it again this time, but I’ve got to try. I’m looking out for your best interests here.

However much you’re backing up your Mac, you’re probably not backing it up enough.

Purely coincidental timing, but this is a nice addition to the link I posted earlier today.

A Modern Backup Strategy

July 6, 2021

Adam Engst, writing at TidBITS:

Allow me to update what I consider to be the pieces you can assemble into a comprehensive backup strategy that acknowledges the reality of today’s tech world.

In summary:

  • A versioned backup, such as Time Machine
  • An offsite backup, such as Backblaze
  • A backup device, such as a secondary Mac or an iPad
  • Cloud-accessible essential data, such as iCloud Drive for photos
  • A nightly duplicate of the primary Mac, via software such as Carbon Copy Cloner or SuperDuper!

I’ll admit I spend a lot more time than the average person thinking about data loss (personally and professionally). But to me, the above list is not overkill. Everyone within the Apple ecosystem should be using the first four, and I strongly recommend all five.

This reminds me of a post from the author of SuperDuper!, Dave Nanian:

Don’t let your data loss story serve as a warning to others. Be the hero who planned ahead and saved your family’s precious photographs.

How to Read Assembly Language

July 6, 2021

Scott Wolchok:

Why, in 2021, does anyone need to learn about assembly language? First, reading assembly language is the way to know exactly what your program is doing. Why, exactly, is that C++ program 1 MiB (say) instead of 100 KiB? Is it possible to squeeze some more performance out of that function that gets called all the time?

There’s also an increasingly relevant ARM64 version.

Embrace the Grind

July 6, 2021

Jacob Kaplan-Moss:

People said I did the impossible, but that’s wrong: I merely did something so boring that nobody else had been willing to do it.

Sometimes, programming feels like magic: you chant some arcane incantation and a fleet of robots do your bidding. But sometimes, magic is mundane. If you’re willing to embrace the grind, you can pull off the impossible.

This is the most important trait of a software developer. The willingness to embrace the grind, every day, is more important than technical knowledge or skill of any kind.

(Via Daring Fireball.)

Sweat, Focus, and Fantastical

May 31, 2021

Apple’s money and resources are effectively limitless. They have the ability to create any piece of hardware or software they desire to create.

Almost.

I don’t think Apple could have made Fantastical, the calendar application that won Mac App of the Year. Fantastical is a great app, but its greatness does not come from being a revolutionary re-imagining of a calendar. It isn’t that. Its greatness does not come from one specific feature that can’t be found anywhere else either.

Fantastical is great because the people who made it sweat the details.

Flexibits, creators of Fantastical, put in the work. They carefully thought through how users would perform each action a user needs to perform with a calendar. They designed an interface with smooth, delightful animations. One that is always responsive to input, and clearly presents the required information. Every user interaction, every interface detail, every small code change that improved performance: they all add up to Fantastical.

The word that keeps coming to mind with Fantastical is polish. This is what the most polished calendar app you could imagine looks and feels like.

Apple sweats the details on a lot of things. But “polished calendar app” is not going to sell a new iPhone (and thus won’t receive the engineering resources to make it happen). The target they’ve chosen for most of their default software is “good enough.” That creates an opportunity to create something for users who want more than “good enough.” A subset of users want the best calendar app.

Like Apple, we can’t focus on every detail of every project. But like Flexibits, we can seize opportunities to sweat details that others don’t.

First ask where you can sweat the details. Then ask where you should.

Order Matters

May 8, 2021

I was recently reminded that integer division is…well, integer division.

Local variables, a globally defined constant, and function parameters (all holding integer values) made this problem more difficult to see in my case, but here’s a simple example:

#include <stdio.h>

int main() {
    int result = 1000 / 10 * 5;
    int reordered = 5 / 10 * 1000;
    printf("result is %d\n", result);
    printf("reordered is %d\n", reordered);
    return 0;
}

Typing the result and reordered lines into a calculator will give you an identical result: 500. It’s easy, especially during a quick code review, to ignore the types, mentally execute both lines and conclude they are functionally identical. So easy in fact, that one might forget that with integer division order matters:

result is 500
reordered is 0

Remember, both explicit and implicit values are integers in such calculations.

// int result = 1000 / 10 * 5;
// ((1000 / 10) * 5)
// ((100) * 5)
// (500)

// int reordered = 5 / 10 * 1000;
// ((5 / 10) * 1000)
// ((0) * 1000) <----- 0.5 cannot be represented as an integer
// (0)

With named values instead of integer literals in this example, it’s easy to imagine a mistake like this reordering issue slipping through.

This is partly a reminder of the importance of unit tests (or regression tests of some kind). Ideally an incorrect change introducing this behavior would be caught immediately. Well-written unit tests are great for pointing out simple bugs like this, though I am making an assumption that this bug would break a functional requirement of the code under test.

But this is mostly just a friendly reminder that with integer division, just like many other pockets of programming, order matters.

Where to Start

April 17, 2021

If you are new or early in your programming journey, these are the things I suggest learning first. They will benefit you no matter what kind of programming you ultimately do.

Learn C

If you understand the fundamentals of computer science, namely data structures and algorithms, you have the ability to understand and use any programming language.

But while that’s true, learning C will give you a practical programming knowledge that computer science theory will not. After learning C you can mentally translate every other language’s behavior to C (for example, parameter passing). Another benefit is the C language can be learned in its entirety (something I would never say about C++).

As someone who has primarily developed systems software for my entire career, perhaps I’m biased. But I believe C is essential knowledge for every programmer.

Learn a scripting language

Programmers need to write tailored but ephemeral programs on a daily basis. The ability to automate some kind of work with minimal investment to create the automation is invaluable.

That’s why I recommend deeply learning a scripting language. I mentioned that any language is on the table for someone who understands the fundamentals, and that’s true. But paying the get-up-to-speed cost every time you need to automate something is expensive.

Python, Perl, and Ruby are examples of scripting languages that can do this work. My personal favorite is Python, but give these and others a look. Pick one that suits you, and master its basics to the point that you don’t need to look much up to use them.

Learn a shell

Technically a shell script is just as capable as the scripting languages I mentioned above, but I use them differently. Using even the most basic data structure will feel more comfortable in a true scripting language. Shell scripts are useful for, well, automating the shell. But that’s incredibly useful.

The shell is the driver for so many programming tasks. Understanding Unix commands, how to chain them together, and how to automate it all will make you a more efficient programmer. (Saving your steps as a shell script is also a great way to remember how to do something.)

Depending on your environment you may have not complete freedom of choice, but I recommend learning one of: bash, zsh, or fish.

Keep learning

I recommend C, a scripting language, and a shell as some of the first things to learn. They provide a foundation for future learning, and improve your productivity.

But remember, the world of computer science and programming is too big to completely master. None of us will learn it all, and that’s fine. The much more important advice I can give is, no matter what you’re learning, to keep learning.

Keep learning.

Persistence

April 7, 2021

Persistence is a critically important quality of a software developer.

Debugging, for example, demands persistence. It’s a grind.

The first architecture of a system will never be correct. Neither will the second. It takes persistence to design and re-design to the right one.

It also takes persistence to continually show up and do your best work. If you do the best work you can every day, you are ahead of most of the industry. And if you’re not doing the best work you can, what are you doing instead?

Spicy

March 29, 2021

During my first week at my first job, I met one of the senior developers on my team.

He asked me if I liked spicy food.

“Not really,” I responded.

He paused.

“You’ll never make it in this industry.”


I love spicy food today.

Of course, you don’t have to enjoy eating any type of food to make it in software. But be it debugging a difficult problem or discovering the obvious mistake that held you up the last three days: you do need to have a tolerance for pain.

The Agenda Slide

March 27, 2021

A small tip for creating a slide deck: delete the agenda slide.

I know it’s in the company’s default template, and everyone else uses it.

But a presentation is an opportunity to build your message to its conclusion.

Why spoil that by opening with your blueprints?