Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Rich H.J for C programmers.2006.pdf
Скачиваний:
18
Добавлен:
23.08.2013
Размер:
1.79 Mб
Скачать

#. a

31

42

The verb rank is 1 and the noun rank is 3, so we will be applying the verb to 1-cells. The frame f is 2 2

 

 

 

 

 

 

 

Think of the operand as a 2×2 array of

 

0 0 1 1

 

0 0 0 1

 

 

 

 

 

 

 

 

 

 

 

1-cells:

 

0 1 0 0

 

0 0 1 0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The verb is applied to each cell:

 

3

1

 

 

 

 

 

 

 

 

 

 

4

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Since each result is an atom, i. e. a 0-cell, the

 

 

 

 

3 1

result is a 2×2 array of 0-cells, i. e. an array of

 

 

 

 

 

 

 

 

4 2

shape 2 2

 

 

 

 

 

 

 

 

 

 

Figure 2. Execution of #. 2 2 4 $ 0 0 1 1 0 0 0 1 0 1 0 0 0 0 1 0

Controlling Verb Execution By Specifying a Rank

The implicit loops we have used so far are interesting, but they are not powerful enough for our mission of replacing all explicit loops. To understand the deficiency and its remedy, consider the new verb monad +/, which creates the total of the items of its operand (just think of it as 'monad SumItems'):

+/ 1 2 3

6

The result was 1 + 2 + 3, as expected.

0

1

i.

2 3

2

 

3

4

5

 

3

5

+/ i. 2 3

7

 

The result was 0 1 2 + 3 4 5, as expected (remember that the items are added, and the items of i. 2 3 are 1-cells). Adding together a pair of 1-cells adds the respective atoms, as we will soon learn.

This application of monad +/ to a rank-2 array corresponds to the C code fragment: for(j = 0;j<3;++j)sum[j] = 0;

for(i = 0;i<2;++i)

for(j = 0;j<3;++j)sum[j] += array[i][j];

Suppose we wanted to add up the items of each row, as in the C code fragment

36

for(i = 0;i<2;++i) { sum[i] = 0;

for(j = 0;j<3;++j)sum[i] += array[i][j];

}

to produce the result 3 12? How can we do it in J? What we have learned so far is not enough, but if we had a way to make monad +/ apply to 1-cells—if we could make monad +/ have rank 1—our problem would be solved: the implicit looping would cause each row to be summed and the results collected.

You will not be surprised to learn that J does indeed provide a way to apply monad +/ on 1-cells. That way is the rank conjunction " .

We will learn all about conjunctions later on—the syntax is a little different than for verbs—but for now, we'll try to understand this " . It's used like this:

u"n

to produce a new verb that is u applied to n-cells individually. This is a simple idea, but its ramifications spread wide. As a first example:

+/"1 i. 2 3 3 12

This is what we were looking for. It happened this way:

The verb rank is 1 and the noun rank is 2, so we will be applying the verb to 1-cells. The frame f is 2

 

 

 

 

 

 

 

Think of the operand as a list of 2 1-cells:

 

0 1 2

3 4 5

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The verb monad +/ is applied to each cell:

 

 

 

 

 

 

 

3

12

 

 

 

 

 

 

 

 

 

 

Since each result is an atom, i. e. a 0-cell, the

 

3 12

 

result is a list of 2 0-cells, i. e. an array of shape

 

 

2

 

 

 

 

 

 

Figure 3. Execution of +/"1 i. 2 3

 

 

 

 

 

Examples Of Verb Rank

Here are some more examples using a rank-3 array as data:

37

0

i.

2 3 4

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

+/"1 i. 2 3 4 6 22 38 54 70 86

The verb rank is 1 and the noun rank is 3, so we will be applying the verb to 1-cells. The frame f is 2 3

 

 

 

 

 

 

 

 

 

 

 

 

 

Think of the operand

 

 

 

0 1 2 3

 

4 5 6 7

 

8 9 10 11

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

as a 2×3 array of 1-cells:

 

 

12 13 14 15

16 17 18 19

 

20 21 22 23

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The verb monad +/ is

 

 

6

 

22

 

38

 

 

 

 

 

applied to each cell:

 

 

