From J Wiki
Jump to navigation Jump to search

Back to: Vocabulary

The Rank Of Verbs Generated By Modifiers

You can get confused when you start writing code that contains modifiers.

Suppose you have written a sentence to find the length of a vector using Pythagoras's Theorem.

ALGORITHM: square the operand (3 4), sum the resulting numbers, then take the square root of the result.

   %: +/ *: 3 4

Once you have written this sentence, suppose you want to make a verb out of it. If you write it explicitly

   length =: verb define
%: +/ *: y

   length 3 4

it seems to work well.

Soon you learn about tacit verb definition. Suppose you now want to write your verb: length tacitly. First you try

   length =: %: +/ *:

   length 3 4
10.7321 17.7321
     11      18

That's no good!

You later learn that you have mistakenly written a fork.

Finally you learn about  u@v which executes v followed by u. That sounds like what you want. So next you try

   length =: %: @ (+/) @ *:

   length 3 4
3 4

That's no good either!

But someone suggests a tiny change: use (@:) instead of (@)

   length =: %: @: (+/) @: *:

   length 3 4

Now it seems to work well.

What's the difference between (@:) and (@)? And why does it matter?

The difference lies in the ranks of the two different tacit verbs you wrote.

You can see the rank of any given verb by using adverb  b.0

   %: @ (+/) @ *:  b.0     NB. (ranks of) the wrong verb
0 0 0
   %: @: (+/) @: *:  b.0   NB. (ranks of) the right verb
_ _ _
  • The wrong verb has rank zero, which means that your verb gets applied to each number individually.
  • The right verb has rank infinity (_), meaning that your verb gets applied to the entire array, in one go.

If you had checked the rank of Atop (@) before you used it, the page would have told you that the rank of  u@v is the same as the monadic rank of v. Since the rank of Square (*:) is 0, you'd have realized that the only possible rank for  %: @ (+/) @ *: was 0.

With At (@:) on the other hand,  u@:v always has rank infinity (_), which means it always acts on the whole array at once. Which was what you wanted.

The difference is shown in the first two columns of the following diagram:


This diagram also shows Appose (&:) and Compose (&) for overall comparison between the four alternative conjunctions.