Jump to content

Rank (J programming language)

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by 204.102.230.43 (talk) at 23:17, 7 July 2018 (Explained how rank is a generalization of looping, is not unique to J, and added references.). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Rank is a generalization of looping as used in other programming languages. It is also a generalization of maplist in LISP and map in modern functional programming languages, and a generalization of scalar extension, inner (matrix) product, and outer product in APL\360. The J is perhaps the canonical implementation of rank but rank is also available in Dyalog APL, the ISO Standard on Extended APL, and NARS2000.

Rank has several different meanings. In general, the concept of rank is used to treat an orthogonal array in terms of its subarrays. For instance, a two-dimensional array may be dealt with at rank 2 as the entire matrix, or at rank 1 to work with its implicit one-dimensional columns or rows, or at rank 0 to work at the level of its individual atoms.

  • Noun rank – The rank of a noun is a non-negative integer.
  • Verb rank – The rank of a verb is a list of three integers.
  • The rank conjunction – The rank conjunction (") is used to derive a verb with a specific rank.

Rank as a generalization of looping

To understand rank, you need to understand some very basic array based programming concepts. In most array based languages, mapping is denoted with a forward slash / it takes two arguments, on its left the operation and it's right the array it's operating on.

   +/ 1 2 3
6

The result was 1 + 2 + 3, as expected.

You can also create an N dimensional integer array with i., it takes an array of arguments, the number of arguments defines the dimension and each number defines the length of the dimension.

   i. 3
0 1 2

   i. 2 3
0 1 2
3 4 5

   i. 3 4 5
 0  1  2  3  4
 5  6  7  8  9
10 11 12 13 14
15 16 17 18 19

20 21 22 23 24
25 26 27 28 29
30 31 32 33 34
35 36 37 38 39

40 41 42 43 44
45 46 47 48 49
50 51 52 53 54
55 56 57 58 59

Now let's apply mapping addition to a 2 dimensional array.

   +/ i. 2 3
3 5 7

The result was 0 1 2 + 3 4 5, as expected. Map runs down each column, adding together each pair of numbers.

This application of +/ to a 2D array corresponds to the C code fragment:

for(j = 0; j < 3; ++j) {
    sum[j] = 0;
}
for(i = 0; i < 2; ++i) {
    for(j = 0; j < 3; ++j) {
        sum[j] += array[i][j];
    }
}

Suppose we wanted to add up the items of each row, as in the C code fragment:

for(i = 0;i<2;++i) {
    sum[i] = 0;
    for(j = 0; j < 3; ++j)
        sum[i] += array[i][j];
    }
}

To produce the result 3 12. How can we do it in J? Simply using rank.

   +/"1 i. 2 3
3 12

Noun rank

Nouns, in J, are arrays. The rank of a noun is the number of dimensions of that array. The derived verb #@$ determines the rank of a noun.

Verb rank

Verbs, in J, are functions which take noun arguments and produce noun results. The rank of a verb controls how the verb is applied to nouns with ranks greater than 0. This verb rank is expressed as three numbers:

  1. Rank for the monad case; for example, −y uses as a monad
  2. Rank for the left argument for the dyad case; for example, x−y uses as a dyad
  3. Rank for the right argument for the dyad case

In all cases, there is some underlying verb definition which applies to cells, which are subarrays of the indicated rank. Or, if the argument does not have that many dimensions, the entire argument.

In verbs, negative rank is interpreted as the rank of the noun supplied for that argument less the indicated value. (But never less than zero.)

For example, a verb with monadic rank of negative one when given an argument of rank 3, breaks the argument down into a list of rank 2 arrays. The verb's body is applied once to each of these 2-dimensional subarrays.

In the context of a specific verb and a specific noun, the dimensions of that noun are divided into the sequence of prefix dimensions, called the frame, and the sequence of suffix dimensions, called the cells. Positive verb ranks indicate the number of cell dimensions, negative verb ranks indicate the number of frame dimensions.

