70

I've had a couple of discussions with a co-worker about the use of single letter variable names in certain circumstances inside our codebase, at which we both disagree.

He favours more verbose naming convention for these, and I do not.

There are three scenarios in my opinion where I use single letter variable names:

  • Loops - i for(int i = 0; i < 10; i++) { ... }
  • Lambda expressions in C# - x/y/z: .Where(x => x == 5)
  • Exceptions - e: try { ... } catch(ExceptionType e) { /* usage of 'e' */ }

These are the only scenarios where I would use it, and I obviously use more verbose naming conventions elsewhere.

My colleague put forward the following arguments for exceptions and loops:

  • i - it doesn't mean anything.
  • e - it's the most common letter in the English language. If you wanted to search the solution for exceptions, you'd find lots of undesired instances of e.

I accept these arguments, but have retorts that, if one does not know what i means in a for loop, then they probably shouldn't be a programmer. It's a very common term for loops and exceptions, as is e. I have also mentioned that, if one wanted, they could search for catch in the case of the exception.

I realise that this is subjective, but then, one could argue that coding standards are just that - opinions, albeit opinions by academics.

I would be happy either way, and will forward the results to him, but would rather that we (our company) continue to use a single coding standard, rather than have two developers with different opinions on what to use.

20 Answers20

84

I entirely agree with your opinion, and believe it isn't all that subjective.

The name of a variable is only as relevant as its scope.

There is no point in endless discussions about a name of a variable which will only be read by a person reading that particular small scoped piece of code. On the other hand, class names and member names need to clearly indicate what is going on. A lot of the expected behavior needs to be explained in a concise name.

Conventions improve readability.

i and e are common conventions used for those small scoped variables. Their intent is really clear if you know the convention.

Conciseness improves readability.

A short variable name which represents its intent clearly is to be preferred over a big variable name.

54

This really depends on the situation/context (and there is no one fits all solution).

