Code is a Language!

The Art of Designing Code – Part 2

Mischa Hildebrand
20 min readJan 18, 2019

In part 1 of this article, we learned that code is a kind of user interface, only that its user is another developer rather than the end user. In this second part we will investigate another kind of user interface and identify several design principles which we will then once again apply to code.

The ultimate goal is to give you a different perspective on code and to provide you with a tool set to make your code easy to understand.

The Media’s Interface

For journalists, it’s crucial to be understood. If their audience doesn’t get what they are trying to say, all their work is worthless. Especially radio and TV producers need to focus on this aspect. After all, consumers of their programs usually cannot jump back, when they didn’t get the message. (They can of course do that in podcasts and video-on-demand, but no one wants to do this all the time.) In addition, listeners of radio programs usually do some other activity else while listening — so producers cannot expect to have their audience’s full attention.

Just like developers and designers communicate an app’s functionality to the user through a user interface, media journalists communicate with their audience through an interface as well. The interface is their language.

The Media Interface

Because language plays such an important role for them, radio and TV journalists have figured out many ways to make their language as easy as possible to understand. These tricks are simple, yet extremely powerful.

Code is a language as well, or more specifically: it’s the application of a programming language. As such, it’s only consequent to assume that we can improve the readability of our code by applying the same language tricks that journalists use. Let’s do that!

The Code Interface

💡 Language Tricks to Improve Your Code

Short Sentences

Read the following sentence, then close your eyes and try to repeat the essential information:

The conference organized by Subh Behara and his team, focussing on Swift, a programming language developed by Apple and the open source community, used primarily for the development of mobile applications, takes place in Singapore at Matrix, a building which is part of the Biopolis research centre, not far from the subway station Buona Vista.

Difficult? That’s because it’s a really long, nested sentence with lots of information. Let’s try to make this easier for our mind:

The conference is organized by Subh Behara and his team.
It focuses on Swift.

Swift is a programming language.
It is used primarily for the development of mobile applications.
It was developed by Apple and the open source community.

The conference takes place in Singapore.
You can take the subway and get off at Buona Vista station.
From there, it’s only a short walk to Matrix.
The building is part of the Biopolis research centre.

Better? We have divided a single long sentence into nine short sentences that each carry less information. By doing this, we made it easier for our mind to digest the information one piece at a time. Periods and line breaks indicate the end of a logical unit and give our mind the opportunity to “take a short break”.

Long sentences are bad for understanding — in code as well. In the following code example we split a long “sentence” (a line) into smaller chunks. As a result, we get more lines of code, but these are easier to read:

Long lines of code are difficult to read.

When you look closely at this example, you will notice that the fist line of code contains many periods – too many! The more code you inspect in your own projects, the more you will see that periods make your code more verbose.

On one hand, every period introduces one new level of encapsulation. Our mind has to wander all the way from UIApplication to height, only to figure out that the long expression UIApplication.shared.statusBarFrame.size.height represents the status bar height. On the other hand, every period increases the total length of the line as well, making it more difficult to read.

As a general rule of thumb, you should always try to minimize the number of periods per line.

Simple Language

Would you understand what’s wrong with your colleague if he told you the following sentence?

My attendance at the meeting today is not possible due to my immediate post-prandial upper-abdominal distention.

Unless you are a medic (or you’ve watched Star Trek IV… 🖖), the answer would most likely be no. That’s a pity, because the actual message is pretty simple:

I cannot join the meeting today because I have flatulence.

It might be that your colleague wanted to intentionally cloud the real reason for his absence. He probably succeeded. The more difficult the language we use, the more difficult it is to understand. Technical terms like post-prandial upper-abdominal distention are only known by a relatively small group of people and even for them, colloquial language is easier to follow.

The same applies to abbreviations. When you write an abbreviation for one or several words, you know exactly what it means at that time. A couple of months later, you might be out of the context and cannot decipher your own abbreviation anymore. For other people who read your text, it’s even worse, because they might have never been in that context and have a different way of thinking.

So in order to keep your language simple, you should:

  • avoid technical terms,
  • avoid abbreviations and
  • be specific.

That’s true for code as well. I recently came across some legacy code like this:

