Long names are a code smell
Tags: typescript, readability, maintenance
Published: 2020-07-15 09:20:09

How do you feel when you read this?

```ts
function getPropertyFromDictionaryOptionCurried<T extends object, K extends keyof T>(object: T): Option<T[K]>
```

If you believe everything is okay, then this article is not for you.

Feeling irritated? Tread on.

# The problem

Long names such as `getPropertyFromDictionaryOptionCurried` are not bad because they make use of full words. They are bad because they *reveal* too much.

You may feel tempted to make a busy name compact by replacing words with single letters. However, if single letters read more naturally than full words, then this would be an improvement:

```ts
getPropertyFromDictionaryOptionC
```

Still looks scary. Let’s shorten it some more.

```ts
getPropertyFromDictOC
```

Instead of neutralizing the problem, we have created another one. We have shortened the name, but we have also obscured what the function is doing.

# The solution

Let's start from the beginning.

```ts
getPropertyFromDictionaryOptionCurried
```

We already know that this function accepts a `Dictionary`. The type signature indicates it. There is no need to repeat ourselves.

```ts
getPropertyOptionCurried
```

The same goes for the `Option` it returns. That's what types are for.

We arrive at:

```ts
getPropertyCurried
```

Using _curried_ as the suffix suggests that currying is something extraordinary.

Suffixes are often used to indicate that something unusual is taking place. For example, a synchronous function in an asynchronous-first environment might be suffixed with the word *sync*.

However, currying is hardly unusual in the JavaScript world.

Instead, let's ask a question: what is this function _in its nature_?

{% youtube f33ieCWRWlI %}

This function _reads from an object_. That's all it does. Let's find a more suitable name.

```ts
getProperty
```

The fact you can call this function in more than one way is a detail, not the dominant characteristic. We can communicate it by adding an _overload_.

A working example:

```ts
function getProperty<T extends object>(obj: T): <K extends keyof T>(key: K) => Option<T[K]>;
function getProperty<T extends object, K extends keyof T>(key: K, obj: T): Option<T[K]>;
function getProperty<T extends object, K extends keyof T>(obj: any, key?: any): any {
    switch (key) {
        case undefined:
          return (key: K) => Option.fromNullable(obj[key]);
        default:
          return Option.fromNullable(obj[key])
    }
}
```

# Takeaways

1. “If you don't want people to use something, give it a longer name” — [Dan Abramov](https://twitter.com/dan_abramov/status/1127664407239114752)
1. Using single letters instead of full words hardly ever makes things better. (Exception: [type parameters](https://twitter.com/WrocTypeScript/status/1167325871830491138))
1. If your function is general-purpose, yet its name sounds specialized, then a simple name combined with overloads is likely a better choice.

## Bonus 1

> The simple, the punchy, the easily remembered will be more effective in the long run than some long name that says it all, but in a such a way that no one wants to say it at all.

— Kevlin Henney in [Giving code a good name](https://www.youtube.com/watch?v=CzJ94TMPcD8&feature=youtu.be&t=360)

## Bonus 2

[The Inverse Scope Law of Function Names](https://www.informit.com/articles/article.aspx?p=1323426)

## Bonus 3

{% twitter 1081853709800345600 %}