In general i,j,k [btw, i can be taken as index; its usage comes from mathematical background where those were most often the first three indexes (remember tensor calculus). It may also be connected to Fortran's history, where i being the first implicitly typed integer, was often used as an index of a loop. ] are often used if it is a simple counter. If it has a specific meaning, like month or year then longer variable name is better.

Rook
  • 19,947
24

I agree with you: i as a loop variable name is an age-old idiom which should not confuse anyone. Same as e for an exception variable in a catch block. The latter (or rather both) should be short and simple, making the scope of the variable small, limiting the possibility of confusion for readers. And if someone wants to search for exceptions, better search for exception types or catch blocks anyway.

This said, I personally prefer using longer loop variable names such as index or idx. My reason is that i is so short, it is difficult to locate with the cursor.

Update

For reference, your coworker's arguments probably come from Ottinger's Rules for Naming - an excellent and pragmatic approach to the subject, recommended for reading. However, he may have overlooked the parts quoted below:

My personal preference is that single-letter names can ONLY be used as local variables inside short methods. The length of a name should somehow correspond to the size of its scope. If a variable or constant might be seen or used in multiple places in a body of code it is imperative to give it a search-friendly name.

And

Certainly a loop counter may be named i or j or k (though never l!) if its scope is very, very small and no other names can conflict with it. These are allowable because those are traditional solution-domain names.

17

I prefer meaningful variable names, even for loop variables. So, I usually write something like

for (int vertexIndex=0; vertexIndex<polygon.VertexCount; vertexIndex++)
   DoSomethingWithVertex(polygon[vertexIndex]);

I realize that there's little difference (either way) for a small loop like this, but:

  • if the loop body is longer, vertexIndex is often clearer than i. Of course i is an index, but what index? To which array? To which element in that array?
  • if the loop body calls other functions and passes the index as an argument, it's often easier to name the value consistently at the caller and the callee locations - and you wouldn't want to call method parameters i and x
  • if there are nested loops, using i, j, k as indices is very confusing and error-prone

to be consistent, I just use meaningful variable names for loop indices everywhere.

@André Paramés asked: "If the loop body is long enough to hide the meaning of i, isn't it time to refactor?"

A typical human brain has a short-term memory capacity of about 7 chunks of data. So if the loop body contains 8 or more chunks (where "chunks" are statements, local variables, parameters, comments), then your brain can't store the meaning of each of those chunks simultaneously. Instead, your brain will shift chunks in and out of the working memory while you read the code. For example, if you use variable names like i and j your brain will shift the meanings of i and j out of its working memory; the next time you read j, your brain will usually rely on context to find the meaning i.e. if you read customers[j] in the middle of the loop body, your brain will infer that j is an index into the customers array. If you had written customers[vertexIndex], you would see that you're using the wrong index. And that's for very short loop bodies with only 8 chunks of information, i.e. 5-8 lines of code.

If the body gets longer, you would typically extract it into a separate function with a parameter vertexIndex. And that's the second point I was making: If the variable is named vertexIndex inside that function, it should really be called vertexIndex at the caller, too.

nikie
  • 6,333
15

more verbose names can be just as meaningless. "i" is so commonly used as a simple iteration counter, it's almost standard practice. Calling the same counter "iter" because some "coding standard" prohibits single letter variable names doesn't add any value whatsoever.

"x", "y", and "z" are standard coordinate names, calling them xCoord, yCoord, zCoord adds nothing.

"e" of course is a mathematical expression. But it's relatively common to use it as a name for exceptions in catch blocks in Java. Calling it "exc" or something similar wouldn't again add real value.

jwenting
  • 10,099
10

I don't agree with your colleagues points.

To me, i means "iteration". Quite meaningful in the case of a loop.

Most IDE's allow for regex-type searching through the text. So you could search for 'e' not inside a word. That would be effective.

TZHX
  • 5,072
6

Short variable names are like pronouns in natural languages: to be used in a small context/scope. "i" in a short loop (no nestings) or "e" in a sequence of a few catches are perfectly ok. In many cases the long/descriptive name for "i" would be "the_stupid_index_needed_to_get_at_the_really_interesting_things" and you use a lambda expression just because it is needed in one context only.

Perl's $_ is a super-pronoun that works (for Perl programmers); though being allowed/encouraged to skip even 'it' (just "print" to "print $_") is something I'm a bit afraid of.

Searching for variable names to spot problems in code would not be my first idea. I think the programmer should have an idea about the class or function where to look in case of specific trouble.

6

(This is .NET-centric but your question mentioned C# lambda expressions, so I think this is relevant in your case.)

I would always use ex for an exception, as e is already used (by WinForms and ASP.NET WebForms conventions) as the EventArgs-typed argument for an event handler.

e.g.

protected void button_Click(object sender, System.EventArgs e)
{
    try
    {
        // whatever
    }
    catch (Exception ex)
    {
        // some exception handling
    }
}

However, MSDN uses e for exception variables.

During this discussion I'd suggest keeping two things in mind:

  • Variable naming conventions can usually be considered a form of religious war.
  • The most important coding convention is to keep to the style of the existing code.
5

I don't see any question here, but "i", "j" usually refer to coordinates just like "x" and "y" (my personal preference), I understand "e" might be a too common, but if your searching for exceptions, jus to that search "Exception".

the biggest problem of using single letter variables is that you might get confused with them, but if that variable has a limited scope, like in a loop or in a try catch , I don't see any problem with it

IvoC
  • 139
5

It is usually not very relevant when you have a single loop, and I prefer to use i or j for simplicity (and because of the convention). With nested loop, I sometimes use more verbose names to recognize which index relates to what. For example, if I have two arrays: of dates and quantitites, and I have a nested loop iterating first over dates, and then over quantities, I would use names dateIdx and quantityIdx, to prevent confusion. I've had bugs in my code when I wrote

matrix[i][j] = fun(dates[i], quantities[j]);

but should have

matrix[i][j] = fun(dates[j], quantities[i]);

With more verbose names, I would easily spot the error, as

matrix[quantityIdx][dateIdx] = fun(dates[quantityIdx], quantities[dateIdx]);

would just look wrong.

quant_dev
  • 5,227
4

An interesting epistemological question is that of meaning. Your colleague seems to assume that just because something means something to him, then there is meaning and otherwise it isn't.

The truth is, of course, that all those symbols we are using everyday, not just in programming, have meaning only because we attribute it to them. Or, to put it differently, the meaning is in your brain, not in the symbol. (To make this clear to oneselve, think of a cuneiform tablet - surely it did have meaning to the writers once upon a time, yet to most of the billions of people today it has not.)

In the light of this, the assumption that long names mean something, while short names do not, is absurd. Moreover, the expectation that a long name in a program text somehow carries the meaning it possibly has in a different context can lead to confusion.

Ingo
  • 3,941
4

A few points:

  • I've heard it suggested that you should prefer to use "ii" to "i" because if you ever do have to search for your loop index you'll be able to do so (and it's more visually distinct in general), and I think that's a good idea.
  • It depends on the scope and content of your loop. If your loop is simply doing something 10 times (eg. if it doesn't even access the loop variable at all), then I think "i" or "ii" is a thousand times more reasonable than a longer name. Everyone who has ever programmed at all should know or learn than "i" normally means "loop variable"
  • If your loop has a large-ish block of code inside, consider extracing that to a function, but either way, it may be valuable to have a short but meaningful name, eg. carIdx or day, not least because you may want to use "i" within the body of the loop.
  • If your loop is looping over the contents of a data structure, use a relevant name: an abbreviation or lowercase form of the datatype or variable contained if it's reasonably distinctive (eg.foreach car in carsOwned), or a longer form if your loop is more complex.
  • I think the same applies to lambdas and exceptions, although I'm less familiar. For instance, if there IS a sensible name for the input to your lambda, especially if there's more than one, then use it, but most of the time, the whole POINT of a lambda is to take an anonymous input, which everyone understands "x" to mean very well.
Jack V.
  • 1,130
4

When talking about readable code, you have a few things to consider:

  • What are your coding standards?
  • What are common conventions for your platform?
  • Is there the potential for confusion?

Assuming your coding standards do not say much about variable naming conventions, should think about discussing the code. For example with the loop below:

for(int i = 0; i < 10; i++)
{
    function(i);
}

The loop and all its functions can clearly be seen for the entirety of its scope. Now, imagine if we have nested loops (my favorite is the loop within a loop within a loop); or perhaps a loop that spans 100 lines. At that point, single letter iterators don't make a lot of sense, because it's so easy to get lost in the scope. You might want to refactor that 100 lines of code into some methods/functions to tame it a bit, but give the index a meaningful name.

On the subject of exceptions, I'd tend to agree that e just isn't a good name. However, my reasons are different from your friend's. I've done a lot of Java programming over the years, and have to deal with all those nasty checked exceptions that will never get thrown unless someone hacks your Java install. It's a fact of life. So as you are handling an exception, you have to encapsulate part of your exception handling within another exception handler. A common place this occurs is with JDBC code.

Bottom line, since each exception you were checking needs a unique name, and you are handling several types of errors in one try clause, give those exceptions names that mean something. Seeing e, e1, e2 doesn't help when I'm reading the code. What type of exception am I looking at? So again, since there is room for confusion, use long names.

3

I use i as a counter in loops only when:

  • it is used as an index; and
  • when its scope is very short.

As Rook said, the term i has a mathematical background as an index which tagged along as a programming convention. However, if it is a long loop, containing many variables, I would rename the counter i to something more explicit. If you have nested loops which iterate over for instance a matrix, I usually use row and col instead as i and j aren't exactly clear of what they refer to anymore ("Was it A[i][j] or A[j][i]...?").

Concerning e for exceptions I tend to use ex because I've seen e be used for element.

gablin
  • 17,525
2

It comes down to the difference between "What are you doing?" vs. "How are you doing it?"

First of all, where possible, use a foreach rather than a for. It better expresses what you are doing (i.e. Walk through the collection, and process each element.) This eliminates the problem of naming altogether.

If the index variable has any meaning at all other than "the_stupid_index_needed_to_get_at_the_really_interesting_things" (thanks E.H.) then use that meaning. row and col should be preferred over i and j if the array is representing a table. I also like to use position or pos if I'm doing lots of swapping.

However, the for (int i = 0 ....) idiom is so well established, that it is the de facto standard for an iteration. Don't mess with well established idiom without good reason.

Exception to above: Math or Physics -- Use the standard formulae from the text.

v = d/t; is more familiar to a physicist or engineer than velocity = distance / time;

1

Although I have no problem using "i" , conding standards demand something more. I wouldn't waste time arguing if it is necessary. For me "loopIndex" and "loopCounter" are two standard names I use instead of "i".

DPD
  • 3,527
1

@nikie listed some of my arguments already, but I want to add that your argument for limiting verbosity is weak.

Looking at the code in isolation, a more descriptive name would help. Identifying the loop itself is not an issue like you mentioned.

You will be using the 'i' many times in an app and could save some typing, but they don't all refer to the same thing. Many SQL scripts will alias a table with a single letter, but every time it is used, it's referring to the same table.

Coming up with meaningful names can be difficult, which is why it is best to make it a habit.

JeffO
  • 36,956
1

For "e", which of course stands for "exception" or "error", it's easy to search for exceptions, you just have to make sure that your search matches whole words (could also search for "e)" with matching whole words, if you don't use a space between the variable and the parenthesis), you won't find many "e"s all by themselves, except in the exception handlers.

For "i", it does have a meaning: it stands for "iterator" (or possibly "index", or "incrementor").

There is another reason to have a short variable name: shortcuts to what would be longer variable/class names which are used very often in a framework or what have you. Such as the JQuery "$".

Phoenix
  • 131
1

I thought i stood for 'increment'. I think the large number of different answers indicates there is something to the original question about meaningfulness of variable names--they often mean something traditional, but many people use them without knowing what the tradition is. It's easy to say that someone who doesn't know what i stands for "shouldn't be a programmer", but how do you learn what i stands for? There are a half-dozen answers right here.

David Rhoden
  • 101
  • 3
1

Steve McConnell in Code Complete had great advice for verboseness of variable names, it all depends on the scope and use of the variable. If you have a large class, your member variables better have clear names as you want to know what the variable represents when you're buried in code half way down the file. If you have a short function or a variable only used for a few lines of code you can make as short as you want as you aren't going to get confused about where its defined or what it represents, and a smaller name makes the code clearer.

Therefore for your case, i, e and x are great variable names. (assuming of course you dont have big complex loops)

Richard
  • 398