Complicated Language: Abbreviations, single letter variables and non-semantic names.

It took me hours to figure out what this code does, especially as the referenced classes and functions were no less cryptic.

Simple Language: No abbreviations, expressive variable and class names, no technical terms.

The good news is that we can learn a lot from this example:

  • Abbreviations are usually not immediately clear to other developers. Every developer has a different history, every developer has learned different things. Thus, you cannot assume that all of them understand abbreviations that are self-evident to you.
    There might be some platform- or industry-specific abbreviations that we can assume other developers to know, like UI, API or HTTP. But when in doubt, leave them out!
  • Single letter math variables are even worse. They don’t carry any semantic meaning. Unless you’re really dealing with coordinate systems, use descriptive variable names instead!
  • Non-semantic names are names that don’t convey the meaning of the value they represent. An object could be anything from a price tag to a spaceship. If it’s a price tag, call it priceTag, if it’s a space ship, call it spaceShip , if it’s something else, call it what it is!
  • Technical terms are words related to a specific topic that many people do not understand. I would even categorize the word “non-semantic” as a technical term which is why I explained it above. Sometimes it’s necessary to use technical terms because they are usually very specific and you might not find another word which describes your variable or class with such accuracy. In general, don’t use them!

Consistency

Imagine you listen to the radio and this is on the news:

A professor from National University of Singapore has been nominated for the Nobel Prize in Physics.
Many physicists envy the scholar.
The physicist has proven the existence of the omega particle.

Fortunately, it’s really simple language but you might still get confused: The text uses three different terms for the same person:

a professor = the scholar = the physicist

When you don’t listen carefully, you might ask yourself: What scholar is the news anchor talking about? Who is that physicist? For that reason, radio journalists settle for one term upfront and then purposefully repeat it every time they refer to it:

A professor from National University of Singapore has been nominated for the Nobel Prize in Physics.
Many physicists envy the professor.
The professor has proven the existence of the omega particle.

It goes a little against what we have learned in school. When writing literature, different terms describing the same object or person make the text more elegant and exciting. Sometimes the author might even want us to think for a moment and let our minds wander. But radio journalists have a different goal: They want their listeners to understand them – just as developers (should) want other developers to understand their code. Therefore, developers need to be consistent with their wording as well.

Fortunately, in a programming language, you cannot make the mistake to accidentally call a variable or function a different name than the one you assigned to it when creating it. However, you can be inconsistent with your naming per se:

A common struggle among iOS developers is the inconsistent naming of user interaction methods. There are all sorts of naming conventions and I won’t be the judge of which one is the best, but when you and your fellow developers use different conventions within the same project (or even within the same file), your code becomes much more difficult to read.

Inconsistent naming of action methods

Instead, settle for a single naming convention for specific use cases within a project with all developers involved. You might need to make a compromise here but believe me that consistency is a much greater gain for you than pressing through your personal taste.

Consistent naming of action methods

The same goes for variable or type names: If you choose to call a parallelogram with right angles a rectangle, go with that name for all your variables describing such an object (at the very least withing the same scope).

Two different terms for the same kind of object.

If you choose to call it a frame instead, there shouldn’t be the word rectangle in your code (unless it’s describing something else).

Consistency means using the same term for the same kind of object.

The News Rule

We humans tend to be a little chaotic when articulating ourselves. That’s because we often get new ideas while we are speaking (or writing — and this parenthesis is a proof of that 😉) and thus, we try to somehow merge these new ideas into the current sentence.

The more information a single sentence contains, the more challenging it becomes for our mind to digest all of it. Take this news story, for example:

SpaceX has launched the world’s most powerful rocket which can put up to a maximum of 64 tonnes in low-Earth orbit which is more than double that of the Delta IV Heavy which is the world’s next most powerful rocket.

If this was broadcast on the radio, a large fraction of the listeners would not be able to follow along and the news anchor would probably have to search for another job after the show.

That’s why there is a special technique news anchors apply to make it as simple as possible for their listeners to follow along — the news rule:

Only 1 piece of new information per sentence!

News anchors usually start a news story with a simple sentence:

1. SpaceX has launched the world’s most powerful rocket.

