Writing Is Writing

Writing Is Writing

Ed Tramell April 24, 2018

Hello, readers! I’m Ed Tramell, a longtime software engineer (and first-time blogger) at Wazee Digital.

Ashley Bailey started our company blog back in 2016. At some point, she asked me if I’d like to be a contributor because she would love to have more engineering representation in the blog.

I said, “Uh … who, me?” (But that was just in my head.) My real answer was, “Sure, I’d like to do that. But … I don’t know what I would write about.”

Months went by. I was definitely interested, and I kept thinking about blogging. I enjoy crafting words almost as much as I enjoy crafting programs. Yet I remained dubious. I just couldn’t think of a topic that seemed blogworthy.

More months went by. Ashley nudged/reminded/encouraged me, saying she liked my writing style. I thanked her for the compliment, but I also dismissed it with this explanation: “Writing in English doesn’t feel all that different from writing computer programs.”

She said that sounded like a pretty good topic right there. I closed my suddenly slack jaw, thought for a moment, and then agreed. It just might work. And now here I am, writing about … writing.

So … Writing in English doesn’t feel all that different from writing computer programs? I can feel your doubt from way over here. Let’s explore what I mean by that.

I write code

Almost everybody deals with computers these days. Even people in non-technical fields have some idea of what it means to “write code.” I’m sure many different people would express it in many different ways, but it would probably boil down to some variation of this: “Writing code means giving a set of instructions to a computer.”

I wouldn’t call that the most complete or accurate definition, but it’s a good start.

By the way, I often wish we programmers could stop calling it “code,” because that word implies our work is necessarily cryptic or mysterious. (“Pay no attention to that man behind the curtain.”) But everybody calls it code these days, so I’m going to have to call it code too. Just know that I mean “code” as in “computer program,” not “code” as in “cryptic.”

I write English

Programming isn’t all I do. A sizable part of my job involves communication with other humans. Some of that is verbal, but a lot of it is written.

I write proposals for new software features and improvements. I write analyses of other people’s proposals. I write bug reports. I write notes about my findings after I fix bugs. I write questions and change requests when I review code for other developers. (And now, I guess I write blog posts, too!)

Another “by the way”: I use English, so I’ll be saying “English.” But rest assured, I mean “human language” in general.

The myth

I’m lucky to have inherited seemingly contrasting talents from my parents — my very technical father and my very literate mother. I’m equally lucky that they both cared enough to be heavily involved in my education. (I probably didn’t always appreciate it at the time, but I sure do now.)

As a result, I lean toward the technical side (hence my career choice), but I can also convey my thoughts in writing. Of course, unearned talent isn’t enough, and skills degrade over time no matter how early you acquired them. I still make mistakes in both kinds of writing. I always will, but I keep working to learn and improve. The point is, I enjoy writing both code and English, and I’ve learned to be effective at both.

It’s funny. Throughout my career, non-technical folks have said, “Wow, Ed, you write pretty well for a programmer!”

Then there are the fellow engineers and the technical managers who have also said, “Wow, Ed, you write pretty well for a programmer!”

After you hear that for a while — especially from multiple directions, and even more especially when you detect a tinge of surprise — you realize the existence of a widely accepted myth: Technical and literate skills don’t mix.

Don’t they?

Code is for communication with humans

Let’s reexamine my definition from above: “Writing code means giving a set of instructions to a computer.” I said it wasn’t complete or accurate, and now I’ll tell you why.

Consider these wise words:

Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.
- Donald Knuth, “Literate Programming,” 1984, page 1

And these:

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
- Martin Fowler, “Refactoring: Improving the Design of Existing Code,” 2000, page 15

Whether you liked your math classes or not, you probably remember this: “Show your work!” Why did your math teacher always say that? Because the specific answer wasn’t the point. They needed you to write down the steps that got you to that answer. There was no other way for your teacher to tell whether you understood the process well enough to be able to solve similar problems.

Writing software feels a little like that. Assuming minimal experience, it’s pretty easy to quickly cobble together some gobbledygook that produces the answer you’re looking for. But just like in math class, one specific answer is not the point. You must show your work (the “algorithm”). Only this time, you’re not trying to prove that you understand it. You’re trying to make it possible for others to understand it.

“But it works, doesn’t it? Isn’t that good enough?” Sure, you betcha, if nobody but a computer will ever need to read it again.

