>>  <<  Ndx  Usr  Pri  JfC  LJ  Phr  Dic  Rel  Voc  !:  wd  Help  J for C Programmers

                                       14. Loopless Code III--Adverbs \ and \.

We have learned about ordinary verbs that operate on the cells of an operand, and we have learned u/ which operates between all the cells of its operand.  In between those extremes are verbs that operate on subsets of the cells of its operand.  In this chapter we will learn a couple of adverbs that apply verbs to subsets of cells chosen according to simple rules; in later chapters we will learn how to form irregular subsets.

u\ y has infinite rank and applies u to successive prefixes of .  It applies u to the first item of y (i. e. u 1 {. y) to produce the first item of the result; it then applies u to the first 2 items of y (i. e. u 2 {. y) to produce the second item of the result; and so on, with the last item of the result being u (#y) {. y .  Example:

   #\ 9 8 7 6

1 2 3 4

This just gives the length of each prefix, not a terribly edifying result.  The details can be seen using fndisplay:

   defverbs 'tally'

   tally\ 9 8 7 6

+-------+---------+-----------+-------------+

|tally 9|tally 9 8|tally 9 8 7|tally 9 8 7 6|

+-------+---------+-----------+-------------+

Note that u is always applied to lists, because {. always produces a list.  In particular, the first item of the result comes from applying u to a 1-item list; conversely, even if y is a scalar, (#y) {. y is a 1-item list.  Note also that if the applications of u produce results of different shapes, framing fills are added to bring the results to a common shape, just as if they were the results from applying a verb to different cells:

   ]\ i. 3

0 0 0

0 1 0

0 1 2

The result is the prefixes themselves, assembled as items of a rank-2 array.

u\ is most often used when u is of the form u/, i. e. as u/\ .  Then the verb u/ is applied to the successive prefixes.  Here are some commonly-used forms:

   +/\ i. 6

0 1 3 6 10 15

+/ means 'total the items', so +/\ i. 6 is (0),(0+1),(0+1+2),(0+1+2+3)..., i. e. the running total of the items of .

   >./\ 9 5 3 10 3 2 20

9 9 9 10 10 10 20

For each item of y, the result is the largest item occurring in the list up to that item of .

   </\ 0 0 0 0 1 1 0 0 1 0

0 0 0 0 1 0 0 0 0 0

</\ y on a Boolean list (i. e. one containing only 0 or 1) is a tricky way to turn off all 1s following the first.  See how it works: </ y will produce a result of 1 only in the case where the last item of y is 1 and the rest are 0, i. e. 0 < 0...0 < 1, so </\ y produces a 1 for that prefix and 0 for all the others.

   *./\ 1 1 1 1 0 0 1 1 1

1 1 1 1 0 0 0 0 0

Keep the leading 1s of y, but set the rest to .

u\. y is similar to u\ y, except that it applies u to suffixes of .  It applies u to all of y (i. e. u 0 }. y) to produce the first item of the result; it then applies u to all but the first item of y (i. e. u 1 }. y) to produce the second item of the result; and so on, with the last item of the result being u ((#y)-1) }. y (that is, u applied to the last item of y).  Example:

   +/\. i. 6

15 15 14 12 9 5

The running total now starts at the end and runs backward.  fndisplay shows the details, and points out a subtlety of u/\ :

   defverbs 'plus"0'

   plus/\. <"0 i. 4

+----------------------+---------------+--------+-+

|0 plus 1 plus 2 plus 3|1 plus 2 plus 3|2 plus 3|3|

+----------------------+---------------+--------+-+

Up till now we have applied unboxed inputs to verbs defined by defverbs and gotten useful results.  Why then must we box the atoms of i. 4 before giving them to plus/\.?  The reason is that the result of a verb defined by defverbs is boxed.  Normally it is joined in an array with other boxed outputs.  Here, the last result, the one containing just the cell 3, is not produced by plus; rather, since plus/ is applied to a 1-element list, the cell is the unmodified input cell.  If we had not boxed the atoms of i. 4 (i. e. if we had executed plus/\. i. 4), the unboxed 3 would be joined to the other boxed results, and that would have given us a domain error.  Whenever you use u/\ y or u/\. y you must make sure that the result of u has the same type (character, numeric, or boxed) as .

The dyadic form x u\ y has rank 0 _ and applies u to infixes of .  An infix is a sequence of adjacent items.  x gives the length of the infixes.  The first item of the result comes from the infix of length |x (that is, the absolute value of x) starting with the first item of y, and subsequent items of the result come from subsequent infixes.  If x is positive, successive infixes start at successive items of y (therefore, they overlap), and the last infix is the one that ends with the last item of y; if x is negative, infixes do not overlap: each one starts with the item following the last item of the previous infix, and the last infix may be shorter than |x .  Examples:

   _2 ]\ 100 2 110 6 120 8 130 3

100 2

110 6

120 8

130 3

This is a convenient way to reshape a list to have 2 items per row when you don't know how many rows there will be.

   2 -/\ 10 8 6 4 2

2 2 2 2

   2 -~/\ 10 8 6 4 2

_2 _2 _2 _2

Applying -/ between each pair of items (with adjacent pairs overlapping) takes the backward difference of each pair.  To take the forward difference, subtract the first from the second using -~/ .

   3 >./\ 1 2 3 8 2 3 1 5 4 3 12 3 2

3 8 8 8 3 5 5 5 12 12 12

This takes the maximum over a rolling window 3 items wide.

x u\. y is similar to x u\ y , but it operates on outfixes which contain all of y except for the corresponding infix.  Its uses are few.  One is to enumerate the faces of a simplex, each of which consists of all the vertices of the simplex with one vertex omitted.  To list the 4 faces of a simplex with 4 vertices, we could use

   1 ]\. 0 1 2 3

1 2 3

0 2 3

0 1 3

0 1 2

When There Are No Subsets

The interpreter treats empty operands with care, so that you don't have to worry about them as special cases.  If you simply must know the details, here they are:  If u\ or u\. is applied where there are no applicable subsets of y (either because y is empty or because it is too short to muster even a single infix), u is applied to a list of fills f and the result has 0 items, each with the shape and type of the result of u .  The items of f have the shape of items of y, and the length of f is 0 for monad u\ or u\., or the length of an infix or outfix for dyad u\ or u\. .  For example:

   $ 2 ]\ i. 1 3

0 2 3

We were looking for infixes of length 2; each one would have had shape 2 3, but with only one item in y we have insufficient data for an infix.  So, the interpreter creates a 2x3 array of fills and applies the verb ] to it; the verb returns shape 2 3 and the overall result is a list of 0 items with that shape.

   $ ]\ i. 0 2 3

0 0 2 3

The cells of y have shape 2 3 so we apply the verb ] to a list of 0 of them (i. e. with shape 0 2 3).  The result of ] has the same shape as the input, and the final result is a list of 0 items each with shape 0 2 3, i. e. with overall shape 0 0 2 3 .


>>  <<  Ndx  Usr  Pri  JfC  LJ  Phr  Dic  Rel  Voc  !:  wd  Help  J for C Programmers