Then they begin the second sentence by referring to the core information from the previous sentence and add one new piece of information:

2. The rocket can put up to a maximum of 64 tonnes in low-Earth orbit.

In the third sentence, they again reference the core information of the previous sentence and add a new piece of information once more:

3. This is more than double that of the Delta IV Heavy.

The same principle is then applied to the fourth sentence and so on:

4. That is the world’s most powerful rocket.

By structuring a news story according to the news rule, sentences get shorter automatically. As there is only one new piece of information per sentence, it becomes easier to digest it for our minds. On top of that, the news rule enforces a linear line of thoughts. It guides the listeners (or readers) step by step through the story.

The News Rule: One piece of new information per sentence.

It’s not surprising that the news rule is a tremendously powerful tool for code as well. Many developers tend to nest different function calls and squeeze everything they can into a single line. While this might make the code a little shorter, it reduces readability dramatically.

Especially, when the outer-most function has multiple parameters and you pass a nested function as the first parameter, it gets difficult to read – just like a nested sentence. It’s hard to figure our where the “sentence” (function) you started with continues and your mind needs to do all the work to bring order into this chaos.

The News Rule applied to code.

When you structure your code following the news rule instead, you get more lines of code, but each line is super easy to understand because it only contains a single piece of information.

Active over Passive

Let’s have a look at two very simple sentences that both have the same meaning:

1. She kisses him.

2. He is being kissed by her.

Which one do you like better?

The second sentence is longer and seems more complicated. That’s because we begin that sentence with the person who is not really doing anything. It hurts me to say it, but he is not really that important in this sentence because she is the actor. Still, we only mention her at the end of the sentence and that’s what makes it counter-intuitive.

For this reason, radio and TV journalists try to use active voice whenever possible. When writing “sentences” (lines) in code, you should also ask yourself, who the actor is.

Who is the actor in your code?

Take the code example above: We simply try to download a resource from a specific URL. On the left side, the download method is implemented on the resource — which is not really where we would expect it. After all, it’s not the resource’s responsibility to download itself. If that was the case, what would the download manager do?

Following the human way of thinking, it’s much better to define the download method on the download manager, the actor. This is equivalent to using active voice rather than passive voice.

When writing a new function, always ask yourself who the actor is and

Define your function on the actor!

Positive over Negative

Journalists strive to be positive — not necessarily with their comments, but with their language. As most adjectives have a contrary counterpart, we usually have two ways to describe a how something is: We either use the adjective itself, or we use the adjective’s contrary preceded by the negation word not. Too abstract? Let’s look at a simple example:

Many people use the phrase

The weather is not bad.

when the sun is shining. That’s bad — not for colloquial conversation, but for both media journalists and developers.

Bad is the contrary of good, so whenever we say bad, we mean not good. It’s negative. Now when we say something is not bad, we are negating a word that’s already negative, effectively resulting in the meaning of the positive word which we could have used in the first place!

Sounds complicated? Well, that’s the reason why you should follow the journalists’ advice and always be positive!

Let’s say we want create a weather app and write a class that represents the weather. We want it to have a boolean property to easily check if the weather is good or bad. There are two ways how we could name this property: isGood or isBad.

Positive vs. Negative

At this point, it doesn’t seem to make a difference how we choose. The problem becomes obvious only when we use the property in code, for example in a conditional clause:

Double negation introduces unnecessary complexity.

On the left side, we check for the contrary (!) of the negation of the word good (bad). On the right side, we simply check if the weather is good and the code even reads (almost) like an English sentence:

If [the] weather is good, go swimming.

Now, what if we want to check for the opposite? What if we like empty pools and want to go swimming only when the weather is bad?

We still need to use the negating operator (!), but this will result in a single negation only: if !weather.isGood. We will never have to deal with an implicit double negation. So remember:

Be positive!

With this attitude, you might even get a smile back from your colleagues every now and then. 😉

ℹ️

Side Note: In some cases, there might be a trade-off between being positive and being expressive. For example, Apple’s UI framework defines a variable isHidden on views. This might be because developers expect a view to be visible by default and some might perceive the word hidden as more expressive than the word visible. It might also be because Apple simply doesn’t know how great it is to be positive. In such cases where you feel like you lose expressiveness, you need to evaluate which trade-off is the greater loss to your code’s readability. (Personally, I still favor isVisible. 😉)

