You answered your own question: such
abstract (not meaningless) variables make sense when the code is completely generic. Most code however is somewhere between generic and specific, literal values, and variable names should represent that semantically.
Also, I would even argue that x and y are not meaningless in this context. There's a reason you didn't write:
function flip(gnarf) {
return function(t, m) {
return gnarf(m, t);
};
}
function compose(bip, boop) {
return function(blep) {
return bip(boop(blep));
};
}
The sequences
{a, b, c}, and
{i, j, k},
{m, n},
{p, q},
{x, y, z} are all well-established "abstract" variable names that most of us remember from high school algebra, and all have different baggage and expectations:
- a, b, and c tend to be generic labels for things, not numbers
- i, j, and k are used for indices and tend to be natural numbers (or more rarely for complex numbers/quaternions, where they are floats)
- m and n are used in matrices and also are used for natural numbers
- in maths, p and q are often fractions
- x, y, and z tend to represent coordinate systems and/or floating numbers
We can combine this to create variable sequences, with subtly different meanings. For example: compare (x1, y1), (x2, y2) with (xa, ya), (xb, yb). To me, if I see foo(x1, y1, x2, y2) that implies either top left, bottom right in an axis aligned bounding box, or perhaps the first point and the second point of a line or vector, or some other situation where the two points are somehow connected in one object or shape. Using (xa,ya) and (xb, yb) however suggests I'm dealing with two distinct points.