Ha. Yeah, right. You have to admit, that’s a pretty unlikely scenario. People are always dreaming up new things they want these programs to do. Which means somebody will eventually have to be able to change that code you just wrote. To change it, they have to be able to understand it (unless they don’t mind causing new bugs, of course). Changes like that could happen a week from now, six months from now, or maybe even 10 years from now. And trust me, even if Future You will be the one doing the changes, you won’t be able to reconstruct today’s mental state if the code looks like gibberish.

If you’re writing code that needs to have any sort of shelf life, you’d better write it so that a human can understand it.

English is for communication with humans

Duh, right? Well, consider this oft-quoted line:

I would have written a shorter letter, but I did not have the time.
- Blaise Pascal, 1656

And this one:

Mystification is simple; clarity is the hardest thing of all.
- Julian Barnes, “Flaubert’s Parrot,” 1984

Pascal’s apparently lengthy letter sounds a lot like the hurried, cobbled-together computer program example from the previous section. Both the letter and the program probably worked to some extent, but both could have used some editing to achieve greater understanding.

And to me, Barnes’ statement presents the same basic idea that Fowler’s does, only from a different point of view. If we over-generalize Fowler’s words, the similarity is even more apparent: “Any fool can write. Good writers write things that humans can understand.

Sure, the things we write in English and the things we write in computer languages usually exist for very different reasons. But whether it’s a computer program, a letter, an essay, or a blog post, the point remains the same …

You’re writing for humans.

People like Pascal and Barnes wouldn’t have felt the need to emphasize the importance of succinctness and clarity if these things were effortlessly automatic.

To that end, I’ll restate my last sentence from the previous section. But let’s change one of the words: If you’re writing anything that needs to have any sort of shelf life, you’d better write it so that a human can understand it.

My top-secret recipe

Here’s how I approach writing for humans (whether code or English):

1. Think up stuff.
2. Write it down.
3. Make it correct.
4. Make it clear.

(Earth-shattering, isn’t it? You can steal it if you want.)

Once I have a writing topic or a programming task in mind, Steps 1 and 2 don’t take very long. Step 3 can take a bit of time or a bunch of time, depending on what I’m writing.

I see Step 4 — make it clear — as the most important step of all, so I spend a fairly large proportion of my time there. The funny thing about Step 4 is this: After I spend some time there, I might find that I need to go back and do more of Step 3 — make it correct —because I’ve clarified things not just for my future readers, but for my present self as well.

In programming terms, that usually means I’ve found and killed a bug before it could show up anywhere but my own computer. Clarity is powerful stuff.

By the way, I’ve also found this “top-secret recipe” to be a great way to combat writer’s block. (Not that I’ve ever experienced the agony a professional novelist must feel when they JUST … CAN’T … MAKE words show up on the page. But as a programmer, I’ve often had either way too few or way too many ideas in my head. Neither extreme is good. Either one tends to make me just stare at the blank screen where my awesome new program is supposed to go.)

I’ve trained myself to just think of something and write it down. It doesn’t matter how bad or stupid or inadequate or just plain wrong it is, because I know I’ve got Steps 3 and 4 there to protect my reputation before anyone sees the bozotic stuff I started with.

And please don’t assume that I think any of this is original. Countless others made this same journey and arrived at the same point way before I ever thought to put on my hiking boots. But it’s often true that you can’t appreciate the journey’s end without taking the journey yourself.

And now … back to my point

Uh, what was my point again? Oh, right: Writing in English doesn’t feel all that different from writing computer programs.

Well, I’ve never really left the point. I’ve just been building up to it. I said that my top-secret recipe for writing applies to both code and English, and it’s true.

But is that all there is to it? Think it, write it, correct it, and clarify it?

Yes. Since I pretty much follow the same path either way, I guess that’s why Englishing and coding feel so similar.

And no. There’s more to it, actually. Over the years, I’ve worked on sharpening both my sets of writing tools. Along the way, I’ve noticed that the English ones can be adapted to help me with my coding, and vice versa.

English skills make my code more effective

Just as I have a writing style in English (as does anyone and everyone else), I also have a writing style when I program. I’m sure some of that style is as natural and ingrained as my Colorado accent, but a lot of it is intentional and for clarity’s sake.

A lot of that style comes from things I’ve learned about English. Here are a couple of examples (there are so many more I could add, but I’m sure you have places to be pretty soon):

