The roots of I,J,K,L usage

Open any codebase written in the last sixty years and you will find loops named i, j, and k. Nobody assigned those letters in a committee. The convention survived punch cards, minicomputers, the internet era, and every language fad since. It has two roots: mathematics and a single rule in the original Fortran compiler.

The mathematical root

Mathematicians were using letters as indices long before computers. In summations, matrix notation, and vector algebra, i and j are the standard row and column indices. René Descartes set the tradition of i, j, k for consecutive unknowns back in the 17th century La Géométrie, and index notation in linear algebra solidified it. When the first programmers wrote numeric code, they transcribed the notation they already knew: Σᵢ became for(i...).

The Fortran rule

Fortran, the first widely adopted high-level language (1957), made the convention official by accident of design: variables starting with the letters I through N were integers by default unless explicitly declared. I, J, K, L, M, N — the first three were the natural loop counters. The rule was a convenience for a language designed to be typed by mathematicians and engineers, and it hardened the pattern into a generation of habits.

Because Fortran dominated scientific computing for decades, the convention spread to the languages that followed. By the time C, Pascal, and later Java and Python arrived, i, j, k for loop variables was already the standard, and each generation of programmers inherited it from the last.

Why it stuck

    Compactness. Short names keep loop bodies dense and readable; the loop variable rarely needs to carry meaning beyond “index.”

    Convention. A shared convention means zero cognitive overhead: every reader instantly knows i is the loop counter and does not wonder whether it means something else.

    Nested sequences. i, j, k give an obvious naming order for nested loops over multi-dimensional arrays — rows, then columns, then depth.

Where the convention stops

The same tradition has limits worth respecting. Short index names work for tight numeric loops; they fail when the variable’s role matters. A loop over users is clearer as user, and modern style guides push named iteration (for user in users, enumerate(), .iter()) precisely because i carries no domain meaning. Reach for i, j, k when you are doing index math; reach for a real name when you are doing domain logic.

So next time you type for i := 0; i < n; i++, remember: you are writing in notation that predates the computer, formalized by a 1950s compiler that defaulted those letters to integers. Few conventions in software have survived that long — and few deserve to.

Leave a Reply

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