# User:Ian Clark/VerbRank

# Verb Rank

based on: http://www.jsoftware.com/help/jforc/loopless_code_i_verbs_have_r.htm

This page explains the concept of ** verb rank**.

Every verb has a verb rank.
It determines the ** cell** of the y-argument (and x-argument) to which the verb gets applied.

## Typical loops in a non-APL

Typical looping tasks you'd perform in a non-APL, i.e. a non- *Array Processing Language*:

1. Loops that do the same thing to each item of a given list 2. Loops that do different things to each item of a given list 3. Loops that do a given thing jointly to all the items of a given list, e.g. find the largest item 4. Loops applied to regular subsets of the given list 5. Loops applied to irregular subsets of the given list 6. Loops that carry over information from one iteration to the next 7. Loops that implement some finite-state machine.

Let's examine the easiest case (1. above) first.

J has a simple way of doing the same thing to each item of a given list.
We call this an *implicit loop* because it's not clear to a non-J programmer that J is doing a loop.
Why not? Because a non-J programmer will probably be looking for an *explicit* looping construct – and not see it.
Nevertheless some sort of loop is implied, in other words a loop is *implicit*.

## Examples of Implicit Loops

In the following examples

- The
:*dyad*(*Plus*`+`) adds numbers`x`and`y`

2 + 3 5

- The
:*monad*(*Integers*`i.`) makes an array of*shape*`y`

i. 2 3 0 1 2 3 4 5

### Example 1

If `y` is an array, (`y+2`) gives us the simplest example of an *implicit loop*.

At each iteration, the items of `y` are taken in turn and the number `2` gets added to that particular item

y =: 3 4 5 2 + y 5 6 7

### Example 2

If both `x` and `y` are lists, then
at each iteration, the items of `y` are taken in turn and the **corresponding item** in `x` gets added to that item in `y`

y =: 3 4 5 x =: 0 1 2 x + y 3 5 7

By **corresponding item** in `x`, we mean

- item 0 of
`x`gets added to item 0 of`y` - item 1 of
`x`gets added to item 1 of`y` - item 2 of
`x`gets added to item 2 of`y` - ...and so forth.

** DEFINITION:**
If lists

`x`and

`y`have the same number of items, then we say that they

*agree*.

But what if `x` and `y` don't have the same number of items, i.e. they don't agree?
Then J refuses to add `x` and `y`.
Instead J signals a ` length error `

y =: 3 4 5 x =: 0 1 x + y |length error | x +y

### Example 3

If `y` is not a list of numbers, but a list of lists of numbers (i.e. a ** table**)

] y =: i. 2 3 0 1 2 3 4 5 x =: 0 100 x + y 0 1 2 103 104 105

Look what happens:

- J
**does not**signal a`length error`, even though`x`and`y`have a different number of numbers, i.e. they have different*shapes*.

However they do have the same number of ** items** – i.e. they do

*agree*.

- In
`x`the items are**individual numbers**–`x`has two such items - In
`y`the items are**rows of numbers**–`y`has two such items.

- In

- The (two) atoms of
`x`get added to the (two) rows of`y`, exactly as in**Example 1**above.

### Example 4

- The
:*monad*(*Base 2*`#.`) makes an*integer*out of the*binary numeral*`y`– i.e. a*numeral*(a list of digits) consisting of the digits`0`and`1`only

#. 1 0 0 1 9 #. 1 0 1 5

- The
:*monad*(*Antibase 2*`#:`) does the*inverse*action, i.e. it makes the*binary representation*of the*integer*`y`– i.e. the representation of`y`as a*binary numeral*

#: 9 1 0 0 1 #: 5 1 0 1

** MNEMONIC:**
(to help you remember which is which)

- (
`#.`) with a**single**dot makes an**atom**(from a list) - (
`#:`) with**more than one**dot makes a**list**(from an atom).

Both these primitives work with arrays in place of single numbers

] y =: #: 9 5 1 0 0 1 0 1 0 1 #. y 9 5

Look what happens:
Antibase 2 (`#:`) converts integers to lists as follows

`9``-->`(`1 0 0 1`) – as we saw above`5``-->`(`1 0 1`) – as we saw above- (
`1 0 1`)`-->`(`0 1 0 1`) – an equivalent binary numeral.

The final step is needed to make a rectangular array out of the two ** items** which make up

`y`, viz. the

*binary representations*of 9 and 5

But notice something important:
Base 2 (`#.`) works in a rather different way to a monad such as ** Negate** (

`-`)

- (
`-`) gets applied to**individual numbers**of`y`, negating each number - (
`#.`) gets applied to**entire rows**of`y`, treating each row (=list) as a*binary representation*

- y _1 0 0 _1 0 _1 0 _1 #. y 9 5

How does J know that Negate (`-`) needs to be applied to individual numbers, but Base 2 (`#.`) needs to be applies to entire rows?

The answer lies in their *verb ranks* – which happen to be different.

## UNFINISHED

CategoryNuVoc CategoryWorkInProgress