Severin Perez

On Writing Technical Blogs

October 08, 2020

Writing is humanity’s superpower—when done well, it informs, provokes, and entertains. Perhaps that is why blogging is so popular among programmers. We’re a naturally curious community and sharing knowledge is an integral part of our ethos.

For the reader, the benefits of good writing are obvious. When an author takes the time to prepare a high-quality article, knowledge flows seamlessly from one mind to another. I would argue though that the benefits may be even greater for the writer. Writing a good technical article requires deep research, careful thought, and a significant amount of experimentation. In other words, an author must master their topic before they can write about it.

A rushed article is one that will attract few readers and inform even fewer. So let’s take a couple of minutes to think about what a good article looks like and how we can produce more of them.

Technical Writing is Just Writing

Technical bloggers tend to be focused on the technical side of their work—often at the expense of their writing. Don’t fall into this trap. Technical writing is just writing and all of the standard rules apply. Here are a few of them.

Be concise. A short sentence is better than a long one. The same goes for paragraphs. Your goal is to inform your reader, not to overwhelm them. Keep things simple.

Have a clear goal. Everything in your article should work towards the same goal. Avoid tangents that are unrelated to your main topic. If the tangents are interesting, save them for a future article.

Structure your argument. All good writing, including technical writing, has an argument. The argument may be “this design pattern is useful” or “this feature works in the following way”. If you aren’t sure what your argument is, take a step back and identify it before moving on. Then you can build your article around the argument by presenting appropriate evidence.

Grammar, grammar, grammar. Standard grammar and spelling makes for clear and relatable prose. This is important in all writing, including technical writing. It may seem like typos and grammar errors are unimportant, but when a reader spots them it will detract from your message.

Edit ruthlessly. The biggest mistake a writer can make is publishing without editing. Your first draft is almost certainly too long, muddled, or riddled with error. Take the time to edit your article and be aggressive as you cut unnecessary material.

As with any kind of writing, technical writing must capture the reader’s attention and keep it. Presenting facts and figures isn’t enough. You need to speak to the reader’s interests and prove that your article is worth their time. Good writing is the best way to do this.

Code Snippets

Technical writing may just be writing, but that doesn’t mean it isn’t unique. If you’re writing about a technical topic then it’s natural to use examples from that domain. For programmers, this means using code snippets. Of course, writing code is itself another kind of writing! That means that many of our earlier rules still apply.

As you are presenting a code snippet, try to empathize with your reader. Is your snippet clear? Does it address your topic directly? Does it introduce unnecessary complexity? Let’s look at an example. Imagine that you are trying to explain how the map function works in Python and provide the following code snippet.

s = [1, 2, 3, 4, 5]
def foo(l, bar):
    return list(map(bar, l))

print(foo(s, lambda x: x * 2))      # [2, 4, 6, 8, 10]

This code works, and it does indeed make use of map, but it’s otherwise unintelligible. The function and parameter names are nonsense, the use of a lambda function is unnecessarily complicated, and the snippet uses a first-class function for no particular reason. The whole point is to teach your reader about the map function—don’t confuse them with related but tangential topics. Here is a better version.

def double(num):
    return num * 2

my_numbers = [1, 2, 3, 4, 5]

doubled_numbers = list(map(double, my_numbers))
print(doubled_numbers)              # [2, 4, 6, 8, 10]

In this version, the intent is much clearer. The map function is the centerpiece of the snippet, the variable names are meaningful, and there are no distracting tangents. Resist the temptation to use advanced functionality when it’s not necessary. Your goal should be simple and direct examples that aren’t muddied by extraneous content.

Sometimes though, clear code isn’t enough. Your snippets also need to be interesting. For example, take the below snippet, which illustrates the concept of class inheritance.

class Car:
    def __init__(self, max_speed):
        self.max_speed = max_speed
        self.current_speed = 0
        self.acceleration_rate = 1
    
    def accelerate(self):
        if self.current_speed < self.max_speed:
            self.current_speed += self.acceleration_rate
        
        if self.current_speed > self.max_speed:
            self.current_speed = self.max_speed

    def describe_speed(self):
        print(f"Current: {self.current_speed}. Max: {self.max_speed}")

class SportsCar(Car):
    def __init__(self, max_speed):
        super().__init__(max_speed)
        self.acceleration_rate = 20

corolla = Car(120)
corolla.accelerate()
corolla.describe_speed()        # Current: 5. Max: 120

mustang = SportsCar(165)
mustang.accelerate()
mustang.describe_speed()        # Current: 20. Max: 165

There is nothing inherently wrong with this snippet—it is clear, concise, and focuses on the topic we’re interested in. The only problem is that it’s not particularly engaging.The Car example is widely used and feels a bit uninspired. Let’s try again.