Prepositions

At times, fellow programmers have accused me of trying to turn computer languages into English “just because.” I admit I do that, but it’s never “just because.” It’s because I’m trying to make something obvious for the reader of my program.

One way I try to help the reader is through the use of prepositions. In elementary school, I was taught that a preposition was a word that links the subject, action verb, and object, while further describing the action. I was told to imagine a running mouse and a bed, and to think of words that could fill in the blank:

  • The mouse ran under the bed.
  • The mouse ran around the bed.
  • The mouse ran to the bed.
  • The mouse ran from the bed.

In programming, we also have subjects, verbs, and objects. But unlike English, we often think in terms of verbs first. (Because programming is all about doing stuff.)

Here’s an example “sentence” in a program (which we really call a “statement” or an “instruction”):

copy(file1, file2);

That’s easy enough. We’re copying one file to another one. But wait … which one is the original file, and which one will end up being the copy? I have no idea. Some programmers shrug this question off, which brings back more childhood memories: “If you don’t know, go look it up.”

Fine. But I could have stayed right here in this code, keeping my focus instead of looking up definitions, if only the programmer had written it this way:

copyTo(file1, file2);

Adding that simple preposition makes it pretty clear that whatever is in file2 will get copied to file1, not the other way around. (Did you guess wrong the first time?) Just like with the running mouse and the bed, the preposition is further describing the action verb (copy), and it identifies the subject (file2) and the object (file1).

Alternatively, we coders also write things in a more “object-oriented” way, loosely meaning that we’re thinking of the object of the sentence first, and then we apply a verb to it to make something happen. You might think that would automatically make things less ambiguous, but not necessarily:

file2.copy(file1);

Nope, I still can’t tell what’s happening. I know that file2 is the object, but I still can’t tell which direction the copy goes. (I know the mouse is running, and there’s a bed, but which direction is the mouse going?) How about one of these instead?

file2.copyTo(file1);
file1.copyFrom(file2);

Prepositions are small, yet powerful. (And a perfectly fine thing to end a function name with.)

Parallelism

Imagine a job ad for a software engineer. One thing the ad needs to do is list the job’s responsibilities. Here’s a not-so-good example:

