Semantic method naming

Correctly naming things is the most difficult programming task (besides other documentation tasks). However, this is only because we often afford these tasks insufficient consideration. As with most things, the more we do it the easier it becomes. In this article we will discover how to choose correct names for our methods to help ourselves and others read and understand our code.

Although we will focus on naming, documenting and naming complement each other very well. Once we get into the habit of writing documentation for each method, describing what the method does, this helps us name our method correctly. If the documentation is good, usually it is possible to name a method correctly just by picking words from its documentation. We can even use this technique to verify that the method name and its documentation are correct by making sure they agree with each other – if they say different things one of them is wrong.

Lets establish our first and more important rule: all functions and methods do something so they should begin with a verb (a doing word). Now we're going to look at how to choose the best verbs to convey the most meaning for what our methods do.

Get less

The majority of methods we write will return a value and it's a common fallacy to choose get as the verb for too many of these methods. Get is fine for accessor methods that perform simple operations like dereferencing a pointer but doesn't communicate enough information to the caller about the complexity of less trivial methods.

Consider a method that fetches data from a database. It may connect to a remote computer, search for data from multiple sources, perform aggregation and sorting. We could call this method getData() but its verb does not differentiate it from another method that merely gets a simple value already stored in memory. By calling our method fetchData() we imply more work has to be done to retrieve the data.

As a rule, use get only for methods with constant time complexity; for anything more complex select a more descriptive verb. For example, if we write a method that uses arithmetic operations to calculate the return value, prefer the verb calculate.

Try to describe what the code in the following method does.

function getItem($match) {  
    foreach ($this->items as $item) {
        if ($item === $match) {
            return $item;
        }
    }
}

We could say this method appears to be searching a collection of items to find one that matches the specified match parameter. From this description we can directly extract a better verb than get; in this case either search or find does a better job of conveying to the caller the complexity of retrieving an item, so we should rename this method, findItem.

Do not do

Since all methods do something, choosing do as our verb does not convey any additional information about what our method is doing. Do is one of several common cop-out verbs that should be avoided, along with handle, perform, return, compute and other synonyms.

Some verbs, such as call, execute, run and prepare, perch on the boundary of suitability. It is not always wrong to use these verbs, but if we find ourselves wanting to use them, first pause to consider whether there is a more specific verb to describe what the method is doing.

Boolean return types

Methods that return true or false should begin with is, are, was, were or a modal verb. Modal verbs include can, could, may, might, must, shall, should, will or would. These methods pose questions such as Button::isEnabled(), Inputs::areValid() or User::canAccess().

An alternative convention found in Ruby is to define questions by appending a question mark instead of prefixing a verb. The methods from the previous examples would be named Button#enabled?, Inputs#valid? or User#access? respectively. You may wish to use this convention if your language supports this syntax.

Subject inference

There is a subtle but important difference between functions and methods. A method is a function that runs in the context of an object, such as those we define in a class. We say that the method is bound to the class or object because when it runs it has access to the data stored in that object.

Sometimes it is sufficient to just use the verb when the subject can be inferred from the bound object. For example, a method that saves a message may be called saveMessage. This method includes a subject (message) which specifies the subject of the operation. However, when the subject is the same as the name of the object our method is bound to, we can eliminate it and simply call our method, save. The subject is inferred from the bound object and reads intuitively: $message->save() as opposed to $message->saveMessage().

Do not describe parameters

A method's signature comprises both its name and its parameters. When using a method, we have access to both, so it is just duplication to describe the parameters in the method name. The method signature findUserByUserIdAndToken($userId, $token) can be simplified to findUser($userId, $token).

In languages that support method overloading, such as C++, C# and Java, we can always follow this rule. However, most popular scripting languages such as JavaScript, PHP, Python and Ruby do not support method overloading, meaning we cannot have two methods with the same name but different parameters. In this case it may be necessary to break this rule in order to differentiate between multiple versions of a method.

Summary

We learned some semantic rules that can be applied to our functions and methods to help determine the correct names. Most importantly, all method names must begin with a verb. If we describe what our method does, and take care to avoid cop-out words, we should be able to select the most appropriate verb to begin our method names.

Some consider documentation more important than code. If code goes wrong and there's no documentation it's difficult to fix because we may not know what it was supposed to do, or why. When a system is clearly defined in descriptive prose we can make informed decisions about the best way to fix it. Correctly naming methods is the first step towards good documentation but to take it a step further we should consider documenting every class and method too, and in turn, this will help us name our methods.


Comments