Current issue

Vol.26 No.4

Vol.26 No.4

Volumes

© 1984-2024
British APL Association
All rights reserved.

Archive articles posted online on request: ask the archivist.

archive/20/2

Volume 20, No.2

J-ottings 38: Decline and Rise : a Matter of Rank

by Norman Thomson

Rank is of enormous importance in J. There are two types of rank, noun rank and verb rank. The former can be applied to any object in the J universe, and is the “tally-of-the-shape” or in J :

   nrank=.#@$

Verb rank is somewhat more subtle, and is of even greater importance in understanding J language constructs. Henry Rich put things with admirable conciseness in “J for C Programmers”:

“If you don’t know the rank of a verb, you don”t know the verb!”

It is not just primitive verbs which possess rank, user defined verbs also possess it, and so do compound verbs, that is verbs formed by combining or adapting primitive verbs using appropriate conjunctions and adverbs. Moreover, there is no excuse for J programmers not knowing any relevant verb ranks, since these are immediately obtainable for any verb by using the b. adverb with right argument 0 :

   %. b. 0                 NB. primitive
2 _ 2
   +/ b. 0                 NB. compound (adverbial)
_ _ _ 
   +.@*: b. 0              NB. compound (using conjunction)
0 0 0
   mean=.+/ % # 
   mean b. 0               NB. user defined
_ _ _ 

Within the J literature I am not aware of any explicit categorisation of verbs by rank, which is why much of this article consists of a lengthy appendix which does just this. I hope that some readers may find this appendix helpful, perhaps long after this preamble has been forgotten.

As postings on the J conference testify, the distinction between @ and @: is a stumbling block in the path of almost every new learner; what I hope to show here is how this block can be rapidly and effectively smoothed by a conscious endeavour to understand verb rank.

In general verbs have three unforced ranks, which are, in the order given in the dictionary definitions:

monadic rank, left rank, right rank

The word “unforced” acknowledges that verbs can have their basic ranks changed to an explicit value by using the rank conjunction " .

Classification by rank has some affinity with verb declensions in the classical languages, and although this analogy should not be pushed too far, it seems reasonable to think of verbs as being grouped by declensions along lines such as the following :

1. Pure scalar verbs, all three rank vector items = 0
2. Pure list verbs, all rank vector items = 1
3. Verbs with hybrid ranks, mostly specialised verbs
4. Pure structural verbs i.e. all rank vector items = infinite
4a. ‘Pure structural plus’ verbs, ranks are _ 1 _

It should be stressed that a verb rank of, say, 1 should not be read as meaning that only objects of noun rank 1 are acceptable as arguments, but rather that all arguments will be processed as assemblages of rank 1 objects. There is an analogy with the operation of a clinic which has a large and motley assembly in the waiting room, from which patients may either be called one by one (processing at rank 0), or by families (that is lists, rank = 1) or the whole lot may be taken together as a single block of humanity (rank infinite). The analogy goes further than this, because the method of calling is independent of what happens once the surgery is entered, in other words, rank comes first, semantics later. Immediately following the above quotation in Henry’s book is an explanation in detail of how rank is applied in particular cases, that is how rank and semantics are married together in terms of cell and frame selection. However, focussing on ranks shows that, apart from the “special algorithm” verbs, J verbs can be grouped into quite a small number of categories.

A general problem in categorising verbs by rank is that of deciding when the monadic and dyadic forms are sufficiently related to each other to justify retaining this association even if they possess different rank vectors. At one extreme monadic > (open) and dyadic > (greater than) are completely unrelated in meaning, even although all their rank vector items are zero. On the other hand verbs such as monadic #: (= antibase 2) and dyadic #: (= antibase) have a strong semantic association although formally they belong to different declensions.

The first declension is in many ways the most familiar, consisting of pure scalar verbs which fall into three broad categories: logical, arithmetic and algorithmic.

Declension 2 is the next easiest to review, since it contains verbs which make no sense other than when applied to lists, for example integers i. (= integers) and ;: (= word formation).

Declension 4 consists of the pure structural verbs, all of whose ranks are infinite, meaning that their arguments are processed in their entirety as single objects.

Declension 4a is sufficiently similar to the previous set to merit sub-classifying rather than a new declension. In each case the primary monadic form has infinite rank, but there is also a matching dyadic form which applies left arguments at the list level (i.e. left rank = 1).

Finally declension 3 consists of hybrids. Three of these are general, #: (monadic and dyadic) and { (from), the other five are specialised algorithmic verbs such as %. (= matrix inverse / divide), which are of great value to a minority of J users, and of little or no interest to the rest.

Finally, compound verbs possess rank vectors in exactly in the same way as primitive verbs, and Henry’s maxim might be extended :

“If you don’t know the rank of a compound verb, you don’t know the conjunction/adverb!”

The dictionary descriptions may seem somewhat bewildering at first, with references to mv, lv, etc. Not so! The present appendix contains a list of conjunction rank rules, together with the permissible noun-verb combinations. For each vv combination the conjunction has the form "u conjunction v", and m=monadic, l=left, r=right.

atop (@) has rank vector mv lv rv, which means that in all three cases the rank of the compound verb is identical to that of the right verb in the compound. For at (@:), however, all ranks are infinite regardless of the composed verbs. So for

   2 3(+/@%)4 5      NB. rank of verb v(%) is zero 

using the clinic analogy, the “patients” are called in matched pairs, and divided to give the result 0.5 0.6. Then at rank 0 leaves items unchanged for a final result 0.5 0.6. However, for

    2 3(+/@:%)4 5

the patients are called in two blocks (left and right), which are divided as blocks to give 0.5 0.6, and then "plus-insert" is applied to this single block to give 1.1.

