Variable name anti-patterns

by Jason Swett,

Overabbreviation

Bad examples:
passwd
fname
cust
o

Good examples:
password
first_name
customer
order

Explanation: Abbreviations like passwd violate the Principle of Least Astonishment. If I know a class has a password attribute I should be able to guess that that attribute is called `password`. Since `passwd` is pretty much totally arbitrary, it’s a practically unguessable. Plus, how valuable is it to save two keystrokes?

I have a saying: It’s better to save time thinking than to save time typing.

Exception: Abbreviations are fine when they match up with real-world abbreviations. For example, SSN, USA and admin are all fine because these are predictable and already familiar to most people.

Naming Scalars Like Objects

Bad example:
store = "Jason's Capsaicin Station"

Good example:
store_name = "Jason's Capsaicin Station"

Explanation: If I see a variable name like store, I think it’s an object. This problem becomes especially severe when the codebase does in fact have a class called Store and some stores are instances of that class and some stores are just store names.

Naming Counts Like Collections

Bad example:
products = 0

Good example:
product_count = 0

Explanation: If I see a variable called products I would probably expect its value to be a collection of some sort. I would be surprised when I tried to iterate over the collection only to discover that it’s actually an integer.

Naming a Variable After Its Type

Bad example:
array = []

Good example:
customers = []

Explanation: A variable called array or hash could contain pretty much anything. By choosing a name like this you’re forcing the reader to do all the thinking.

Use of Mass Nouns For Collections

Bad examples:
news[0]
inventory[0]

Good examples:
articles[0]
inventory_items[0]

Explanation: There are certain words that have no singular form. Examples include “stuff”, “garbage” and “laundry”. This anti-pattern especially applies to database table names.

Key/Value Mystery

Bad examples:
products.each { |key, value| puts value }
products.each { |k, v| puts v }

Good example:
products.each { |name, price| puts price }

Explanation: Names like key and value have almost no meaning. There’s almost always a more purpose-revealing option.

8 thoughts on “Variable name anti-patterns

  1. Robert

    Another pet-peeve of mine: Adding a property named “type” to differientiate between a newly made distinction between different subclasses of an object.

    Reply
  2. Anonymous

    From my experience, overabbreviation is useful for names of objects that are used extremely commonly. For example, if you are writing an application which primarily revolves around customer objects and references a “Customer” class in literally every other class, calling it “Cust” will greatly improve the conciseness of your code. However, if less than 10% of your files reference a “Customer” class, you should absolute avoid overabbreviating.

    This technique has to be used extremely sparingly, but from my experience, it is very useful to cut down on the verbosity of Java code in particular without compromising readability. You just have to be really really careful with it.

    Also, don’t forget this classic:
    int TWENTY_SEVEN = 27;

    Reply
  3. Jack

    I don’t support basically any of this.

    However, some of this is just my own personal ideal and I don’t write code amongst other people; so it can be argued that some of my personal ideals should be trumped under the importance of something more standard when making things designed to be worked with by others.

    First off, I don’t think you should go out of your way to make something more obvious for the sake of it, because the amount of inconvenience it causes to not know what something means is limited to finding out exactly once.
    It is ideal that everyone would always know exactly what something means, but you’re working with an intricate program full of complex mechanics and characteristics. What is an “array lookup table”? It’s a very deliberate description of a complex mechanic, interchanged between engineers to provide useful information.
    I do support that things should be as easy to understand as is practical, I just think “practical” means being more of a literal description of something.

    Second off, I think it’s redundant (and and anti-pattern) to store information about the variable in the variable name.
    The name is an identifier and the value is data. And if the value is a string, of course it’s going to be the store name. And vice-versa.

    >passwd is pretty much totally arbitrary
    It’s not, it’s a standard naming convention where you remove vowels to shorten something. The `a` happens to not be removed here.
    It’s what UNIX commands use. `mk`, `cp, `mv, etc.

    >Plus, how valuable is it to save two keystrokes?
    We’re talking about idealism, so “it doesn’t really matter that much” doesn’t apply.
    It affects the bigger picture, though. Obviously those 2 keystrokes mean nothing, but it if you have an entire program full of little less-than-idealisms then it begins to spiral into an awkward mess and mental real-estate gets wasted on trying to navigate an unclear picture.

    >If I know a class has a password attribute I should be able to guess that that attribute is called password.
    You shouldn’t be programming by guessing, you should be figuring it out by being scientific.

    >Explanation: There are certain words that have no singular form.
    Again, I don’t think you should be going out of your way to specify attributes about the variable.

    Is the selling point that you can iterate over it and use the singular versions?
    Because I don’t think one should do that, either:
    1. The difference in so many pluralisations is just an `s`, and that causes 2 variables to be exactly one letter apart.
    2. This concept is so inconsistent in so many languages that it’s utterly hopeless to try and make that standard

    >Explanation: Names like key and value have almost no meaning. There’s almost always a more purpose-revealing option.
    This I support for the same reason that you shouldn’t specify information about the variable in the name that isn’t redundantly communicated by the type.

    Reply
  4. Pawel

    How about `ls` for list, fn for `fn` or arr for array.

    Let’s say we write generic function, which filter collection of items. We could write something like:

    “`csharp
    static IList FilterInvalidItems(IList ls) => ls?.Where(item => item.Invalid).ToList() ?? List.Empty;
    “`

    Another thing is naming inside predicates. Should we keep them verbose or shorten?

    Reply
  5. Stephen Jones

    You make a lot of good points. I agree with nearly everything.

    However, I think a lot of your anti-patterns are helped by _light_ Hungarian notation (type prefixes).
    Sure, HN got a bad rap in the 90s from over-use and added complexity. I get it. Using aplisThing to mean array-of-pointers-to-lists-of-strings is absurd.

    Instead, sticking to a small set of basic prefixes clarifies some of your anti-examples with only a tiny amount of added typing:

    aCustomers[] – array of customers
    nCustomers – customer count
    sCustomer – name of customer

    OK, many people say type prefixes are redundant since modern IDEs show you the type of variables easily. Agreed, but code is much more readable/scannable when you _don-‘t_ have to hover over every parameter and variable just to get the gist of its type.

    In my experience, here are 90% of the basic “Hungarian-light” prefixes you’ll ever need:

    a: Array (aCustomers = array of Customers)
    b or f: binary/flag (bError = true/false)
    n: Number (nCustomers = number of Customers)
    i: index to an array or loop (iRetries = count number of retries in loop)
    s: String
    dt: date (dtStart = date of start)
    o: object (oCustomer = new Customer();)
    li: List

    Reply
    1. Stephen Jones

      Also, I’d argue that type prefixes are a near necessity now that dynamically-typed languages, like JavaScript, have become important (some say the dominant) in our industry.

      Reply
  6. Christina Eneroth

    Agree 100%. I don’t see any reason to break these rules.

    Even if every other line refers to the same class, say Customer, Cust isn’t any easier to read, and with auto complete isn’t any quicker to write. Also, typically “the most common” classes/types aren’t just the one the application is built around, but 10 or so, which makes it much harder to understand the code for new developers. If just one piece of the puzzle was missing you could easily guess it from the context, but when the same code overabbreviates so many things you can’t read it, you don’t understand what the abbreviation mean either. Just keep it simple and spell it out.

    Regarding introducing new meta syntax like a light Hungarian notation I don’t see why. customers, customer_count and customer_name reads better than aCustomers, nCustomers and sCustomer. Again, just keep it simple and spell it out.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *