" (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│
└─┴─┘```