Home » Programming Best Practice » I, J, and K Should Die

I, J, and K Should Die

ijkOne of the hardest things we do as programmers is naming things.  But the easiest thing to name is counter variables and most of us do it wrong several times a day.

Of course, I’m talking about the notorious habit of naming our counter variables I, J, or K depending on how far down we’ve nested our looping.

History

Now, my understanding of the history of I, J, and K as common variables that we use in programming is that the practice started in FORTRAN.  There are two reasons why FORTRAN programmers did this.  FORTRAN is primarily a math language.  I, J, and K were used in math and so the practice was carried over into FORTRAN and from there to other languages.

FORTRAN encouraged this by also automatically declaring I, J and K as integers.  So using I, J and K made the code slightly easier to write and seemed to be considered a best practice at the time.

The other reason I, J, and K have prevailed as indexing variables is because in the early days, our variable name length was limited and in some languages, the variable names were stored in our code and consumed memory, which was a precious resource we didn’t want to waste on long variable names.

And so the practice continues to this day, largely because, “We’ve always done it that way.”

Story

But let me tell you a story that illustrates why this is a bad idea.

Admittedly, this story is pretty old, but only because in my 28 years of programming, this is still the best story I have to illustrate this issue.

You see, one day, back when I was still regularly programming in C++ (for you kids out there, C++ is what Java and CSharp get most of their syntax) my manager came to me with a bug.

Now the interesting thing about this bug is that it only occurred with one particular data set.  Most of the time it worked.

So, I put on my detective’s hat and went to work.  Now, I try to go for the quick kill first.  So, I set break points at various locations and checked variables and found out …  nothing.

That’s right, nothing.

After about four hours of trying various methods of the above and trying to step through the code only to find the looping that was taking place was going to cause that to take several weeks, I finally stumbled on to the problem.

And I do mean I stumbled, there’s no way I was going to find this problem using any of my standard debugging techniques.

Here is what the code looked like:

for(i = 0;i < someValue;i++)
{
    // lots of code here
    for(j = 0;j < someOtherValue;j++)
    {
        // still more code here
        for(k = 0;k < yetAnotherValue;k++)
        {
            // and again, more code
            if(someConditionThatBarelyEverHappens)
            {
                for(i=0;i < 3;i++)
                {
                    // some correcting code here
                 }
             }
            // more code
         }
        // more code
    }
}

Do you see what I see?

Do you see it?

What was happening is that the inner “for(i…)” loop was resetting the outer I so that the whole loop essentially turned into an infinite loop for this data set.

Now, this code was wrong on so many levels.  But the chief problem with the code is that by the time the original programmer for this routine got to the inner “for(i…)” loop they had forgotten that they’d already used “I” as a variable.

For all I know, the guy who put the inner “for(i…)” loop in wasn’t even the same guy as the one who created the outer variable.

So, how do we fix this code?

Well that’s easy.  In fact, creating variable names that mean something in place of I, J, and K is one of the easiest code fixes we can implement.

What is I and index of.  If you are looping through an index of bananas, call it “bananaIndex”  It isn’t rocket science.

Challenge

And so, my code challenge to you is this:

  • Never, ever, use I, J or K (or any other single letter) as a variable name in your code.  There should be a rule in your code quality checking that just prevents this.  Even in JavaScript code.  With tools like closure compilers, there is no valid reason to use short variable names even in JavaScript.
  • When you find an existing single letter variable name, change it to something meaningful.

References

Another Site Talking About I, J and K

http://www.eonlinegratis.com/2014/why-do-most-of-us-use-i-as-a-loop-counter-variable/#sthash.Wp7McXcC.dpbs

 

Other post in Programming Best Practice

Related Post

  • Avoiding Code ComplexityAvoiding Code Complexity A couple of weeks ago, I talked a bit about how we name things.  Specifically, I talked about the very bad habit of using the variables i, j, and k as variables in our for/next loops.A […]
  • Limiting Beliefs of ProgrammersLimiting Beliefs of Programmers At the risk of making half of my audience think I’ve gone off the deep end, I’m going to address a topic that I’ve only recently REALLY begun to understand, in part thanks to Soft […]
  • DRY ProgrammingDRY Programming Today I thought I’d talk to you about the programming principle known as DRY.  As you may know, DRY stands for “Don’t Repeat Yourself” and it shows up in a lot more places than you might […]
  • How to Become a Better ProgrammerHow to Become a Better Programmer As you advance in your career, you will inevitably want to improve as a programmer.  And as you search the Internet and read various web post on the subject you will also inevitably […]
  • 5 Reasons Learning Terminology Increases Your Effectiveness [As A Programmer]5 Reasons Learning Terminology Increases Your Effectiveness [As A Programmer] A couple of weeks ago I wrote a post “7 C# Interview Questions to Weed out Losers” which was my most popular post yet.  As of this writing, it has received over 13,000 views.  It also […]

About Dave Bush

Dave Bush is a Full Stack ASP.NET developer focusing on ASP.NET, C#, Node.js, JavaScript, HTML, CSS, BootStrap, and Angular.JS.Does your team need additional help in any of the above? Contact Dave today.

  • roberto

    I agree with you

  • jackar

    I think the problem with your code was not naming of variables but overall complexity of the method with 5 levels of nesting. Would you spot the problem faster if the variable name would be ‘count’?

  • Theodore

    Your inference from this bug is not correct.

    If you use the “loop with inline declaration format” you can never inadvertently reuse a counter: for(int i=0;i<10;i++). Here the loop itself is used for declaration of the counter variable. Hence if you use a inner for loop with the same counter your IDE will point out the mistake.

    Local variables inside a single method are the best place to "not worry about naming conventions". Especially for loops are best suited for the use of i,j,k. It is also so familiar to developers.

    For example if i have a command like get(i,j) I can easily grasp that i is probably in the outer loop and j in the inner loop.

    I would actively encourage people to use i,j,k in the local context within a single method.

  • John H

    wouldn’t another solution be to declare a new local instance of i as in:
    for (int i=0; i < someValue; i++)
    {
    }

    Won’t that be safe even if another i is declared somewhere else? Because i is now defined only within that block?

  • Dave Bush

    John and Theodore,

    Yes, using a “loop with inline declaration format” would “solve the problem” (as in it would have prevented the bug in the first place) but you are still left with variables that tell you nothing about the code other than (maybe) which is from which loop.

    jackar,

    Yes, the code complexity is yet another issue. Both the naming and the complexity contributed to the issue. Fixing either would have prevented the problem.

    I address the complexity issue in another post here http://blog.dmbcllc.com/avoiding-code-complexity/

    Replacing the variables i,j, or k with count really is no better. But if you are looping through an index of bananas, it would be much more clear to call the indexer bananaIndex.

  • jphamilton

    i, j and k are fine. It’s the nested for-loops that aren’t fine.

    • Dave Bush

      I addressed this in the comment below.

  • AmanZed

    Really; i, j, and k are fine. What is wrong with borrowing conventions from mathematics and physics, where i, j, and k are commonplace and well understood? Where do you think computer programming came from? Here’s just a case in point: summation notation: capital sigma, i=1 to N. Or 1 to m. Maybe it’s a Microsoft thing.

  • If you are going to do manipulations on 3 or 4 dimensional data, why not use a language more appropriate to the task, eg Matlab?

    • That would be fine if:
      1) You can find programmers that know Matlab (or other similar languages) and also know your primary language
      2) Every nested loop problem was a multidimensional data problem. (Which isn’t the case)