Rank in q refers to the number of arguments a function takes – or the number of indices you can use to index an array. Because Apply and Index have the same syntax, functions and lists are syntactically interchangeable in many contexts, reflecting a key insight at the heart of q. (For example using lists and dictionaries with iterators.) So both functions and data structures have rank.
Most kdb+ data structures have rank 0, 1, or 2. (Atoms have rank 0: they can’t be indexed.) In q’s ancestor languages APL and J, functions take no more than two arguments, but the languages make more elaborate provision for higher-rank arrays.
In APL and J the term rank refers to how a function partitions its arguments. For example Equal = compares items atom by atom. We say it has implicit atomic iteration, or just that it is atomic; in APL terms it has rank 0. On the other hand while Index At@ has atomic iteration through its right argument (is right atomic) it treats its left argument as a list, no matter how complex its items. An APLer would say Index At has left rank 1 and right rank 0. And Match~ has no implicit iteration at all; it compares its left and right arguments in their entirety. An APLer would say it has infinite rank.
And we care because? APL and J have a rank operator. It modifies the way functions – primitive or user-defined – iterate through their arguments. In an earlier episode of the Array Cast, Joel Kaplan told how Arthur Whitney, the designer of q, discovered that many primitive functions could be defined from others by applying the rank operator. In the end, J then APL and BQN got the rank operator, and q did not.
The latest episode of the Array Cast explores rank and leading-axis theory. While q does not have a rank operator, it is illuminating to consider the ways in which problems can be solved merely by altering how a function iterates through its arguments.