54

 

70

 

86

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Since each result is an

 

 

 

 

 

 

 

 

 

 

 

 

atom, i. e. a 0-cell, the

 

 

 

 

 

 

6 22 38

 

 

 

result is a 2×3 array of

 

 

 

 

 

 

54

70 86

 

 

0-cells, i. e. an array of

 

 

 

 

 

 

 

 

 

shape 2 3

 

 

 

 

 

 

 

 

 

 

 

Figure 4.

Execution of +/"1 i. 2 3 4

 

 

38

+/"2 i. 2 3 4 12 15 18 21 48 51 54 57

The verb rank is 2 and the noun rank is 3, so we will be applying the verb to 2-cells. The frame f is 2

Think of the operand

0 1 2 3

12 13 14 15

4 5 6 7

16 17 18 19

as a list of 2 2-cells:

8 9 10 11

20 21 22 23

 

The verb monad +/ is

applied to each cell. As

we have learned, this sums 12 15 18 21 48 51 54 57 the items, making each

result a rank-1 list

Since each result is a

 

 

 

rank-1 list, i. e. a 1-cell,

12

15 18

21

the result is a list of 2

48

51 54

57

1-cells, i. e. an array of

shape 2 4

 

 

 

Figure 5. Execution of +/"2 i. 2 3 4

+/"3 i. 2 3 4 12 14 16 18 20 22 24 26 28 30 32 34

The verb is applied to the single 3-cell. Its items, which are 2-cells, are added, leaving a single 2-cell as the result.

How about i."0 (2 2 2)—can you figure out what that will produce? (Notice I put parentheses around the numeric list 2 2 2 so that the rank 0 wouldn't be treated as part of the list)

39

The verb rank is 0 and the noun rank is 1, so we will be applying the verb to 0-cells. The frame f is 3

 

 

Think of the operand as a list of 3 0-cells

 

 

 

 

 

 

 

 

 

 

 

 

2

 

2

 

2

 

 

 

 

(i. e. atoms):

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The verb monad i. is applied to each cell:

 

 

 

 

 

 

 

 

 

 

 

 

0 1

 

 

0 1

0 1

 

 

 

 

 

 

 

 

 

 

 

 

 

Since each result is a list, i. e. a 1-cell, the

 

 

 

 

 

0 1

 

 

 

result is a list of 3 1-cells each with shape 2, i. e.

 

 

 

 

 

0 1

 

 

 

an array of shape 3 2

 

 

 

 

 

0 1

 

 

 

Figure 6. Execution of i."0 (2 2 2)

 

 

 

 

 

 

 

 

0

i."0 (2 2 2)

 

 

 

 

 

 

 

 

1

 

 

 

 

 

 

 

 

 

 

0

1

 

 

 

 

 

 

 

 

 

 

0

1

 

 

 

 

 

 

 

 

 

 

If you worked through that, it might have occurred to you that the shape of each result cell depended on the value of the operand cell, and that if those cells had not been identical, there would be some rough edges showing when it came time at the end to join the dissimilar result cells together. If so, full marks to you! That can indeed happen. If it does, then just before the cells are joined together to make the final result, the interpreter will bulk up the smaller results to bring them up to the shape of the largest. First, if the ranks of the results are not identical, each result will have leading axes of length 1 added as needed to bring all the results up to the same rank (e. g. if one result has shape 2 5 and another has shape 5, the second will be converted to shape 1 5, leaving the data unchanged). Then, if the lengths of the axes are not identical, the interpreter will extend each axis to the maximum length found at that axis in any result: this requires adding atoms, called fills, which are always 0 for numeric results and ' ' for literal results. Example:

i."0 (0 1 2 3)

0 0 0 NB. original result was empty list; 3 fills added 0 0 0 NB. original result was 0; 2 fills added

0 1 0 NB. original result was 0 1; 1 fill added

0 1 2 NB. this was the longest result, no fill added

fndisplay—A Utility for Understanding Evaluation

J contains a script that we will use to expose the workings of evaluation. You define verbs which, instead of operating on their operands, accumulate character strings indicating what operations were being performed. This gives you a way of seeing the operations at different cells rather than just the results.

Start by loading the script:

40