Function name shouldn’t start with get

Author: Swen Kooij

Date: 2021-11-27

Functions that start with get are a personal pet peeve of mine. For example, I find getName to be a suboptimal function name. We’re taught early on to prefer function names that start with a verb. Many developers resort to get because it perfectly describes almost anything.

Disclaimer: I am aware that complaining about something as dumb as the verb a function name starts with comes across as nitpicky. It is not a hard rule. There’s always a trade-off. The intention of this article isn’t to convince you to never use get. The intention is to be thought-provoking.

Too generic

I believe that its generality is the problem. It can mean just about anything. Let’s say we come across the following call site:

name = getName()

In a strongly typed codebase you might be lucky and at least get a hint from the types about what this function does:

const name: string = getName();

Without looking at getName’s implementation, I cannot tell which of the following is true:

Doesn’t allow guessing performance and failure characteristics

I find it important that the reader is able to make an educated guess about what a function does. A function that fetches a name from the database has very different performance and failure characteristics than a function that just returns this.name.

A reader, or future editor, of the code might make very different choices depending on what they think the function does. A function that is actually just a property/accessor might be called repeatedly with a negligible impact on performance. For example:

console.log('User name is', getName());
doSomeWork(getName());

The fact that getName is called twice is not going to be a problem here, practically speaking. Each invocation would take mere nanoseconds. If getName actually fetches from a database or API, the code block above would be very problematic and would be better written as:

name = getName(); // add some error handling here

console.log('User name is', name);
doSomeWork(name);

Without a more specific verb in the function name, the reader isn’t able to make an educated guess about the performance and failure characteristics. This might lead developers less familiar with your code base to write code that isn’t as performant or resilient as you would want.

Requires mental gymnastics

We could obviously make the argument that a quick peek at the function declaration would make it clear to the reader what the function does. We could also argue that it’s often clear from the context in which the function is used what it does and what performance and failure characteristics it has.

Unfortunately, this often doesn’t hold up in reality. Authors often forget about how much bias and prior knowledge they have compared to someone who is completely new to the code base. Someone new to the code base has no context whatsoever. They might be completely unaware that in 99% of the cases, functions that are named getSomething just access a property.

Without any prior knowledge, readers have to do a lot of mental gymnastics to thoroughly understand an unfamiliar piece of code. Even guided by fancy IDE features such as “peek declaration on hover”, there’s the mental cost of having to read, dissect and understand a function.

This mental gymnastics cost grows linearly with the size of the code that the reader is trying to understand. Functionality often spreads across dozens, if not hundreds or thousands of files, classes, functions. Having to mentally jump back and forth between them makes it harder to create a mental model of how things work.

Code is read more than it is written

In most organizations, code is written once and read at least twice. Once by you, the author, and once again by a reviewer. Usually, the numbers far exceed the number of authors/writers. There might be multiple reviewers, future authors that need to make modifications to debug something, new reviewers, etc.

It makes sense to optimize for the reader rather than the writer.

What to do instead

Pick a better verb

In most cases, there are much better verbs available in the English language to more accurately describe what a function does.

Below is a quick cheat sheet that I personally use. It is not exhaustive and is absolutely not always applicable. It’s just a little crutch to start figuring out an alternative name.

Verb Reader expectation
fetch, query, retrieve Functions that retrieve data from a data store or API. Something that might take a while and has a relatively high chance of failure.
post, push, update, delete Functions that push data to a data store or API. Something that might take a while and has a relatively high chance of failure.
make, construct, compose, generate, create, combine Functions that compose, generate or create data/objects entirely locally. Something that is quick and has a low chance of failure.
search, find, filter Functions that filter or search through data locally.

Use namespaces to hint

Another great way to communicate what a function does is to ensure its call site always involves some form of prefixing. For example:

db.getName()

In the example above, the reader can immediately figure out that this fetches from a database, despite the function name itself being very generic. Most languages offer some way to namespace functions.

In more flexible languages, this shouldn’t be an excuse to just put all functions as static methods in a class. For example, in Python, one could adjust imports to ensure name spacing:

from myapp import db

db.getName()

Of course, we can do something similar in TypeScript/JS:

import * as db from 'myapp/db';

await db.getName();