Avoid Numbers

When you listen to the radio and you hear the following sentence, it’s quite likely you’ll have no clue what the news host just said:

488 of the 535 members of congress have voted on the civil rights act today. The remaining 47 members were absent. 366 voted for the act, 122 against it. The bill was passed.

That’s because numbers don’t carry any intrinsic meaning and when confronted with many different numbers in a single sentence, our mind struggles to put a meaning to them. For that reason, radio and TV journalists try to avoid numbers whenever possible and use qualitative descriptions instead:

Congress has voted on the civil rights act today. Three quarters of the members voted for the act, the others against it. The bill was passed in spite of the fact that many members of congress were absent.

On the media, this usually comes with a trade-off in precision. Fortunately, we do not have this problem in code.

Let’s say we want to write a method for laying out a number of subviews in a grid (similar to what is called a collection view in iOS).

A grid layout.

The following code undoubtedly does the job:

Magic numbers: A function for laying out subviews in a grid.

However, it uses many magic numbers. We call them magic not because they are so beautiful but because they seem to appear out of nowhere. If we were to change the vertical line spacing, for example, it would take us a while to identify the number representing this value.

Therefore, you should always extract magic numbers into constants and define them at a central place, for example at the top of the file you’re editing or in a dedicated constants file.

Defining constants for magic numbers.

With these constants, we can rewrite our layout method as follows:

Using constants rather than magic numbers makes your code more expressive.

Much better, isn’t it? Now whenever we want to change any of the parameters, we don’t even need to touch the layout algorithm – we only need to modify the, defined at a central place. The method is much easier to read because we use semantic constant names rather than plain numbers. But we can do better!

Admittedly, the code is not overly complicated but it still takes some time to understand what’s happening in the if-clause. We got rid of the numbers, but the individual lines still read like mathematical formulas, hiding the semantics. Let’s improve this by extracting both the if-condition and its body into separate functions:

Extracting code into separate functions allows you to label the code with meaningful names.

With these new functions, we can express the whole if-clause in a developer-friendly way:

This reads almost like an English sentence. It expresses very clearly, what the code does and focuses solely on our intent. Some programming languages like Swift support inline functions, allowing you to nest these functions inside the layout function. Using inline functions, this is how the overall simplified function will look like:

The simplified layout method makes use of inline functions.

If your programming language doesn’t support inline functions, you can sometimes extract the code into top-level functions. However, the downside of this approach is that you will have to pass variables that are known within the scope of the layout function as parameters to the extracted functions. This might decrease readability and you might be better of not extracting the functions, depending on the use case.

Whether or not you decide to extract your code into functions, you should always remember this simple rule:

Extract numbers into meaningful constants!

Implicit Context

Imagine you see some footage of a tragic plane accident on TV. While showing the footage, the news host says the following:

A plane has crashed into a housing complex near San Francisco today.
Most of the passengers of the plane were killed.
But 3 passengers of the plane survived.

Doesn’t this sound weird? That’s because the host is repeating information we already know in every sentence.

The first sentences introduces a plane crash, so when talking about passengers in the second sentence, we can assume that those are the passengers of the plane — no need to repeat this information. In the third sentence, we can not only omit the plane, but the passengers as well, because the last thing we remember from the previous sentence are the passengers.

Naturally, we can apply this concept of implicit context to code as well. Let’s say we create an app for an online shop and we want to be able to present a product with different visual styles.

Different visual styles for laying out a cell.

In order to do that, we create an enumeration with three cases, each of which represents a different style.

Next, we write a class for the article cell – the UI element we’re going to use to display the products.

We want to be able to update the cell’s appearance at any time, so we define a method on the article cell which is responsible of doing just that. The method accepts an ArticleCellStyle as its single input parameter and updates the UI accordingly. Unfortunately, we just introduced some repetition to our code:

When we call a method named update(style:) on an article cell, it’s kind of clear that we want to update the article cell’s style. There is no need to explicitly name the ArticleCellStyle — we could simply go with Style.

