Fifty Shades of J/Chapter 05
Table of Contents ... Glossary ... Previous Chapter ... Next Chapter
Principal Topics
- b. (basic characteristics), verb ranks, conjugations
Rank
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 an 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 conjugations 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 conjugations along lines such as the following:
- Pure scalar verbs, all three rank-vector items = 0
- Monadic list verbs, all rank-vector items = 1
- ‘Irregular’ verbs with hybrid ranks, mostly specialised
- Pure ’structural plus’ verbs, ranks are (_ 1 _)
- Verbs with all ranks infinite.
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 #: (antibase2) and dyadic #: (antibase) have a strong semantic association although formally they belong to different conjugations.
Scalar verbs which form the first conjugation all have rank 0 and are the ‘most penetrating’, meaning that unless otherwise modified by the rank conjunction they operate at the lowest cell levels. The ordinary arithmetic verbs are thus all of rank 0. Second conjugation verbs are all monadic and operate at the level of lists, such as i. (integers) and #: (base 2). The conjugations range from the most penetrating in the first conjugation through to those of the 4th and 5th conjugations which handle objects at a macro level. In between at the third conjugation are a set of verbs which are the counterpart of irregular verbs in natural language grammars.
Conjugation 2 contains monadic verbs only which make no sense other than when applied to lists, for example on integers (i.) (integers) and on characters (;:) (word formation).
Conjugation 3 contains irregular verbs some of which are 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.
Conjugation 4 consists of the structural verbs, all of whose right ranks are infinite, meaning that their arguments are processed in their entirety as single objects.
Conjugation 5 consists of verbs whose ranks are all infinite (_).
Compound Verbs and Rank
Compound verbs formed with conjunctions and adverbs possess rank vectors in the same way as primitive verbs, and Henry’s maxim applies as much to compound verbs as to primitives. The rules which govern the rank vectors of compound verbs are somewhat complex, and it is generally best from a pragmatic point of view to use the b.0 test to confirm them. It is worth noting though that compounds arising from atop, appose and bond have rank vectors (_ _ _) which is a consequence of their not forcing rank inheritance (see Essay #2: A Composition on Composition) in which the following table appears):
at and appose are the most basic composition verbs and follow the rules:
Compound Monadic | Compound Dyadic | |
---|---|---|
at | (u@:v)y means u(v y) | x(u@:v)y means u(x v y) |
appose | (u&:v)y means u(v y) | x(u&:v)y means (v x)u(v y) |
atop and compose invoke rank inheritance and obey the rules:
Compound Monadic | Compound Dyadic | |
---|---|---|
atop | (u@v)y means (u@:v)"(m v)y | x(u@:v)y means x(u@:v)"(lr v)y |
compose | (u&v)y means (u&:v)"(m v)y | x(u&v)y means x(u&:v)"(mm v)y |
where m v is the monadic rank of v, lr v is a list of its left and right ranks, and mm is the list m,m.
under requires that v be monadic:
Compound Monadic | Compound Dyadic | |
---|---|---|
under | (u&.v)y means v^{-1}(u v y) | x(u&.v)y means v^{-1}((v x)u(v y)) |
Compare these:
2 3(+/@%)4 5 NB. (+/@%)b.0 is 0 0 0 0.5 0.6 2 3(+/@:%)4 5 NB. (+/@:%)b.0 is _ _ _ 1.1
Using the clinic analogy, in the first case the ‘patients’ are called in matched pairs, and each is divided to give result 0.5 0.6. 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 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.
The name at conveys less well the way in which infinite rank produces verb sequencing, that is “u following v”, is a perhaps a more pictorial way of thinking about it.
Another example is:
2 (#.@^.)2 5 6 NB. (#.@^.)b.0 = 0 0 0 1 2.32193 2.58496 2^.2 5 6 1 2.32193 2.58496
i.e. the (#.) has no effect. However:
2 (#.@:^.)2 5 6 NB. (#.@:^.)b.0 = _ _ _ 11.2288 2 #.1 2.32193 2.58496 11.2288
i.e. the left argument applies to both u and v.
Here are yet more examples illustrating atop and at:
Compare:
({:@*:)i.2 3 0 1 4 9 16 25
with:
({:@:*:)i.2 3 9 16 25
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 in the first case 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.
Next compare:
({:@#.)2 3$1 0 1 1 1 0 5 6
with:
({:@:#.)2 3$1 0 1 1 1 0 6
Here the rank of the rightmost verb is 1, and so in the first case tail is applied to each of the base2s 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 0.88172 2
with:
2 3 4(+/@:%.)m 3.13978 _1.45699 1.19892
This is a dyadic example, in which the rank of the rightmost verb is 2. Operand 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.
Adverbs
Again, pragmatically it is best to use the b.0 test. J adverbs are relatively few in number and are all monadic in the sense that each qualifies a single verb, although the compounds arising may be either monadic or dyadic. The following is a table of them :
Monadic | Dyadic | |
---|---|---|
/ | Insert | Table |
/. | Oblique | Key |
\ | Prefix | Infix |
\. | Suffix | Outfix |
~ | Reflexive | Passive |
} | Item Amend | Amend |
b. | Basic Characteristics | Boolean |
t. | Taylor coefficient | Deprecated |
t: | Weighted Taylor coefficient | Deprecated |
f. | fix | -- |
M. | Memoize | Memoize |
Regardless of the verb which they qualify, infixed and suffixed verbs always have left rank 0, reflecting the fact that the semantics require an integer as left argument for the compound verb. On the other hand, the rank of reflexive (~) is infinite because rank depends on arguments for the compound; the ranks of passive depend on those of the qualifying verb, as in:
(+~) b.0 _ 0 0 (#.~) b.0 _ 1 1 (%.~) b.0 _ 2 _ (i.~) b.0 _ _ _
Appendix : Verb Ranks
1st Conjugation: rank 0
Logicals (monadic)
-. | (not) |
Logicals (dyadic)
= | (equals) |
~: | (not equals) |
< | (less than) |
<: | (less than or equals) |
> | (greater than) |
>: | (greater than or equals) |
+: | (not or) |
*: | (not and) |
Arithmetics (monadic)
-. | (subtract from 1) for Boolean Not, or complementary probability |
Arithmetics (monadic and dyadic)
+ | (conjugate/plus) |
- | (negate/minus) |
* | (sign/times) |
% | (reciprocal/divide) |
^ | (exponential/power) |
^. | (natural logarithm/logarithm) |
<. | (floor/lesser of) |
>. | (ceiling/greater of) |
| | (modulus/residue) |
! | (factorial/out of) |
%: | (square root/root) |
+. | (real&imaginary/imaginary /GCD) |
*. | (length&angle/angle /LCM) |
Algorithmics (monadic)
p: | (i^{th} prime) |
Algorithmics (monadic and dyadic)
? | (roll/deal) |
j. | (imaginary/complex) |
o. | (pi times/circle functions) |
r. | (angle/polar) |
q: | (prime factors/prime exponents) |
2nd Conjugation: monadic, list-oriented
i. | (integers) |
{ | (catalog) |
;: | (words) |
#. | (base 2) |
". | (do) |
#: | (anti-base 2) |
p. | (roots) |
A. | (Anagram Index) |
C. | (Cycle-Direct) |
3rd Conjugation: irregular (with ranks)
(monadic)
%. | (matrix inverse : 2) |
(dyadic)
#: | (antibase : 1 0) |
p. | (polynomial : 1 0) |
{ | (from : 0 _) |
A. | (Anagram : 0 _) |
%. | (matrix divide : _ 2) |
C. | (permute : 1 _) |
4th Conjugation: dyadics with left rank 1, right rank infinite
$ | (reshape) |
|. | (shift) |
|: | (transpose) |
# | (copy) |
{. | (take) |
}. | (drop) |
": | (format) |
{:: | (fetch) |
5th Conjugation: rank infinite
(monadic)
= | (self-classify) |
< | (box) |
~. | (nub) |
~: | (nub sieve) |
{: | (tail) |
}: | (curtail) |
#: | (base) |
$ | (shape) |
|. | (rotate) |
|: | (transpose) |
# | (tally) |
{. | (head) |
}. | (behead) |
": | (default format) |
L. | (level of) |
(dyadic)
-. | (less) |
-: | (match) |
i. | (index of) |
". | (numbers) |
E. | (member of interval) |
(monadic and dyadic)
, | (ravel, append) |
,. | (ravel items/stitch) |
,: | (itemize/laminate) |
/: | (grade up/sort) |
\: | (grade down/sort) |
; | (raze/link) |
e. | (raze in/member in) |
$. | (sparse) |
$: | (self-reference) |
[ | (same/left) |
] | (same/right) |
s: | (symbol) |
u: | (unicode) |
x: | (extended precision) |
0: | (constant function) |
…also 9: to 1: and _1: to _9: and _: (infinity)