class Receipt:
    def __init__(self, item, cost):
        self.item = item
        self.cost = cost
    
    def receipt_msg(self):
        return f"{self.item}, ${round(self.cost, 2)}"

    def deliver(self):
        msg = self.receipt_msg()
        print(f"Printing receipt... {msg}")
    
class EmailReceipt(Receipt):
    def __init__(self, item, cost, customer_email):
        super().__init__(item, cost)
        self.customer_email = customer_email
    
    def deliver(self):
        msg = self.receipt_msg()
        print(f"Emailing receipt to [{self.customer_email}]... {msg}")

regular_receipt = Receipt("Subscription", 120)
regular_receipt.deliver()
    # Printing receipt... Subscription, $120

paperless_receipt = EmailReceipt("Subscription", 120,                  
                                 "charles@diffengine.ai")
paperless_receipt.deliver()
    # Emailing receipt to [charles@diffengine.ai]... Subscription, $120

The Receipt example is mundane, but it feels like something that you might actually write as a developer. In that sense, it’s much more relevant than the Car example. The subject matter may be boring, but it’s real.

Relevance is one way to help your readers connect with your snippets, but it’s not the only way. Don’t be afraid to use a little whimsy. Why write about Vehicles and Animals when you could write about Starships and Dinosaurs instead? Use your imagination! Choosing engaging examples for your code snippets will keep your reader focused and interested.

Presentation

Now you have a well-written article with thoughtful and engaging code snippets, but there is still one way that you can tank the whole thing: poor presentation. The visual design of your article provides structure and governs how topics flow into one another. If you don’t pay attention, your words could be overshadowed by clunky design.

Most blogging platforms have ample functionality for design, whether it’s italics, code highlighting, bullets, subheadings, or images. Make use of this functionality—it’s there to help you design a visually appealing article that draws the reader in rather than pushing them away.

Good visual design is clean and functional, with a dash of style. Per usual though, our principle of simplicity and concision applies. There is no need to litter your article with unnecessary images or charts. A little bit goes a long way. And when you do decide to use non-text elements, do so thoughtfully. Visual elements are as much a piece of your article as the text, and should show equal care. Consider the below code snippet for a notional article about searching algorithms.

def binary_search(items, target):
    left = 0
    right = len(items) - 1
    
    while left <= right:
        mid = (left + right) // 2
        
        if items[mid] == target:
            return True
        
        if items[mid] > target:
            right = mid - 1
        else:
            left = mid + 1
    return False

company_languages = ["C++", "Clojure", "JavaScript", "Python", "Ruby"]
candidate_language = "Python"

if binary_search(company_languages, candidate_language):
    print(f"We use {candidate_language} too!")
else:
    print(f"Are you willing to learn another language?")

Not very appealing is it? The content is fine, but the lack of syntax highlighting is distracting and bland.

def binary_search(items, target):
    left = 0
    right = len(items) - 1
    
    while left <= right:
        mid = (left + right) // 2
        
        if items[mid] == target:
            return True
        
        if items[mid] > target:
            right = mid - 1
        else:
            left = mid + 1
    return False

company_languages = ["C++", "Clojure", "JavaScript", "Python", "Ruby"]
candidate_language = "Python"

if binary_search(company_languages, candidate_language):
    print(f"We use {candidate_language} too!")
else:
    print(f"Are you willing to learn another language?")

Much better! It’s a small change, but it makes for a more enjoyable visual experience. It also shows that you’re taking the time to consider the details. And if you considered the details with a simple thing like syntax highlighting, then the reader will know that you considered details in the content of your article as well.

Why Write?

Writing is hard, but it’s also joyful. For a writer, it can be immensely satisfying to put your thoughts to paper. Not only are you likely to learn something new in the process, but your reader might learn something new too. And the more you write, the more joy you will derive from the process.

For technical bloggers, imposter syndrome is always a concern. No matter how much you learn, it will always seem like someone else knows more. Remember though, you’re not writing a textbook. You’re writing for yourself. You should strive to be accurate, and do sufficient research and testing to confirm as much, but at the end of the day you’re still an amateur. And that’s OK!

Good writing is as much about learning as it is about teaching. If you’re curious about a topic, or even confused by it, the best thing you can do is write about it. The process will force you to learn along the way, so long as you are driven by a desire to be accurate and thorough.

As with coding, or data, or engineering, writing is a skill that takes practice. But quantity does not necessarily mean quality. Don’t aim to be prolific—aim to be thoughtful. All writing, whether technical or otherwise, is deeply personal. It says something to the world about who you are, and if you take the time to do it right, readers will take notice.


This article originally appeared on Medium.


You might enjoy...


© Severin Perez, 2021