Responsibilities:

  • Write programs.
  • Fixing bugs.
  • Mentor for new engineers.
  • Company blog.
  • The information is present, but there’s something unsettling about it. The brain wants to put an introductory phrase in front of each one, like “The engineer will…” That works for the first one, but not for the others. So now the reader is distracted and has to slow down a bit. In English, this is called a lack of parallelism. Here’s that ad snippet again, but this time with proper parallelism.

    Responsibilities:

  • Write programs.
  • Fix bugs.
  • Mentor new engineers.
  • Blog for the company.
  • This concept applies to programming as well. You want to help your readers, not distract them and slow them down.

    Take a look at this function (not written in any real computer language):

    function doThings:
    if (today is ‘Tuesday’ and moon.state is ‘full’) then howlAt(moon);
    huntVillagers();
    dvr.getListings().select(‘The Wolfman’).record();

    This “doThings” function is all over the place! We’re looking up dates and moon states and figuring out how to program our DVR. Sure, it’s not too hard to understand in this tiny example. But now imagine 20 more lines like this, or 100, and with much more complicated calculations, and you start to understand why debugging careless code can be difficult at best.

    In programming circles, we talk about a “Single Level of Abstraction.” That’s parallelism, plus a little more. Let’s try it this way:

    function doThings:
    howlAtMoonIfAppropriate();
    huntVillagers();
    recordFavoriteMovie();

    Now it’s a simple list of things to do, all nice and parallel. Just below this function, we’d find the other functions (like “recordFavoriteMovie”). The reader could read each of these functions for more details about what it does.

    That is, the functions would get less and less abstract as we went along, with each function representing a single level of abstraction. The reader of this program would now be able to stop reading at whatever level of detail is useful, instead of being forced to wade through all those details by default. Not only that, but clearer code makes it easier to spot bugs. (In this example, we probably want to set our movie recording before we go after those villagers. Villager-hunting can be time-consuming.)

    I learned how to do the parallelism thing back in high school English, but I admit it took me a while to figure out that it applies to programming as well.

    Code skills make my English more effective

    Earlier, I said this about my writing style when I program: “… a lot of it is intentional and for clarity’s sake.”

    The same thing applies to my writing style in English. The programmer in me is always looking over the English writer’s shoulder and making suggestions. (Though sometimes those suggestions do get ignored. What a geek, that programmer!)

    Here are a couple of examples (again, there are many, but I’m limiting myself to two again):

    Compartmentalization

    Barring any technical limits on file length and whatever else, you could theoretically write a million-line program all in one big function in one big file. But, ouch. BIG ouch. (“Hey! I finally found the bug! Right here on line 723,827! … Hello? Where did everybody go?”)

    So, we compartmentalize our programs. A program has modules, a module has files, a file has functions, and a function has statements. (That’s the gist, anyway.)

    We don’t do this for the computer; it doesn’t care. We do this for the poor human that has to read the program and make sense of it. A human can keep only so many things in short-term memory, so we write things in smaller chunks.

    Similarly, I could have written this post in one humongous paragraph. Again, big ouch. I’ll bet you’re glad I didn’t do that.

    The programmer in me sees it like this: A blog post has sections (and maybe some sections even have subsections, like this one), a section (or subsection) has paragraphs, and a paragraph has sentences.

    It’s hard to bend this analogy much further without shattering it. And of course, I’ve been using ridiculously extreme examples. Surely nobody would put a million-line program into one file, nor would they write a whole blog post in one paragraph.

    In general, it’s just about breaking a big chunk of writing into smaller, human-manageable chunks, and then labeling them so the reader’s brain can index and find them again. Finding that proper chunk size takes some planning and effort, but the resulting clarity sure is worth it.

    The right tools for the job

    We programmers often discuss using the right tools for the job. You shouldn’t try to use a hammer to drive a screw, and you shouldn’t try to use a screwdriver to drive a nail.

    Some programs are very temporary. Maybe we’re just rearranging some records in a database, and it’s easier to write a program than to do it manually. (We often call that program a “script” when it’s written in a different, smaller language.) After we’re done with that script, we’ll never need it again, because the database is never going to be like it was before we ran the script on it.

    Such a temporary program definitely needs to be correct, but it doesn’t need to be nearly as clear as a program that we expect to be running our website 10 years from now. To put it a different way, you could say that the temporary database rearrangement program doesn’t need to be as formal as the permanent website program.

    But what about a program we write now and might need to use a few times over the next few months before we delete it for good? Furthermore, maybe some other programmer will need to be able to update it. In that case, the program might need to be a little more formal (clear), but still not so much as our website program. There are different levels of formality. Use the right tools for the job.

    Obviously, writing in English has different levels of formality, too. But maybe there are more levels than we readily imagine.

    I’m sure that if there are any English teachers out there reading this, they’ve instinctively reached for their red pencils, as I’ve shamelessly thrown out pseudo-words such as “bozotic” and “Englishing.” (But hey, I did just use “furthermore” a couple of paragraphs ago!)

    (Not to mention the plethora of parenthetical asides I’ve inserted, as well as all those sentences that start with conjunctions like “not.” And sentences that aren’t really sentences. And don’t forget the massively, horribly overused hordes of adverbs walking around with vague metaphors.)

    But (oops — another leading conjunction and now more parentheses!), I’m writing for a blog. It’s infotainment. Yes, a company blog generally needs to be heavier on the information than the entertainment, but all “info” and no “tainment” makes for a dull blog, right? With full intent, I commit these literary fouls to try to make my writing feel more conversational, which I hope will keep my readers engaged enough to absorb my ideas.

    When I was younger, I think I took my high school and college English composition classes too seriously. “This is how you structure your writing. No exceptions. Anything else, and you get marked down.” I continued to think that way long after I had entered the working world. I thought there was formal writing for work and such, and informal writing for friends and family. I didn’t realize there was anything in between.

    I was wrong. Just like in programming, there’s a spectrum of formality levels, not a dichotomy. Use the right tools for the job.

    Busting that myth

    “Technical and literate skills don’t mix.” I understand this widely accepted myth, but I don’t have to accept it for myself. These skills mix quite nicely, thank you. I plan to keep stirring them up and never let them separate again.

    “Writing in English doesn’t feel all that different from writing computer programs.” Hopefully this makes more sense now than it did at first. As soon as I realized it, I got better at both.

    For me, writing is writing, and always the twain shall meet.

    Freemantle