4

Can using single-character variable names as parameters in a function okay?

For example, look at the code below:

public static int factorial (int x) {

    if (x == 0) {
        return 1;
    }

    return (x * factorial (x - 1));
}

In this case, is using variable name "x" okay as the parameter for the function? In which case would you want to avoid such thing?

Tulains Córdova
  • 39,570
  • 13
  • 100
  • 156

2 Answers2

5

In your factorial example it's perfectly OK.

An example of how it would not be OK is:

public int calculateInterest(int x, int y, int z){
      //////
}

Because to calculate the interest you need to pass principal, rate and time.

  • Is the coder expected to pass them in that order asumming x is principal, y is rate and z is time?

I think not.

public int calculateInterest(int principal, int rate, int time){
      //////
}

In this answer from a similar question there's a list of acceptable cases for single-character or two-character variable names.

Tulains Córdova
  • 39,570
  • 13
  • 100
  • 156
3

Using meaningful name for function parameters is a way of making the code self-documented and you should do always do it.

Though, there are some situation where it can introduce unnecessary verbosity or even confusion. In these case it's ok to use a single letter. For example:

  1. Purely arithmetic functions that takes a single number (usually x).
    • OK: factorial(x), sin(x), etc.
    • Unnecessary: abs(number)
  2. When there exists conventional letters.
    • OK: vectorLength(x0, y0, x1, y1), repeat(something, n).
    • Obviously not OK: dotProduct(vector0horizontalComponent, vector0verticalComponent , vector1horizontalComponent, vector2verticalComponent),
    • Unnecessarily verbose: repeat(something, numberOfRepetitions)
  3. Trivial functions and small lambda expressions.
    • OK: div(x,y) = x/y, map(u -> u.address.country, users)
    • Unnecessarily verbose (but ok): , div(numerator, denominator), map(user -> user.address.country, users)
  4. Highly generic code. Often seen in functional code, especially when using destructuring.
    • OK: map(f, [x, xs]) = if xs == [] then [] else [f(x)] + map(f, xs)
    • Unnecessarily verbose: map(functionToApply, [firstElementOfList, restOfList]) = ....

When readability inside a function is an issue, remember you can always use a variable to rename another locally, e.g:

function getRotationMatrix(angle) {
    var t = angle;
    return new Matrix([
        [+cos(t), -sin(t), 0],
        [+sin(t), +cos(t), 0],
        [0,       0,       1],
    ]);
}

The rule I follow is to keep names (whether for variables, parameters or even functions/methods/classes) as short as possible while still being perfectly clear within the context. Which means, among other things:

  • Longer names are useless if they don't contain useful information on the variable. E.g: userInstance, TextInput0, TextInput1
  • Longer names are useless if they contain redundant information : E.g. intYear, userList, UrlUtils.getUrlParser(...).parseUrl()
  • Avoid abbreviation as they are hardly ever totally unambiguous (except common ones in the language or domain)

TLDR: use names as long as necessary, no shorter, no longer.

kjaquier
  • 159