Doc/Articles/Play102

From J Wiki
Jump to navigation Jump to search

At Play With J ... Table of Contents ... Next Chapter

1. MIMD Machines

. By Eugene McDonnell. First published in Vector, 10, 2, (October 1993), 128-129.

I had a request recently from someone who wanted to apply a verb a different number of times to a list of arguments. What was wanted was a simpler way of writing:

     (f a),(f f b),(f f f c)

My initial response was to say that J did not as yet have a way of describing Multiple Instruction-Multiple Data machine architectures (MIMD), although such a mechanism had been described [1]. I pointed out that a collapsing transpose could solve the problem, but my questioner would have none of that, as it implied a great deal of useless computation. There the matter rested for a while. After several months I had another request from the same person who wanted to know if I had made any progress on the problem. Actually, I hadn’t thought about it at all in the interim, but since my questioner seemed to be a determined type, I gave it a few minutes more thought, and found what I think is a neat use of one of J’s more interesting differences from APL, the way scan is defined: that is, the verb applied is monadic, not dyadic. The symbol (\) that in APL is "scan" is, in J, "prefixes". For example, whereas in APL one writes +\1 2 3 to obtain the continued sum of the values in the argument, in J one would have to write +/\1 2 3 to obtain the same result.

     +\1 2 3
1 0 0
1 2 0
1 2 3

Here the monadic verb conjugate, denoted by +, is being applied, first to 1, next to 1 2, and last to 1 2 3; since these are real numbers, their conjugates are the same as the arguments, and since J reshapes results so that they conform, and then appends them, we get the zero fills at the right of the top two rows. Compare this with

     +/\1 2 3
1 3 6

which is the analog to APL’s +\1 2 3. Finally, here is the solution to the MIMD problem. First I define three variables, a, b, and c:

     'a b c'=: 3 4 5

Next, I define a verb f to be the natural logarithm (^.).

     f=: ^.

and apply it once, twice, and thrice, to a, b, and c, respectively:

     f a
1.09861
     f f b
0.326634
     f f f c
_0.742579

This is the desired result, but done the hard way. Now for the easy way: Define a verb g in which the verb f is applied (@) to the tail ({:) of its argument a number of times (^:) equal to the length (#) of its argument:

     g=: f@{:^:#

For example, g 3 1 4 1 5 9 applies f six times to 9:

     f f f f f f 9
0.854804j1.01575
     g 3 1 4 1 5 9
0.854804j1.01575

Perhaps you already see how this will end. We apply the prefix scan (\) adverb to g, and apply this derived verb to a,b,c:

     (g\)a,b,c  NB. apply g to successively longer prefixes
1.09861 0.326634 _0.742579
     NB. q.e.f.

Showing once again that where there’s a will there’s a way. Note that because of the way prefix scan is defined, it is easy to visualize how, in a multiprocessor environment, the applications of g to all three arguments can be carried out simultaneously.

Reference

[1] Bernecky, R., Hui, R. K. W., Gerunds and Representations. APL Quote Quad 21, 4, Stanford, Calif., (1991-08), 39-45.

Vector Vol.10 No. 2


This article has been updated to reflect the current version of J.


Endnotes by IanClark

Endnote[1]

Eugene prefers =. for in-session assignments whereas others might prefer: =:. On the conservative principle (after all, this is Eugene's book) I've let it stand in this paper.

However, this is debatable. On one or two instances we're going for enforcing a few (strictly limited) conventions uniformly throughout the book. For example, if Eugene writes:

 a=:12345
 a
12345

we're going to save a line by writing:

 ]a=:12345
12345

Maybe replacing =. with =: (where it's better style) should be one of these conventions?

  • In the early days of J the choice between =. or =: generally did not matter so much. However, since the introduction of the session manager it is better to use =: unless you are assigning local names in an explicit definition. The reason is that in a script names specified using =. became local to the session manager code. I suggest that in this round of editing all occurrences of =. , other than those used to define locals in explicit definitions, be changed to =: . -- Roger Hui <<DateTime(2009-03-28T13:35:33-0800)>>
  • I agree and I've made the changes to the above code. -- Ian Clark <<DateTime(2009-03-29T12:29:00-0000)>>

.

Endnote[2]

I notice that the Wiki uses a different fixed-font for in-line J code than it does for blocks of code. Why is this?

Endnote[3]

You'll all be aware that the novice reader (and the typesetter!) has a significant visual-cognitive task in discerning J code embedded in narrative. Probably most of the time spent on typesetting this book has been down to this problem in one form or another. APL (at least the original APL, with its characteristic slanting capitals for all variables) did not have this problem, and I rather wonder if it wasn't designed with that in mind. But others will know, not me, and I don't want to walk into a minefield. :-) Just to say I'm a little wary of RogerHui's proposal to follow in-line J at the end of a sentence with a narrative period (or colon) preceded by a nonbreaking space. This was what I first thought, but now I would rather omit the space, and indeed the book 1st edition does so throughout. (But I'm prepared to revise my view over this.)

IMO the effect in the Wiki is pleasing, because J Dot and narrative period look quite different and the narrative period comes up hard against the J phrase, which a final J Dot would not.

The effect in the book is less pleasing, because narrative period, set in Book Antiqua (the Vector house-standard), looks too much like J Dot. Likewise narrative colon and J colon. But again the period comes up hard against the J phrase and doesn't (really) look like part of the code.

Here are some examples from the narrative above:

Without nonbreaking space...

First I define three variables, a, b, and c:

For example, g 3 1 4 1 5 9 applies f six times to 9:

...which is the analog to APL’s +\1 2 3.

With nonbreaking space...

First I define three variables, a, b, and c :

For example, g 3 1 4 1 5 9 applies f six times to 9 :

...which is the analog to APL’s +\1 2 3 .

Which do people like best?

...Which gets us on to another problem: in-line APL. Since the Wiki seems to be using UTF-8, I propose to treat APL code like J code but with embedded APL chars coded in UTF-8. The article with the most APL code in it is 33 Pick A Card, Any Card -- and I'll port that to the Wiki to test my conjectures (and then remove my ownership so that someone knowledgeable can check out the J code).

Endnote[4]

I'm going for smartquotes in the narrative and will expunge dumbquotes throughout the book where these do not appear in code. (One of the trials of being a typesetter.) I'm tempted to say please make my job easier -- but whatever you do, it won't, because I'll have to check it anyway. (And... yes, I'm not using smartquotes in my own endnotes.)