Modern programming languages like Swift or Kotlin support nested types which solve this problem. Instead of defining a top-level ArticleCellStyle, we can simply define a Style type within the scope of our ArticleCell.

With nested types, you can make use of implicit context.

This has the additional benefit that the code’s structure now follows the rules of proper encapsulation: These styles only have a meaning with respect to an ArticleCell, thus it makes sense to move the style definition inside this class.

The full type name of this enumeration is now ArticleCell.Style. We can use this name when referencing the type from outside the ArticleCell class. However, with proper encapsulation there shouldn’t be a need for that.

Modern compilers make use of implicit context as well. When calling our update(style:) method on an ArticleCell, we don’t need to pass the full name of the style because the compiler is already expecting an ArticleCell.Style due to the method’s signature.

Modern compilers allow for omitting the type prefix due to implicit context.

Of course, you can also make use of implicit context when naming your variables inside the scope of a function. When you have a method that sets the padding of a view on each side, it’s usually more readable to write

func updatePadding() {
let left = 5
let right = 10
let top = 2
let bottom = 6
setPadding(left, right, top, bottom)
}

than

func updatePadding() {
let leftPadding = 5
let rightPadding = 10
let topPadding = 2
let bottomPadding = 6
setPadding(leftPadding, rightPadding, topPadding, bottomPadding)
}

Taking advantage of implicit context does not mean to lose precision. You can apply this concept in many situations, but you always need to make sure that you actually have a context within the current scope and you’re not just omitting important information required to understand your code.

Use implicit context to shorten your variable and type names!

Headlines

A clear, visible structure always helps to follow along — this applies to a news show on the radio or TV as well as to newspapers, books, talks and, as expected, to code. One way to structure anything related to text is using headlines.

Let’s have a look at a newspaper for a change:

This might be a good article but if we want to skip the introduction or if we are only interested in the part that explains why headlines improve readability, we need to scan through the whole text in order to find the relevant passage.

Newspaper and online journalists tackle this problem by introducing headlines for subsections of their articles. This makes it a lot easier for their readers to quickly jump to the part that interests them most. Radio and TV journalists frequently use this concept as well, for example when they begin every story of a news show with a catch-line.

Headlines for subsections make it easier to find the information of interest.

As developers, we have multiple options to introduce headlines:

  • First of all, every type name is also a headline for its code contents. Equally, a function name is a headline or summary for the code it encapsulates.
  • Every modern IDE (like Apple’s Xcode) has a project navigator which allows you to create and navigate through files and folders. File names are headlines for the code they contain. Folder names are headlines for the files they contain. You can collapse folders to hide the details for a better overview and focus on the headlines only.
Your project’s folder and file names are headlines as well.
  • Lastly, some IDEs automatically compile a list of all the functions and variables in a file you can access with a jump bar. In Xcode, you can use a special keyword in code to add headlines and even separator lines to this list: Use
    // MARK: Your Headline
    to add a simple headline and
    // MARK: — Your Headline
    to add a separator line followed by a headline.
    (Personally, I like to use emojis in conjunction with the headlines because they attract a developer’s attention and summarize a headline in a single image. It definitely adds to readability but the downside is that you cannot type emojis directly with your keyboard and it takes time to find the right one.)

The fact that I’m starting to talk about using emojis in code now tells me that I should better end this article right here… with an emoji: 😉.

Conclusion

In this article, I introduced you to a journalist’s perspective on code. You have learned many language tricks journalists use in their daily routine. These tricks can also be applied to code in order to improve readability.

The collection of these tricks should be treated as a tool box that you can access at any time, when writing code yourself or when reviewing code of other developers. There is never a silver bullet in programming, but I hope this article helps you to articulate what’s wrong with code when all you have is a gut feeling that it’s somehow difficult to read.

This article is a written, enhanced version of my talk ▶️ The Art of Designing Code, presented at iOS Conf SG in Singapore.

Thanks for Reading! ✌️

If you have any questions or corrections, please leave a comment below. My Twitter handle is @DerHildebrand.

--

--

Mischa Hildebrand

iOS Developer, Radio Journalist, Physicist. Trying to make the world a better place with loads of positive vibes. 🤗