In the dyadic case, there are two frames: one for the left argument, and one for the right argument. These frames must agree. If the frames are not identical, one must be a prefix of the other. The result of evaluating this verb will have the dimensions of the longest frame as the prefix dimensions of its result. (Trailing result dimensions, if any, would be the result of the verb applied to the relevant cell(s).) In degenerate cases, where the arguments do not have sufficient dimensions, the rank of the verb is effectively reduced (which would influence its result).

For example,

   10 + 4 5 6
 14 15 16

Here, the verb + has a rank of 0 0 0, the left argument has a rank of 0, and the right argument has a rank of 1 (with a dimension of 3). Thus, the left argument has a rank 0 frame and the right argument has a rank 1 frame (with a dimension 3). The left argument's (empty) frame is a valid suffix for the right argument's frame, so this is a valid operation. The result has a rank of 1 and a dimension of 3.

The rank conjunction

The rank conjunction takes a verb left argument and creates a new verb using that as the body of the verb. The right argument specifies the rank of this derived verb.

If the right argument is only two numbers, they are taken as the ranks for the dyadic case, and the second number is used for the monadic case.

If the right argument is only one number, it is taken as the rank for all three cases.

If the right argument is a verb, its rank is used.

For example, these all derive the same verb:
  • +"0 0 0
  • +"0 0
  • +"0
  • +"+

If the left argument to the rank conjunction is a noun, a constant verb is created. The body of this verb ignores the values of any arguments and always produces a result which is that noun.

References

Abrams, P.S., An APL Machine (http://www.slac.stanford.edu/pubs/slacreports/reports07/slac-r-114.pdf), Ph.D. Thesis, Stanford University, 1970-02; §II.E.

Backus, J.W., Can Programming be Liberated from the von Neumann Style? A Functional Style and Its Algebra of Programs (https://www.thocp.net/biographies/papers/backus_turingaward_lecture.pdf), Communications of the ACM, Volume 21, Number 8, 1978-08.; §11.3.3.

Bernecky, R., An Introduction to Function Rank (https://dl.acm.org/citation.cfm?id=55632), APL88 Conference Proceedings, APL Quote Quad, Volume 18, Number 2, 1987-12.

Bernecky, R., and K.E. Iverson, Operators and Enclosed Arrays (http://www.jsoftware.com/papers/opea.htm), 1980 APL Users Meeting Proceedings, 1980-10-06 to -08.

Bernecky, R., K.E. Iverson, E.E. McDonnell, R.C. Metzger, and J.H. Schueler, Language Extensions of May 1983 (http://www.jsoftware.com/papers/satn45.htm), SATN 45, I.P. Sharp Associates Limited, 1983-05-02.

Brown, J.A., The Principles of APL2 (http://www.softwarepreservation.org/projects/apl/Papers/PRINCIPLESOFAPL2), TR 03.247, IBM Santa Teresa Laboratory, San Jose, California, 1984-03; §20.0.

Dyalog, Dyalog APL Version 14.0 Release Notes (http://www.dyalog.com/dyalog-version-140.htm), Dyalog Limited, 2015.

Hui, R.K.W., Rank and Uniformity (http://www.jsoftware.com/papers/rank.htm), APL95 Conference Proceedings, APL Quote Quad, Volume 25, Number 4, 1995-06.

Hui, R.K.W., Remembering Ken Iverson (https://keiapl.org/rhui/remember.htm), 2004-11.

Hui, R.K.W., Inner Product—An Old/New Problem (http://www.jsoftware.com/papers/innerproduct/ip.htm), British APL Association Conference 2009, 2009-06-08.

Iverson, K.E., Operators and Functions (http://www.jsoftware.com/papers/opfns.htm), Research Report #RC7091, IBM, 1978-04-26.

Iverson, K.E., A Dictionary of APL (http://www.jsoftware.com/papers/APLDictionary.htm), APL Quote Quad, Volume 18, Number 1, 1987-09.

Iverson, K.E., A Personal View of APL (http://www.jsoftware.com/papers/APLPersonalView1.htm), IBM Systems Journal, Volume 30, Number 4, 1991-12.