Contents
" (Rank) Conjunction
Specifies which n-cell a verb applies to.
A J array can be viewed as a list of lists, which can be counted by Tally (#). The first axis spans the outermost list, of the biggest cells, the last axis spans the innermost lists, of the smallest: the 0-cells. An array naturally falls into decreasing-sized cells on this basis. This is central to understanding Rank (").
]z=: i.2 3 0 1 2 3 4 5 #z NB. outermost list has 2 elements 2 #"2 z NB. outermost is 2-list, 1 of them, of 2 elements 2 #"1 z NB. Next-in are 1-lists, 2 of them, each of 3 elements 3 3 #"0 z NB. Next-in are 0-lists, 6 of them, each of 1 element (atom) 1 1 1 1 1 1
It is common to misconstrue +/"1 z as somehow signifying the axis along which addition takes place. APL has a misleadingly similar-looking construct: +/[1] z which actually does mean this. But this is not what really happens when J evaluates: +/"1 z.
See http://www.jsoftware.com/help/dictionary/intro20.htm for a clearer treatment than the entry in the J Dictionary for ".
foo=: 3 : 'smoutput ''y'' ; y' NB. Show the actual argument foo sees foo b. 0 NB. Show "ranks" of foo, ie what happens if "n is left out of foo"n _ _ _ NB. <monadic>, <left>, <right> ]z=: i.2 2 0 1 2 3 foo z NB. same as foo"_ because rank of foo <monadic> is '_' (as b. shows) ┌─┬───┐ │y│0 1│ │ │2 3│ └─┴───┘ foo"2 z NB. the 2-cells of z ┌─┬───┐ │y│0 1│ │ │2 3│ └─┴───┘ foo"_ z NB. effectively "2 because (#$z) is 2 ┌─┬───┐ │y│0 1│ │ │2 3│ └─┴───┘ foo"1 z NB. the 1-cells of z ┌─┬───┐ │y│0 1│ └─┴───┘ ┌─┬───┐ │y│2 3│ └─┴───┘ foo"_1 z NB. same as "1 because _1+(#$z) is 1 ┌─┬───┐ │y│0 1│ └─┴───┘ ┌─┬───┐ │y│2 3│ └─┴───┘ foo"0 z NB. the 0-cells (=atoms) of z ┌─┬─┐ │y│0│ └─┴─┘ ┌─┬─┐ │y│1│ └─┴─┘ ┌─┬─┐ │y│2│ └─┴─┘ ┌─┬─┐ │y│3│ └─┴─┘
Common uses
1. To sum a 2-D array across rather than down.
]z=: i.2 2 0 1 2 3 +/z 2 4 +/"1 z 1 5
Try symbolic addition with plus in place of (+)
plus=: (4 : '<(":>x),''+'',(":>y)')"0 NB. Note the final "0
plus/ z NB. sums the _-cells (2-cells in this case)
┌───┬───┐
│0+2│1+3│
└───┴───┘
plus/"1 z NB. sums the 1-cells
┌───┬───┐
│0+1│2+3│
└───┴───┘
plus/"0 z NB. because / now sees no atoms to put (+) between
0 1
2 3
plus/"2 z NB. applies plus/ to biggest cells (whole of z here)
┌───┬───┐
│0+2│1+3│
└───┴───┘
plus/"_ z NB. effectively "2 because (#$z) is 2
┌───┬───┐
│0+2│1+3│
└───┴───┘To see better what's happening here, try Box (<) in place of +/.
<z ┌───┐ │0 1│ │2 3│ └───┘ <"1 z ┌───┬───┐ │0 1│2 3│ └───┴───┘ <"0 z ┌─┬─┐ │0│1│ ├─┼─┤ │2│3│ └─┴─┘
2. To construct an array of the same shape as z having 1 (say) for every atom in z
]z=: i.2 3 0 1 2 3 4 5 1"0 z 1 1 1 1 1 1 z=: 2 3 $ 'abcdef' 1"0 z 1 1 1 1 1 1
3. To make a verb of a noun, fitting it for use in a tacit expression.
0:, 1:, ... are special cases of this, being equivalent to: 0"_, 1"_, ... respectively.
notimp=: smoutput bind 'NOT-IMPLEMENTED'
5!:6 <'notimp' NB. linear repn of verb
smoutput@('NOT-IMPLEMENTED'"_)Atop (@) needs a verb as its right-arg, which is what 'NOT-IMPLEMENTED'"_ is. It is a verb that ignores its arguments and returns the string: 'NOT-IMPLEMENTED'.
4. To apply a verb to individual atoms, when it would otherwise work on the whole array
z=: i.2 2 < z ┌───┐ │0 1│ │2 3│ └───┘ <"0 z ┌─┬─┐ │0│1│ ├─┼─┤ │2│3│ └─┴─┘
