                                   Chapter 7

                           USING J : FLOW STRUCTURES


      Do I really need a loop?
      Do While in J?


*========================================
# Do I really need a loop?

+------------------
| Kingsley Morse
| <15160016@hpdmd48.boi.hp.com> 9 May 91

Does anyone know how to do this other than writing a loop? Given a matrix

                  M     =     1 2 3
                              4 5 6
and a vector
                  V     =     7 8

I'd like to multiply 1 2 3 by 7, and multiply 4 5 6 by 8. In other words:

                  1 2 3  x  7
                  4 5 6     8

The result will be

                  7  14 21
                  32 40 48

Instead of writing a loop to do this, does APL have a more concise way?


+------------------
| Rudi Rynders
| <15160018@hpdmd48.boi.hp.com> 9 May 91 14:05:03 GMT

I would convert the vector V = 7 8 to a matrix the same size as M and
fill it with a row of sevens and eigths as in VM assign 2 3 rho 7 7 7 8 8 8
and then multiply M by VM to get the desired answer.


+------------------
| L.J.Dickey
| <1991May15.120900.15736@watmath.waterloo.edu>

In article <15160018@hpdmd48.boi.hp.com> rrr@hpdmd48.boi.hp.com (Rudi Rynders)
writes:
..
>I would convert the vector V = 7 8 to a matrix the same size as M and
>fill it with a row of sevens and eigths as in VM assign 2 3 rho 7 7 7 8 8 8
>and then multiply M by VM to get the desired answer.

And, If you choose to use J, you could write

               M * |: (|. $ M) $ V

or in APL, you could do the same thing because

               |: (|. $ M) $ V
is
                transpose ( reverse rho M) reshape V


+------------------
| Roger Hui
| <1991May15.134305.10894@yrloc.ipsa.reuter.COM>

Rudi Rynders) writes:


> Sorry for the spurious previous responses, I flubbed with my editor.
> I would convert the vector V = 7 8 to a matrix the same size as M and
> fill it with a row of sevens and eigths as in VM assign 2 3 rho 7 7 7 8 8 8
> and then multiply M by VM to get the desired answer.