Informally the difference between atop and at is that u and v are more closely bound in the former. The name “atop” is very apt as it gives a picture of two creatures, one piggy-backing on the other, and thereby fusing to make a tight compound before any considerations of data come into play. “at” conveys less well the way in which infinite rank produces verb sequencing, that is “u following v”, is a more meaningful phrase than “u at v”. Here are some further examples of atop and at :

Compare ({:@*:)i.2 3 and ({:@:*:)i.2 3 . As above, the only rank which matters in the first case is that of *: (= square) which is 0. The semantic rule which extends tail when applied to scalars (i.e. at rank 0) is “no change” and so the final result is

0  1  4
9 16 25
In the second case, tail with infinite rank means the tail of the list of lists arising from squaring, which gives the result list 9 16 25.

Compare ({:@#.)2 3$1 0 1 1 1 0 and ({:@:#.)2 3$1 0 1 1 1 0

Here the rank of the rightmost verb is 1, and so in the first case tail is applied to each of the antibase 2s of the two three-lists which make up the right argument, giving a final result 5 6. In the second case, tail applies to the entire result of #. which is a two-list, so that the final result is 6.

Compare 2 3 4(+/@%.)m=.?2 3 3$10 and 2 3 4(+/@:%.)m

This is a dyadic example, in which the rank of the rightmost verb is 2. m represents two sets of 3 by 3 linear equations with the same right hand side 2 3 4. In the first case the result is the sums of each of the three solution sets (x1+ y1+ z1, x2+ y2+ z2) . In the second case summation applies to the two-list of solution values, so that the final result is (x1+ x2, y1+ y2, z1+z2) .

... and so I could continue. However, space is not unlimited, and in any case, if I have succeeded in explaining the general principles, then the reader will already have reached a point where he needs no further assistance from me!


Appendix : Verb Ranks

Declension 1, rank vector = 0 0 0

Logicals (all dyadic)

= Equal~: Not-Equals
< Less Than<: Less than or Equal
> Larger Than>: Larger or Equal

Arithmetics

MonadicDyadicMonadicDyadicMonadicDyadic
+ConjugatePlus+.Real/ImagGCD(Or)+:Double Not-Or
-Negate Minus-.Not -:Halve
*Signum Times*.Len/AngleLCM(And)*:Square Not-And
%Reciprocal Divided by%:Sq Root Root
^ExponentialPower^.Natural LogLogarithm
<.Lesser of>.Larger of
|Magnitude Residue
!Factorial Out Of

Algorithmics

MonadicDyadicMonadicDyadic
?RollDealp:Primes
j.ImaginaryComplexq:Prime FactorsPrime Exponents
o.Pi TimesCircle Functionsr.AnglePolar

Declension 2, all rank vector items = 1

MonadicDyadic
i.Integers1
{Catalogue1
;:Word formation1
#.Base 21Base1 1
".Do1

Declension 3, hybrid ranks

MonadicDyadic
#:Antibase 2_Antibase10
{ From0_
%.Matrix Inverse2Matrix Divide_2
A.Atomic Permute1Atomic Permute0_
c.Characteristic2Eigenvalues02
C.Cycle1Permute1_
p.Roots1Polynomial10

Declension 4, all ranks = infinite

MonadicDyadic
=Self-Classify-.Less
<Box-:Match
~.Nub i.Index Of
~:Nub SieveE.Member of Interval
{:Tail".Numbers
}:Curtail
L.Level Of

MonadicDyadicMonadicDyadicMonadicDyadic
,Ravel Append,.Ravel ItemsStitch,:ItemizeLaminate
/:Grade UpSort Up\:Grade DownSort Down
;RazeLinke.Raze InMember In
$.SparseSparse$:Self-ReferenceSelf-Reference
[Same Left]SameRight
{::MapFetch

Monadic and Dyadic
s:Symbol
u:Unicode
x:Extended Precision

Constant Functions, that is 9:, _8:,..., 0:, 1:,2:, ... 9: and also (infinity)

Declension 4a, rank vector = inf 1 inf

MonadicDyadic
$Shape Of_Shape1_
|.Reverse_Rotate (Shift)1_
|:Default Transpose_Transpose1_
#Tally_Copy1_
{.Head_Take1_
}.Behead_Drop1_
":Default Format_Format1_

Conjunctions

nnnvvnvvRank Vector
&xxbond, composemvmvmv
&.xundermvmvmv
&:xappose___
@xatopmvlvrv
@.xagenda (with gerund)mvlvrv
@:xat___
.xdot 2__
:.obversemuluru
::adverse___
^:xpower___
`:xevoke gerund___
;.xcut_1/2_ *
d.xderivative0
D.xderivativemu
H.xhypergeometric000

*1/2 is appropriate because cut is the J mechanism for partitions, for which there is a wide range of options, some of which process the left argument on a rank 1 basis, others on a rank 2 basis.

Adverbs

MonadicDyadic
/ Insert_Table__
/. Oblique_Key__
\Prefix_Infix0_
\.Suffix_Outfix0_
~/. Reflexive_Passiverulu
{./. Item Amend_Amend__
b./. Basic characteristics_Boolean00


script began 22:35:58
caching off
debug mode off
cache time 3600 sec
indmtime not found in cache
cached index is fresh
recompiling index.xml
index compiled in 0.1902 secs
read index
read issues/index.xml
identified 26 volumes, 101 issues
array (
  'id' => '10010520',
)
regenerated static HTML
article source is 'HTML'
source file encoding is 'ASCII'
read as 'Windows-1252'
completed in 0.2215 secs