Alternatively, in J, one could write  M *"1 0 V  .  The rank conjunction
(") modifies times (*) to work on rank 1 objects on the left and rank 0
objects on the right; that is, multiply vectors of M by scalars of V.

Alternatively, one could write  M *"_1 V  ; that is, multiply items of M
by items of V.


+------------------
| Eythan Weg
| <WEG.91May15133638@convx1.convx1.ccit.arizona.edu>

In article <1991May15.120900.15736@watmath.waterloo.edu> ljdickey@watmath.waterloo.edu (L.J.Dickey) writes:

   In article <15160018@hpdmd48.boi.hp.com> rrr@hpdmd48.boi.hp.com (Rudi Rynders) writes:
   ...
   >I would convert the vector V = 7 8 to a matrix the same size as M and
   >fill it with a row of sevens and eigths as in VM assign 2 3 rho 7 7 7 8 8 8
   >and then multiply M by VM to get the desired answer.

   And, If you choose to use J, you could write

          M * |: (|. $ M) $ V

In J I would write M*"1 0 V.

+------------------
| Pat Monardo
| <1991May17.031707.27992@cshl.org>

In article <1991May15.134305.10894@yrloc.ipsa.reuter.COM> hui@yrloc.ipsa.reuter.COM (Roger Hui) writes:
>
>Alternatively, in J, one could write  M *"1 0 V  .  The rank conjunction
>(") modifies times (*) to work on rank 1 objects on the left and rank 0
>objects on the right; that is, multiply vectors of M by scalars of V.
>
>Alternatively, one could write  M *"_1 V  ; that is, multiply items of M
>by items of V.

amen. and the absurdity of the previous posts should make them
reconsider whether the APL they speak has any value at all.

+------------------
| Raul Rockwell
| <ROCKWELL.91May17075620@socrates.umd.edu>

Pat Monardo:
   amen. and the absurdity of the previous posts should make them
   reconsider whether the APL they speak has any value at all.

ahem.

Much as I like J, I must point out that APL (and even that FORTRAN or
C language :-) does have some value.  Specifically, APL runs on my
machine, and the machine we use at work.  Also, APL runs quite fast
(at least the APL we use).

I expect that J will *eventually* run APL into the dirt, speedwise,
because J seems to be a simpler language, at heart.  (And because
there is some pretty good talent interested in making J available.)
However as things presently stand APL has quite a bit of value that J
lacks.  (And even when J stablizes and runs fast, there will be people
sticking with APL because that's what their applications run in -- and
that's nothing compared to people sticking to COBOL for the same
reasons).

In the words of the famous philosopher:  Lighten up, eh?  People were
having fun.


+------------------
| Pat Monardo
| <1991May17.182034.5515@cshl.org>

In article <9105171506.AA23991@ucbvax.Berkeley.EDU> liebtag@stlvm20.vnet.ibm.com ("David Liebtag") writes:
>Pat Monardo,
>
>   Any argument that concludes that ANY language has no value on the
>basis of how difficult it is to multiply the values in the rows
>of a matrix by the values in a vector is patently absurd.
>
true. i should have said has no value to me. i also believe
that the rank operator is a wonderful invention, up there in
the top ten computer inventions of all time.

+------------------
| Robert Bernecky
| <1991May17.215809.27935@yrloc.ipsa.reuter.COM>

In article <1991May17.031707.27992@cshl.org> monardo@cshl.org (Pat Monardo)
writes:
>In article <1991May15.134305.10894@yrloc.ipsa.reuter.COM> hui@yrloc.ipsa.
reuter.COM (Roger Hui) writes:
>>
>>Alternatively, in J, one could write  M *"1 0 V  .  The rank conjunction
>>(") modifies times (*) to work on rank 1 objects on the left and rank 0
>>objects on the right; that is, multiply vectors of M by scalars of V.
>>
>>Alternatively, one could write  M *"_1 V  ; that is, multiply items of M
>>by items of V.
>
>amen. and the absurdity of the previous posts should make them
>reconsider whether the APL they speak has any value at all.

Perhaps we should be a bit gentler, and just suggest that those APL dialects
of yore have failed to adopt general principles of extension, and have
added special cases for many primitives instead, following the lead
of the Fortran 90 designers...

I think the key to J and rank is that the SAME expression works for ANY
verb, whether primitive or user-defined. This is what sets it apart from
APL2 and other such dialects of APL. This makes the language easier to
learn and use than APL2, simpler to implement, and more general.

For example, I think one of the APL2 gurus suggested adding vectors to
matrix rows by doing (pardon me if I get this wrong, please) v+[1]m.

Swell. Now, replace the + with a user-defined function whose only contents
is +, and tell me why:  v foo[1] m doesn't work.


+------------------
| Greg P. Jaxon
| <1991May22.162856.18418@csrd.uiuc.edu>

rbe@yrloc.ipsa.reuter.COM (Robert Bernecky) writes:
>Perhaps we should be a bit gentler, and just suggest that those APL dialects
>of yore have failed to adopt general principles of extension, and have
>added special cases for many primitives instead, following the lead
>of the Fortran 90 designers...

I don't see any 'failure' in the quest for generality in 'APLs of yore'.
Neither do I see very many 'special case' inventions, although sometimes
in a complex web of design issues a general plan is only deliverable in
the form of special cases.  Axis brackets and index brackets turn out to
be clumsy syntax in a pure realm of applicative programming, and the rank
operator is an admirable invention.  Of course it can be adopted directly
into APL, but its usefulness as a language component comes partly from
how all its companion primitives are defined.  And so it lives most
comfortably in J.  APL could become J? -- No, the design of APL is
essentially complete, the design space split into the APL2 and Dictionary
variants, which explored DIFFERENT design goals, both succeeded at their
goals to the extent possible within the existing framework of APL.
Who was following Fortran 90, Bob? No one I was talking to!

APL users could become J users. -- Yup some will, maybe J will be so
good that most APLers will switch.  That's the way languages and marketplaces
evolve.

>I think the key to J and rank is that the SAME expression works for ANY
>verb, whether primitive or user-defined. This is what sets it apart from
>APL2 and other such dialects of APL. This makes the language easier to
>learn and use than APL2, simpler to implement, and more general.

>For example, I think one of the APL2 gurus suggested adding vectors to
>matrix rows by doing (pardon me if I get this wrong, please) v+[1]m.

>Swell. Now, replace the + with a user-defined function whose only contents
>is +, and tell me why:  v foo[1] m doesn't work.

The early APL2 prototype defined an axis operator that used the syntax
you suggest, and I believe supplied the definition you expect.  APL2 was
most relentless in introducing the 'principle of substitutability' into
the APL language design, so your point has not been lost.  I don't think
that SUBSTITUTABILITY between primitive things and user-defined things
is 'what sets J apart from APL2'.

I'd answer that APLB provides two ways for a user to write a 'function whose
only contents is +'. 1) $Z is A FOO B [1] Z is A + B$ and then inform
the interpreter that its 'rank is 0 0 0' by writing FOO" for +.  In
APLB,  V FOO"[1] M  <->  V+"[1]M  <->  V+[1]M.  2)  Pass + as an operand
to a user-defined operator $Z is V (FOO GOO) M.  When you say V +GOO M
FOO becomes +, and can be treated in the same way that + can.  So on
line [1] of this operator (or suspended inside it) you can utter the
magical incantation  V FOO[1] M and get the Middle Product feature
built into + to do your work.   The issues were not just syntax and
its extendability... (P.S. Dave Liebtag: Can APL2 do these two things?)

When I was at work on these things the language treated primitives
differently from user-defined things because it could know more
about the properties of the primitive's definition. It could know the
'rank' in the J sense.  It could know the 'identity function', and
whether the function was associative, commutative, etc.  Rather than
ignore these important properties when definining the operators, APL2
was willing to use them where they were available, and wait for a
language extension (like rank) that would help a user include these
properties when defining his/her own functions.

Axis is a syntactic lemon. It'll never make bordeaux wine, but it can
make lemonade!



*========================================
# Do While in J?

+------------------
| Michael J. A. Berry
| <MJAB.91Mar22144533@nanna.think.com>

The J status document for 2.9 lists various things with interesting names
which aren't in the J dictionary (at least not the version I have).  Have
people out there had any luck figuring out the following:

U .v    gerund
m :0    verb
m :1    do-while

[[NB. sws.  These have changed ]]


+------------------
| Raul Rockwell
| <23MAR91.00430776@uc780.umd.edu>

Well, since I've got J 3.0 with 2.9 docs, I suppose I can answer this
one...  (Note, this has been tested on sun4 J 2.9)

   nz =. ''::'x. }:^:(0=y.) y.'
   3 nz 4
4
   3 nz 2
2
   3 nz 0
3

   f =. 0: . , . nz . ({~) : 1
   data=. 1 0 0 _1 0 0 1 0 0 2 0 0 3
   data f 13 0
0 1 1 1 _1 _1 _1 1 1 1 2 2 2 3
   data f  (#data);i.0
1 1 1 _1 _1 _1 1 1 1 2 2 2 3

   f =. 2&= . , . nz . ({~) : 1
   data f (#data);i.0
1 1 1 _1 _1 _1 1 1 1

(I think, I didn't actually test this last variant, but it matches my
experience)

' given ':{       ger=.  w . g . m . s
                    f  =.  ger : 1
' then: ':{       x f n;<b
' step 0':{       r=.     c=.     b }:i=. _1
' step n':{       r=. r g c=. c m x s i=. i+1

----------------------------------------------------------------------

also,

2 3 5   + . - . * . % :0  4

+-----+-------+-------+-------------+
|6 7 8|_2 _1 1|8 12 20|0.5 0.75 1.25|
+-----+-------+-------+-------------+

(This one's from memory)
In other words,  you just box the results and stick them together.
Rank is supposed to be maxima of ranks of the argument functions (and
it doesn't have to be 4 functions for :0)

[[NB. sws. Here goes...

   nz =. '' : 'x. [^:(0~:y.) y.'
   3 nz 4
4
   3 nz 2
2
   3 nz 0
3

   NB. sws. This is the way do until may eventually work, but it isn't
   NB.      available now. I've used B. Bernecky's article in APL91

   f =. 0: ` , ` nz ` ({~) `:1

   data=. 1 0 0 _1 0 0 1 0 0 2 0 0 3
   data f 13 0
0 1 1 1 _1 _1 _1 1 1 1 2 2 2 3
   data f  (#data);i.0
1 1 1 _1 _1 _1 1 1 1 2 2 2 3

   f =. 2&= ` , ` nz ` ({~) `:1
   data f (#data);i.0
1 1 1 _1 _1 _1 1 1 1

(I think, I didn't actually test this last variant, but it matches my
experience)

' given ']       ger=.  u ` g ` m ` s
                    f  =.  ger ` : 1
' then this line ']       x f n;<b
' becomes:'
' step 0']       r=.c=. b [i=. _1
' step n']       r=. r g c=. c m x s i=. i+1
' until this is true']       r u c
----------------------------------------------------------------------

also,

NB. sws.  this works now

   2 3 5   + ` - ` * ` % `:0  (4)
6 _2  8  0.5
7 _1 12 0.75
9  1 20 1.25

]]

P.S. (3.0 question) does anyone know what transitive n. (moments) is
supposed to do?


+------------------
| Roger Hui
| <1991Mar26.053718.4160@yrloc.ipsa.reuter.COM>

A gerund is a verbal form that can be used as a noun, as "programming"
in "programming is an art".  Gerunds in J are arrays of atomic representations
of verbs, and can be manipulated like other nouns.  When recognized by adverbs
and conjunctions, gerunds give rise to many useful verbs, such as do-while,
if-then-else, case, and recursion.  (See Bernecky and Hui paper in APL91.)

The notation for gerunds has evolved since J 2.9.  In particular,
u`v (previously u .v) yields the atomic representations of u and v.

If g=.v0`v1`v2 ... , then g/x inserts v0, v1, v2 between the items of x,
repeating v0, v1, ... cyclically.  It is therefore a generalization of
the ordinary insert f/x (which inserts the single verb f).  For example,
+`*/}.,x,"0 y  evaluates polynomial y at x using Horner's rule.

If g=.p`b`c`r and f=.g\ , then f y is b y if p y is 0, and f y is y c f r y
otherwise.  Thus factorial can be define as  fac=.*`1:`*`<: .  From their
use in g\, the verbs p, b, c, and r may be remembered as follows:
  proposition  (*   signum in factorial example)
  basis        (1:  constant function 1)
  combine      (*   multiply)
  reduce       (<:  decrement)

Other verbs can be derived similarly, usually as g`:k for the conjunction
`: (previously spelt : ), but also as  g adv  for certain cases (as with \).


 