                                   Chapter 5

                             USING J : INTRODUCTION


      Simple J questions
      Questions about J.
      J query
      Difference between "+ +" and "(+ +)" in J
      j parsing in 2.9
      J changes with 3.2
      More j questions
      script file in J
      a new dimension
      J bugs
      Simple question(s) based on Dickey's "What is J?"
      Grade Down Columns of An Array
      programming in J


*========================================
# Simple J questions

+------------------
| Emmett James McLean
| <1991Sep1.225152.22316@csus.edu>

These questions are probably answered in the book "Programming in J",
but I understand that it may be a while before I get my copy since
there is currently a mail strike in Canada.


If I type the following J command

        a=. 2 2 $ 1+i.4

        a
    1  2
    3  4

And,

    b =. 0.7  0.9  0.2 0.25

How do I get:

1:
    1  4
    3  8           (Multiply the 2nd column by 2)

2:
    1  4
    6  8       (Multiply the 2nd row by 2)

3:
    1  2  1  2
    3  4  3  4

4:
    1 16
    3  4       (Change element 2 to 16)

5:
    3  7       (Add across the columns)

6:
    0.7  0.9
    0.2  0.25  (Use the array of a to index into b)

Similiarly, if :

    a=. 2 2 2 $1+i. 8

    a
      1  2
      3  4

      5  6
      7  8

How do I get ?:

7:
      2  4  (Multiply the top item by 2)
      6  8

      5  6
      7  8

8:
      1  4  (Multiply the right column by 2 in both items)
      3  8

      5  12
      7  16

9:
      3 7 11 15  (Add across the columns)


+------------------
| L. J. Dickey
| <1991Sep9.194216.28439@watmath.waterloo.edu>

In article <1991Sep1.225152.22316@csus.edu> vpcsc4@sfsuvax1.sfsu.edu
        (Emmett James McLean) writes:
[edited. LJD ]
>These questions are probably answered in the book "Programming in J",
>but I understand that it may be a while before I get my copy since
>there is currently a mail strike in Canada.
>
>If I type the following J command
>       a=. 2 2 $ 1+i.4
>And,
>    b =. 0.7  0.9  0.2 0.25
>How do I get:
>
>1: (Multiply the 2nd column by 2)
>    1  4
>    3  8
>
>2: (Multiply the 2nd row by 2)
>    1  4
>    6  8
>
>3: [catenate two matrices]
>    1  2  1  2
>    3  4  3  4
>
>4: (Change element 2 to 16)
>    1 16
>    3  4
>
>5: (Add across the columns)
>    3  7
>
>6: (Use the array of a to index into b)
>    0.7  0.9
>    0.2  0.25
>
>Similiarly, if :
>    c=. 2 2 2 $1+i. 8
>How do I get ?:
>
>7: (Multiply the top item by 2)
>      2  4
>      6  8
>
>      5  6
>      7  8
>
>8: (Multiply the right column by 2 in both items)
>      1  4
>      3  8
>
>      5  12
>      7  16
>
>9: (Add across the columns)
>      3 7 11 15

Well, I shall venture out again.  Here are some answers that
work for me.

1: (Multiply the 2nd column by 2)
   a * 1 2

2: (Multiply the 2nd row by 2)
   a * "(1) 1 2
   a * "1 (1 2)

3: catenate two matrices
   a ,"1 a

4: [put a 16 in location 0 1 of a ]
   i =. < 0 1
   16 i } a

   16 (<0 1) } a

[[NB. sws.  Ammend has changed. this is now done via
   (16) 1}a
 ]]


5: (Add across the columns) 3 7
   +/ "1 a

6: (Use the array of a to index into b)
   ($a)$(,a-1){b

Similiarly, if:
   c=. 2 2 2 $1+i. 8

7: (Multiply the top item by 2)
   c * "(1 0) 2 2 $ 2 1 1 1
Here are other examples that shows which indices are important:
   d =. i. 2 3 4
   d * "(1 0) 2 3 $ 2 1 1 1 1 1
   d * "(1 0) 2 3 $ 2 (0) }, 2 3 $ 1
   d * "(1 0) 2 (0 0)}2 3 $ 1

8: (Multiply the right column by 2 in both items)
   c * "1 (1 2)
or
   c * "(1) 1 2

9: (Add across the columns) 3 7 11 15
   ,+/"1 c


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

L. J. Dickey posts a variety of answers for Emmett James McLean, but I
thought I'd add a few variants on some of these themes:

EJM:
< >If I type the following J command
< >     a=. 2 2 $ 1+i.4

note that this gives the same result:
   [    a =. 1 + i. 2 2
1 2
3 4

< >and    b =. 0.7  0.9  0.2 0.25

< >6: (Use the array of a to index into b)
< >    0.7  0.9
< >    0.2  0.25
While the suggested solution,
   ($a)$(,a-1){b
works, it doesn't have to be that complicated.  This works for me:
   (a-1){b
0.7  0.9
0.2 0.25

< >Similiarly, if :
< >    c=. 2 2 2 $1+i. 8
Note that   c =. 1 + i. 2 2 2   gives the same result


+------------------
| L. J. Dickey
| <1991Sep11.035847.19449@watmath.waterloo.edu>



The other day, in response to an article by vpcsc4@sfsuvax1.sfsu.edu
(Emmett James McLean), I wrote about the arrays a and c:
        a       =. 1+i. 2 2
        c       =. 1+i. 2 2 2
hui@yrloc.uucp (Roger Hui) has written to me and suggested
some improvements.

Question 2 of EJM's article askes how to multiply the 2nd
row by 2.  In my answer, I wrote that one could type:
   a * "(1) 1 2
This is wrong.  The expression
   a*"(_1) 1 2
gives the right answer.

In response to question 7, about how to multiply the top item
by two, I said that to multiply the top item of c by 2, one
could type
   c * "(1 0) 2 2 $ 2 1 1 1
This is correct.  However, the expression
   c*"(_1) 2 1
is simpler.

In response to question 8, about how to multiply the right
column by 2, I wrote that one could use:
   c * "1 (1 2)
This is correct.  However, the epression
may be replaced by a simpler one, namely
   c*1 2

Thanks to EJM for asking the questions in the first place, RR
(rockwell@socrates.umd.edu, Raul Rockwell) for suggesting simpler
expressions for a and c, and to RH for pointing out my error and
suggesting improvements.



*========================================
# Questions about J.

+------------------
| Rudi Rynders
| <15160009@hpdmd48.boi.hp.com> 8 Jan 91 22:57:42 GMT

OK, how DOES one catenate two m-rowed arrays in the "horizontal" direction in J?
A pretty basic question , I admit. But why is it so hard to find?

Anyone care to explain in detail the "OVER" and "BY" constructs?.


+------------------
| Sam Sirlin
| <1991Jan9.171347.19535@jato.jpl.nasa.gov>

In article <15160009@hpdmd48.boi.hp.com>, rrr@hpdmd48.boi.hp.com (Rudi Rynders)
writes:
]> OK, how DOES one catenate two m-rowed arrays in the "horizontal" direction in
J?
]> A pretty basic question , I admit. But why is it so hard to find?
]>
]> Anyone care to explain in detail the "OVER" and "BY" constructs?.
]>
]> Rudi Rynders  (rrr@ hpdmd48.boi.hp.com)

To catenate two arrays on their last axis, use under:

  a ,&.|: b

This takes the transpose to start, catenates, then transposes the result (I
think). It does seem to work at least for matrices. I suspect that with
dyadic transpose one could catenate about arbitrary axes, albeit rather
more cryptically than in traditional APL. And people used to say that APL was
a write only language! As to over and by, my list (2.7) doesn't have those
names, so I would have to consult other documentation. Did you send away to
J for this? At least it gives mathematical details, which means you can
eventually (using tests) figure them out. Consider it a puzzle.



I've not been able to find a way to do the equivalent of reassignment:

  A[I] .is X

in J. Is this really impossible? Doesn't this make it hard to do some things
that FORTRASH even does easily (such as setting up similar arrays)? Or
maybee I should compare to Matlab, the other ascii APL derivative.


+------------------
| Bob Bernecky
| <1991Jan10.174810.27410@yrloc.ipsa.reuter.COM>



to catenate along last axis in J, use the rank adverb:
   x,"1 y



*========================================
# J query

+------------------
| SOFPJF@VM.UOGUELPH.CA
| 26 Feb 91 13:35:20 AST

Other than "Null Reshape" (''$x), is there a way to 'scalarize' something?

[[NB. sws.  This doesn't work:

   x=. 1 1 1$5
   x
5
   $x
1 1 1
   $'' $x
1 1
]]


+------------------
| L.J.Dickey
| 26 Feb 91 14:06:02 EST

        From: SOFPJF@VM.UOGUELPH.CA
        Date:         Tue, 26 Feb 91 13:35:20 AST
        Subject:      J query

        Other than "Null Reshape" (''$x), is there a way to 'scalarize'
        something?

I think that there might be yet others, but here is one other way:

                0{,x

I was interested to note that if m is a matrix, say

        m =. 5 + i. 2 3

and one does a "0 select", without doing the ravel, they get the first row.
I was surprised when I did the Null Reshape on a matrix.



*========================================
# Difference between "+ +" and "(+ +)" in J

+------------------
| Dirk Talkenberger
| <hm331ta.689347944@duc220> 5 Nov 91 13:32:24 GMT


Hey!

I am playing with J/PC v3.2. While typing in all sorts of expressions,
I got these two pieces

        + + 2
2
        (+ +) 2
4

Can anyone tell me the difference and what purpose the second
construct is for?


Thank You for any explanations!


+------------------
| Sam Sirlin
| <1991Nov5.164940.28903@csi.jpl.nasa.gov>


In article <hm331ta.689347944@duc220>, hm331ta@uni-duisburg.de (Dirk
 Talkenberger) writes:
]> I am playing with J/PC v3.2. While typing in all sorts of expressions,
]> I got these two pieces
]>
]>      + + 2
]> 2
]>      (+ +) 2
]> 4

The first is conjugate conjugate 2, or just 2. The second is the new
(in J) hook idom. Hook is two verbs next to each other. Its dyadic
form is just what you would expect, but it also has a monadic form:

(g h) y <-> y g h y

rather than g h y. You also get different results using *, ^ etc.
instead of +. There's also fork, three verbs together...



*========================================
# j parsing in 2.9

+------------------
| Sam Sirlin
| <1991Mar13.185342.26366@jato.jpl.nasa.gov>

I noticed that the parser changed a bit. While (in <2.4) expressions
such as
   fn=. (a;b)::''
used to work, now this produces spelling errors and you must use
   fn=. (a;b) ::''
I think this is because ) changed due to line labels, so j looks for
): if there is no space. A small price to pay for line labels.

[[NB. sws.  This is now
   fn=. (a;b) :''
]]



*========================================
# J changes with 3.2

+------------------
| Sam Sirlin
| <1991Jul11.234121.1250@jato.jpl.nasa.gov>

I noticed some minor changes in my J 3.2 on a Sun Sparc:

   a=. 'text'
   a,''
text
   a=. a,: 'next '
   a
text
next
   a,''
domain error

The domain error didn't show up in 2.9. I haven't checked the pc version yet.
Why?

[[NB. sws.  This has been fixed]]

I also noticed that monadic ; changed. I must say I found the old version
very useful (added an extra 1 to the dimension of its argument), and had
to change it in lots of places in old code that I wrote.


+------------------
| Roger Hui
| <1991Jul13.155901.591@yrloc.ipsa.reuter.COM>

In article <1991Jul11.234121.1250@jato.jpl.nasa.gov> sam@kalessin.jpl.nasa.gov
 (Sam Sirlin) writes:

>    a
> text
> next
>    a,''
> domain error
>
> The domain error didn't show up in 2.9. I haven't checked the pc version yet.
> Why?

Sorry, this one is a bug (and had been fixed in the current version).
The last sentence should have resulted in  3 5$'text next      '  rather
than signalling domain error.

> I also noticed that monadic ; changed. I must say I found the old version
> very useful (added an extra 1 to the dimension of its argument), and had
> to change it in lots of places in old code that I wrote.

Sam, I think you mean that the old monadic  ;  was Ravel Items.
The old spellings were:

, Ravel / Append        ,. Raze / -     ,: Itemize / Laminate
; Ravel Items / Link    ;. Cut          ;: Word Formation / -

A new verb, Append Items, has been added, and the dyad of  ,.  is a
sensible choice of notation for it.  We are then led to the current
spelling:

, Ravel / Append    ,. Ravel Items / Append Items    ,: Itemize / Laminate
; Raze / Link       ;. Cut                           ;: Word Formation / -

The defns of Ravel Items and Raze are unchanged; they have just been
respelled  ;  and  ,.  respectively.  We could have left their spellings
alone, but the current spelling has the advantage that:
(a) The  ,  words have a sense of "ravel" or "append".
(b) The  ;  words have a sense of "box" (anyway, Box with Cut is common).
(c) The monad of  ,.  is  (,"_1)@(,"_1)  and the dyad of  ,.  is  (,"_1) .
Moreover, for non-atomic arguments, the monad simplifies to  (,"_1) ;
that is, for non-atomic arguments  ,.  is  (,"_1)  for both the monadic
and dyadic cases.

(Be warned that in Version 3.2, the dyad of  ,.  is Append List  ,"1  .
This has since been changed to Append Item  ,"_1  .)

Spelling changes are disruptive and embarrassing, and we don't
make them unless there are compelling reasons.  I have reviewed
the spelling changes since August 1990, when J first became
publicly available.  They are:

  Dot Product    Ravel Items        Left
  Defn           Raze               Right
  Custom         Cycles             Gerund
  Cut            Atomic Permute     Evoke Gerund

The changes involve new facilities (Custom, Cut, Ravel Items,
Raze, Cycles, Atomic Permute, Gerund, Evoke Gerund); or less
well-understood aspects of the new dot-colon spelling (we thought
..  and  :  by themselves were not usable); or "what were we
thinking of" (Left and Right).  The factors driving spelling
changes seem likely to decline in importance with time.



*========================================
# More j questions

+------------------
| Mark Keil
| <1991Oct1.050328.28234@apollo.hp.com>


Why j? why not g or s as the name of the language?
Are all the previous letters taken for other languages,
or does it have some mystic significance?

Is j polymorphic? Does it allow operator overloading?
(yes, I know that one can create new verbs, though I
don't yet understand the details)

What is the value of having the =: copula create an uneraseable name?
What does "global" really mean for =: ?

In the dictionary, its hard to tell what a "." at the end of a sentence
means. Is it really the end of a sentence, or is the "." attached to
the character ahead of it as part of a verb or noun or whatever.
In u/. [oblique] , that section ends with ",.y." . does one read this
as ,.y period, or as ,.y. [implicit end of sentence] ?

Why do 0: and 1: have ranks of (_ _ _) [or is it (_ __)] ?

I take it that only 0 origin indexing is allowed in j. Is this true?

Thanks,


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

[Note: please take my postings with a grain of salt or two.

 For example, in a recent posting, it was asked if J allowed a set of
 functions to have "private data".  My answer ignored that it is
 fairly easy to have both local functions and local data which are not
 visible to the outside world.  It's true that they would not persist
 past the termination of their parent function if no arrangements are
 made for some sort of external reference.  However, it is relatively
 straight-forward to make such arrangements with the LinkJ package...
  -- Raul]

Mark Keil:
   Why j? why not g or s as the name of the language?
   Are all the previous letters taken for other languages,
   or does it have some mystic significance?

Well, this is mostly a stylistic issue.  However, as I understand it,
a one letter name is used because it conveys the terseness of the
language, and J is used at least partially because of the support for
complex math....

[[NB. apd. Roger Hui gave the name J because it is the easiest letter
      to type, lay your hands on the keyboard and see.
      Some notebook computers implement a trackball on the J key for
      the same reason.
]]
   Is j polymorphic? Does it allow operator overloading?  (yes, I know
   that one can create new verbs, though I don't yet understand the
   details)

Yes, and yes.  Though, you when you define or redefine an operator you
are responsible for providing the entirety of the definition if that
operator.  [It is easy, btw, to extract the current definition of an
operator, should you want to make tools for some sort of incremental
definition...]

   What is the value of having the =: copula create an uneraseable
   name?  What does "global" really mean for =: ?

The property of being unerasable is associated with a name, and is
independent of the choice of copula (though, obviously, a local
unerasable name [local "given name"] will only persist for the
duration of the parent).  Given names end with a ':', for example:
   ] x =: 1
1
   ] x =: 2
2
   ] x: =: 3
3
   ] x: =: 4
not reassignable
   x, x:
2 3

The difference between '=.' and '=:' is that '=.' always makes an
assignment in the local symbol table (in effect, localizing the
variable if no local definition exists), while '=:' always makes an
assignment in the global symbol table.  For example

  print =. 1!:2&2

  l1 =. 'x =. 1'
  l2 =. 'print x'
  l3 =. 'x =: 9'
  l4 =. 'print x'
  l5 =. ' ''x'':'''' 0'
  l5
 'x':'' 0

  (l1;l2;l3;l4;l5) : '' 0
1
1
9

Note that the global assignment of x did not alter the local value of
x.  [Also note that the 0s are dummy arguments to get a 'function' to
execute.]

   In the dictionary, its hard to tell what a "." at the end of a
   sentence means. Is it really the end of a sentence, or is the "."
   attached to the character ahead of it as part of a verb or noun or
   whatever.  In u/. [oblique] , that section ends with ",.y." . does
   one read this as ,.y period, or as ,.y. [implicit end of sentence]
   ?

Yes, this is a bit akward.  In my most recent copy of the dictionary
[if I could just find it], it looks like an attempt was made to use a
bold period for when it's part of J, and a non-bold period when it's
part of english -- unfortunately, there still isn't much to
distinguish the two.

On the other hand, in the definition of oblique, there is no other
reference to 'y.', while there are several references to 'y', so one
can safely assume that the intended symbol is 'y'.  Ultimately, I
think that you are supposed to resort to an executable copy of J to
provide examples and resolve this sort of ambiguity.

   Why do 0: and 1: have ranks of (_ _ _) [or is it (_ __)] ?

Because, given arbitrary arrays as results, they return 0 or 1.
Infinite rank (_ _ _) is just another way of saying this.

Note that while it is possible for one to take an infinite rank
function and specify that it applies to lesser arrays, it is a bit
more difficult to achieve that sort of generality by taking [for
example] a scalar function and specifying that it applies to greater
arrays.  [It would work, but the results are different.]

   I take it that only 0 origin indexing is allowed in j. Is this true?

No.  It is true that the primitives only support 0 origin indexing.
You can easily derive origin 1 indexing, should you desire that.

For example
   index=.  >:@i.
   select=. <: { ]
   iota 5
1 2 3 4 5

   2 3 index 'this';'is';'a';'test'
+--+-+
|is|a|
+--+-+

[[NB. sws.  he ment
   iota=.  >:@i.
   iota 5

   select=. (<:@[) {]
   2 3 select 'this';'is';'a';'test'
]]
Though I recommend you look up the symbols I've used if you have any
questions on this.


+------------------
| Richard S. Freedman
| <1990Nov29.032733.7810@nas.nasa.gov>

I am using J on a Vax with BSD unix. When I create an output "log" file
using the )script command this file is empty upon exiting J.  What is the
definition of the session "log" and what should be on this file ?



*========================================
# script file in J

+------------------
| Lee Dickey
| <1990Dec1.171214.10761@watdragon.waterloo.edu>

In article <1990Nov29.032733.7810@nas.nasa.gov> freedman@amelia
        (Richard S. Freedman) writes:

>I am using J on a Vax with BSD unix. When I create an output "log" file
>using the )script command this file is empty upon exiting J.  What is the
>definition of the session "log" and what should be on this file ?

The command

        )script - 'somefile'
[[
  NB. sws. this is now
  script=. 0!:2 &<
  'somefile' script ''
]]
is intended to create a file with the given name that contains a
transcript of all characters into and out of the interpreter.

There is a feature that distinguishes between input lines and output
lines.  It can be seen in this little example:

[[
kalessin{sam} > J
J 4.1   Copyright (c) 1990-1992, Iverson Software Inc.  All Rights Reserved.

   exit=. 0!:55
   script=. 0!:2 &<
   'temp' script ''
   i. 3 4
0 1  2  3
4 5  6  7
8 9 10 11
   script ''
   exit ''
kalessin{sam} > cat temp
   i. 3 4
0 1  2  3
4 5  6  7
8 9 10 11
   script ''
kalessin{sam} >
]]

Upon input, lines of files that begin with ^@ are not executed.
This allows you to re-execute the commands that you gave during
a session, without re-executing the output.

In the above example the line ")script -" seems to be necessary
to write and close the file.  However, I think it is intended
that the ")off" command do the same thing.



*========================================
# a new dimension

+------------------
| J Storrs Hall
| <Sep.20.02.36.50.1990.11172@planchet.rutgers.edu>

In J, function rank seems to be set to 0 when functions are
composed even though it was originally something else, e.g.

   (5&{.)&(5&*) i.10           gives the same result as
   (5&{.)"0 (5&*) i.10         and NOT the same as
   (5&{.) (5&*) i.10           as one would expect.

Is this a bug or a feature (or an implementation limitation)?

ps-- the third line is equivalent to 5{.5*i.10 giving 0 5 10 15 20
as expected, but the first two yield

0  0 0 0 0
5  0 0 0 0
10 0 0 0 0
15 0 0 0 0
20 0 0 0 0
25 0 0 0 0
30 0 0 0 0
35 0 0 0 0
40 0 0 0 0
45 0 0 0 0

[[NB. sws.  these now give the expected results
   (5&{.)&(5&*) i.10
0 5 10 15 20
   (5&{.)"0 (5&*) i.10
0  0 0 0 0
5  0 0 0 0
10 0 0 0 0
15 0 0 0 0
20 0 0 0 0
25 0 0 0 0
30 0 0 0 0
35 0 0 0 0
40 0 0 0 0
45 0 0 0 0
   (5&{.) (5&*) i.10
0 5 10 15 20
]]


+------------------
| Raul Rockwell
| <12060@chaph.usc.edu> 20 Sep 90 08:21:40 GMT

In article <Sep.20.02.36.50.1990.11172@planchet.rutgers.edu>
josh@planchet.rutgers.edu (J Storrs Hall) writes:

   In J, function rank seems to be set to 0 when functions are
   composed even though it was originally something else, e.g.

      (5&{.)&(5&*) i.10           gives the same result as
      (5&{.)"0 (5&*) i.10         and NOT the same as
      (5&{.) (5&*) i.10           as one would expect.

   Is this a bug or a feature (or an implementation limitation)?

It has to be a feature.

Composition produces a single function.  You're doing 5 take of the
result of 5 times.  Since times is a scalar function (rank 0 verb),
the composition is also rank 0.

+------------------
| J Storrs Hall
| <Sep.20.14.47.05.1990.1543@klaatu.rutgers.edu>

In article <12060@chaph.usc.edu>, news@usc.edu writes:
  ...
> It has to be a feature.

> Composition produces a single function.  You're doing 5 take of the
> result of 5 times.  Since times is a scalar function (rank 0 verb),
> the composition is also rank 0.

That can't be right.  The composition of two functions of different
rank should be the higher rank, because of the very problem I
mentioned originally.

Suppose you tried composing plus reduction and 5 plus.  5 plus
has rank 0, so by your logic the composition should have rank 0.
But this leaves plus reduction coerced to rank 0, rendering it
the identity function.  But on the other hand, it's quite easy
to have a function of *lower* rank operate within the context
of a higher rank, and you'd get the right answer.


ps: by "right answer" I just mean the definition, ie,

   f&g h   <==>   f g h



*========================================
# J bugs

+------------------
| Harald Brandt
| <1990Dec5.163512.20826@eua.ericsson.se>

This is a note on some bugs, or possible bugs, I have found in J. I figure it
might be valuable to report bugs found, so as to inform the designers of the
interpreter and other users. Some of these bugs may be known already, or may
not really be bugs but mere misunderstandings. First I thought of sending this
only to ljdickey, as you are a bit involved in J and may therefore perhaps
forward reports on bugs to ISI (or should I send a copy by surface mail to
ISI?). However, I decided to post this to the newsgroup so other people can
share experiences or inform me of better knowledge (at the risk you think I am
cluttering the newsgroup with junk of course). I use J version 2.8 on a
Macintosh II with a 13" color screen, System 6.0.5, 4 Mbyte RAM, J is set to 1
Mbyte.


1.  Infinity in the Power conjunction

I tried the expression on top of page 9 in the J Dictionary that comes with the
J package. It solves y = cos(y). The following is an excerpt from a dialog
(copied from the session, so I KNOW there are no retyping errors):

   2&o.^:_ (1)
ill-formed number
   2&o.^:99 (1)
0.739085
   2&o.^:_99 (1)
0.962266j1.11097

[[
NB. sws. this should work now:
    2&o.^:_ (1)
0.739085
   2&o.^:99 (1)
0.739085
   2&o.^:_99 (1)
0.962266j1.11097
]]

The first input should have worked, since the document 'status.doc' doesn't say
anything about limits on the the '^:' conjunction and the infinity symbol '_'.
The second input shows that the conjunction works fine with number 99, and the
third input shows that the character '_' is okey as a negative number. So
something is wrong with the very useful infinity (or asymptotic) case.!


2.  The Definition conjunction

I tried the code in the article of 20 Sept: <12061@chaph.usc.edu>
The function 'read' was defined as: 'read =. 1!:1' (reads characters from the
keyboard). The following is an ecerpt from my session:

    set =. (read 1 )::''
spelling error
   set =. (read 1 ) ::''
(y.,'=:y.') :: ''
   set 's'
syntax error
[[
   set=. (read 1):''
   set=. (read 1) : ''
       set 's'
domain error
]]

The first input shows that J refuses to accept a parenthesis immediately to the
left of '::' whereas J did in the article. The second input shows that J
accepts the sentence when I add a blank inbetween the parenthesis and the '::'.
Is this a bug, or is it intentional? I can not deduce from the parsing rules or
elsewhere in the J dictionary that there must be a blank there.

(Just today I read a posting by ljdickey that he experienced the same thing
with version 2.7 for Atari, but that does not explain why.)

The third input shows that the 'set' function doesn't work even though it
swollowed the definition of 'set'. For what reason I do not know. Is this a
bug, or is that nestling of definitions illegal?  (I.e is article
<12061@chaph.usc.edu> based on lies or an erronous interpreter?)


3.  The Merge adverb

Page 16 in the J Dictionary describes the merge adverb. Specifically the
following sentence there confuses me: "More generally, the shape of x may be a
suffix of the shape of j, and the result is a merge of ($j)$,x and y.". Either
I do not understand it, or it does not work as the definition says. The
following is an ecerpt from my session, where 'am' is a character matrix I
created for test purposes:

   am
asdfgh
jkloaz
xcvbnm
qwerty
uiopaa
   (2 2$'ASDF') (2 2&$0 2;4 4; 2 3;2 2)} am
asAfgh
jkloaz
xcFDnm
qwerty
uiopSa
   (1 2$'ASDF') (2 2&$0 2;4 4; 2 3;2 2)} am
length error
   ('ASDF') (2 2&$0 2;4 4; 2 3;2 2)} am
length error
   (3 2$'ASDF') (2 2&$0 2;4 4; 2 3;2 2)} am
length error
   ('AS') (0 2;4 4; 2 3;2 2)} am
length error
   ('A') (2 2&$0 2;4 4; 2 3;2 2)} am
asAfgh
jkloaz
xcAAnm
qwerty
uiopAa
[[
NB. sws. merge is now called ammend, with a new definition.
NB. the above don't work:
   (2 2$'ASDF') (2 2&$0 2;4 4; 2 3;2 2)} am


domain error
   (1 2$'ASDF') (2 2&$0 2;4 4; 2 3;2 2)} am
domain error
   ('ASDF') (2 2&$0 2;4 4; 2 3;2 2)} am
domain error
   (3 2$'ASDF') (2 2&$0 2;4 4; 2 3;2 2)} am
domain error
   ('AS') (0 2;4 4; 2 3;2 2)} am
domain error
   ('A') (2 2&$0 2;4 4; 2 3;2 2)} am
domain error

NB. one way to use ammend is to define a mapping to the ravel of am:
   index=. ($@])#.[
NB. which allows the old behavior (without the annoying boxes)
   (2 2$'ASDF') ((2 2 2$0 2 4 4 2 3 2 2) index am)}am
asAfgh
jkloaz
xcFDnm
qwerty
uiopSa
NB. the above can also be used as
   (2 2$'ASDF') ((2 2 2$0 2 4 4 2 3 2 2)&index @])}am
NB. which gives the same result. If you prefer boxes, you can use
   indexb=. [{i.@$@]
   (2 2$'ASDF') (2 2&$0 2;4 4; 2 3;2 2)&indexb@]} am
NB. also the same.
   (1 2$'ASDF') ((2 2 2$0 2 4 4 2 3 2 2)&index@])}am
length error
   'A' ((2 2 2$0 2 4 4 2 3 2 2)index am)}am
asAfgh
jkloaz
xcAAnm
qwerty
uiopAa
 ]]

The first long input shows the normal behavior (although the 2 2$ seems
meaningless, it is in accordance with the definition). The next four inputs
yielding "length error" are various tests that I would have expected to work
according to the definition (or what else does "suffix" mean?). The last one is
the only that works, but that is only because it is an atom left argument. What
is actually meant or intended?


4.  Stiff Window

The J-window I get (console) has no scroll-bars and cannot be increased in
size, but when clicking and dragging at the bottom right corner (where resizing
normally is done) dotted lines of imaginary scroll-bars show up, so the Mac
obviously expects the window to be of the standard resizable scrollable type.

This, however may not be a real bug, but I find it hard to believe that a
programmmer does not make use of the standard scrollable window that comes
almost effortless for free in a Macintosh! That is why I suspect it is a bug
(or a bit too lazy implementation).

[[NB. sws. I can't check this as I don't have a mac]]

Regards



*========================================
# Simple question(s) based on Dickey's "What is J?"

+------------------
| Peter S. Shenkin
| <1991Dec28.003048.22514@ctr.columbia.edu>


I've been going through Dickey's "What is J?" introduction, and I have
what I think is a simple question.

Example 1. consists basically of the following session:
    a =. i. 9
    +/ % ! a
 2.71828

However, the above is very different from:
    a =. i. 9
    foo =. +/ % !
    foo a
 36 36 18 6 1.5 0.3 0.05 0.00714286 0.000892857

That is, when foo is defined, it results in the hook (+/ % !), rather than
in the simple sequence (if that's the word I want) of +/ % ! .

So my question is:  suppose I did want to define a verb equivalent to the
sequence +/ % ! .  How would I do it?

Second, what is the logical reason that j chooses to make verb definition
act this way?  Dickey's Example 2. seems to indicate that this behavior
is general.  Why doesn't j require me to set up the definition in the following
manner, if what I want is the hook?
    foo =. (+/ % !)

If possible, I would appreciate an appropriate reference to "Programming in J"
and/or "Tangible Math", in addition to a "user-friendly" answer;  I am still
trying to bootstrap my way to being able to read the documentation.

Thanks,


+------------------
| Eythan Weg
| <WEG.91Dec28130003@mace.cc.purdue.edu>

In article <1991Dec28.003048.22514@ctr.columbia.edu>
 shenkin@avogadro.barnard.columbia.edu (Peter S. Shenkin) writes:


   I've been going though Dickey's "What is J?" introduction, and I have
   what I think is a simple question.

   Example 1. consists basically of the following session:
       a =. i. 9
       +/ % ! a
    2.71828

   However, the above is very different from:
       a =. i. 9
       foo =. +/ % !
       foo a
    36 36 18 6 1.5 0.3 0.05 0.00714286 0.000892857

   That is, when foo is defined, it results in the hook (+/ % !), rather than
   in the simple sequence (if that's the word I want) of +/ % ! .

   So my question is:  suppose I did want to define a verb equivalent to the
   sequence +/ % ! .  How would I do it?

The first case matches the first line of the parsing table of the
dictionary and the second matches the fourth and sixth lines.  You may
want to consider e=.+/&%&!  The semantics of e is detremined by line 5
applied repeatedly, line 4, and then line 12.  The expression e i.9
uses the first line.  All lines refer to the parsing table.

   Second, what is the logical reason that j chooses to make verb definition
   act this way?

I don't know.  I think it is part of a whole, which works fairly well.

                Dickey's Example 2. seems to indicate that this behavior
   is general.  Why doesn't j require me to set up the definition in
   the following manner, if what I want is the hook?
       foo =. (+/ % !)

Because it is redundant.

   If possible, I would appreciate an appropriate reference to "Programming in
 J"
   and/or "Tangible Math", in addition to a "user-friendly" answer;  I am still
   trying to bootstrap my way to being able to read the documentation.



Try maybe "Order of Execution" on page 9 of "Programming in J".



*========================================
# Grade Down Columns of An Array

+------------------
| Ann Simpson Chapin
| <33789@usc.edu> 21 Jun 91 03:57:51 GMT

Does anyone know how to grade down the columns of an array (rank 2) so that
each column of the array is graded down as if it is a separate vector?
I do not want to have to create an interative function, and I also do not
want to have to create separate vectors from each column, grade down each
vector, and then reconcatenate the vectors into the original array.

I have received several suggestions from various sources about creating
nested indicies into the array to solve the problem, but everyone I know
that has tried to solve this problem in a noniterative fashion has not
been able to.  If you can do this, please include the steps in your
response.  I am using APL Plus II on a 386 with plenty on memory and a
math coprocessor.....

Thanks,


+------------------
| L.J.Dickey
| <1991Jun21.060649.919@watmath.waterloo.edu>

In article <33789@usc.edu> ann@neuro.usc.edu (Ann Simpson Chapin) writes:
>Does anyone know how to grade down the columns of an array (rank 2) so that
>each column of the array is graded down as if it is a separate vector?

I have a solution to this problem.

>I do not want to have to create an interative function, and I also do not
>want to have to create separate vectors from each column, grade down each
>vector, and then reconcatenate the vectors into the original array.

Yeah, that would be a pain.

>I have received several suggestions from various sources about creating
>nested indicies into the array to solve the problem, but everyone I know
>that has tried to solve this problem in a noniterative fashion has not
>been able to.  If you can do this, please include the steps in your
>response.

Here are the steps in my solution, straight from a session script:

[[NB. sws.  you can replace NB: below by just NB. in current versions of J]]

   NB: =: '0 0$0' : 'x.'
   shape =. 4 5
   m =. (($?~)*/) shape       NB: 'Deal me a matrix.'
   m                          NB: 'What did I get?'
 6  7  1  2 18
13  4 15  3  0
16 19 12 17 14
 8 10 11  5  9
   r =. (\:"1)&.|:m           NB: 'Grade down each row under transpose.'
   c =. ($m)$i.}.$m           NB: 'Plain column selectors.'
   ( <"1 r,"_2 c ){m          NB: 'The desired result.'
16 19 15 17 18
13 10 12  5 14
 8  7 11  3  9
 6  4  1  2  0
   ( <"1 r,"_2 c )            NB: 'The indices.'
+---+---+---+---+---+
|2 0|2 1|1 2|2 3|0 4|
+---+---+---+---+---+
|1 0|3 1|2 2|3 3|2 4|
+---+---+---+---+---+
|3 0|0 1|3 2|1 3|3 4|
+---+---+---+---+---+
|0 0|1 1|0 2|0 3|1 4|
+---+---+---+---+---+

Comments:

The thing that makes this relatively easy in J is the way
the rank operator can be used to great advantage.
The first place this happens is in the expression
        \:"1
which means grade down each row.  I used this on each row of the
transpose, and then transposed the result back to get "r".
This was the most interesting part for me.

The second most interesting part was discovering how to
put the row indices and column indices together to generate
the subscripts used to select from the matrix.   For me, the
expression

   ( <"1 r,"_2 c )

was enlightening.

>           I am using APL Plus II on a 386 with plenty on memory and a
>math coprocessor.....
>
>Thanks, Ann

I am using J, Version 3.2 on my Atari Mega ST2.

Thank you, Ann, for posting such an interesting question.
I have learned a little more about J and the rank operator.


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

Ann Simpson Chapin:
   Does anyone know how to grade down the columns of an array (rank 2)
   so that each column of the array is graded down as if it is a
   separate vector?  I do not want to have to create an interactive
   function ..

   I am using APL Plus II on a 386 with plenty on memory and a math
   coprocessor.....

Well, if you were using J, I'd recommend something like
   \:~ "1  &.|: array

But since you're not, I'll try and describe a way to do this in
vanilla APL.  Basically, you coerce the array to a vector, sort the
vector in a way which preserves the original column order, then
reshape back to the original shape.

First off, you'll need the array in vector form.  You'll want all
members of a single column adjacent to each other, so you need to
transpose the array before you ravel it.  I'm going to give each
sentence twice -- once in psuedo-apl puns, and once in J.

   vec <- , (\) array
   vec =. , |:  array

Second off, you'll need to grade the array.  You want the grade to
preserve the original column ordering, so you need to normalize the
array, and add numbers to force the proper static ordering.

  normalized <- /|\  /|\ array
  normalized =. /:   /:  array

  colHorder <- - (R vec) x (R array)[0] / i (R array)[1]
  col_order =. - (# vec) * (0{$array)   # i. 1{$array

  grade <- \|/ colHorder + normalized
  grade =. \:  col_order + normalized

Finally, you need to restore the original shape of the array.  Note
that you need to do a transpose as well, which means that you need to
reshape using transposed dimensions.  (I'll just reverse the
dimensions here).

  sorted <- (\) ( (|) R array)R vec[grade]
  sorted =. |:  ( |.  $ array)$ grade{vec

voila.

As an aside, I haven't tested this code yet, but the basic concept is
sound.  I hope you can read it.  Also note that I've assumed origin 0
for the APL session -- I trust conversion to origin 1 is obvious, if
that is desired.

puns used here:
  <-   assignment
  (\)  transpose
  (|)  rotate
  R    rho
  H    delta
  x    times


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

Just a couple second thoughts on the sorting method I mentioned in my
last post.

First, one does not need to to transpose the array before ravelling
it.  Since the sort will totally reorder the array, and since the key
I provided results in a transposed array after sorting, the initial
transpose is redundant.  (Though it is probably useful conceptually).

Second, the normalization technique I used wouldn't work if you wanted
to maintain the relative positions of "identical" elements.  I think
this might be significant with floating point values, because of the
effects of comparison tolerance.

Also, I mistyped at least one bug into the code.

So, ammended code (same puns as before):

   vec <- , array
   vec =. , array

   normalized <- \|/ \|/ vec
   normalized =. \:  \:  vec

   colHorder <- - (R vec) x (R array)R i  (R array)[1]
   col_order =. - (# vec) * ($ array)$ i. 1{$ array

   grade <- \|/ colHorder + normalized
   grade =. \:  col_order + normalized

   sorted <- vec [  (\) ( (|) R array ) R grade ]
   sorted =. vec {~  |: (  |. $ array ) $ grade


(the typo in my prior post, by the way, was where I used 'array'
rather than 'vec' to compute 'normalized')

Finally note that my use of intermediate variables is purely
stylistic -- all of these values could be computed on the fly (though
there may be a significant cost associated with computing 'vec' on the
fly in some dialects of APL).


+------------------
| Robert Bernecky
| <1991Jun23.172018.4316@yrloc.ipsa.reuter.COM>

In article <33789@usc.edu> ann@neuro.usc.edu (Ann Simpson Chapin) writes:
>Does anyone know how to grade down the columns of an array (rank 2) so that
>each column of the array is graded down as if it is a separate vector?
>I do not want to have to create an interative function, and I also do not
>want to have to create separate vectors from each column, grade down each
>vector, and then reconcatenate the vectors into the original array.

>response.  I am using APL Plus II on a 386 with plenty on memory and a
>math coprocessor.....

As pointed out by LJ DIckey, you can use function rank if using a modern
dialect of APL (J or SHARP APL/PC). Otherwise, you can try this approach,
which I used back in the dark ages on a card sorter, IF your data
is small numbers such as student test scores, etc.

Consider the array x to be numbers in the range from 0 to 100.
Add 1000 to column one, 2000 to column two, etc. In SHARP APL, this
would be x+rank 1 (1000 times iota negative one take rho x).

Now ravel and upgrade, than take the 1000 residue.

Basically, each set of numbers sorts within the x000'th column.


+------------------
| L.J.Dickey
| <1991Jun24.001559.27591@watmath.waterloo.edu>

In article <1991Jun21.060649.919@watmath.waterloo.edu> I wrote:
>In article <33789@usc.edu> ann@neuro.usc.edu (Ann Simpson Chapin) writes:
>>Does anyone know how to grade down the columns of an array (rank 2) so that
>>each column of the array is graded down as if it is a separate vector?
>
>I have a solution to this problem.
> ...

Well, I have thought a little more about this and have learned some more.

Earlier, I presented this:

   NB: =: '0 0$0' : 'x.'
   shape =. 4 5
   m =. (($?~)*/) shape       NB: 'Deal me a matrix.'
   m                          NB: 'What did I get?'
   r =. (\:"1)&.|:m           NB: 'Grade down each row under transpose.'
   c =. ($m)$i.}.$m           NB: 'Plain column selectors.'
   ( <"1 r,"_2 c ){m          NB: 'The desired result.'

Here, I will show another solution that I found, a solution that
is far superior, in my opinion:

   (\:"1 m) {"1 m

This can be presented as a tacit function

   sbr =. {"1 ~ \:"1
   sbr m

and of course, as a consequence, the expression

   sbr &. |: m

does the desired task.  Finally, as was gently pointed
out by two kind readers, the expression

   \:~ "1 m

simply sorts by rows. So,

   \:~ "1 &. |: m

sorts by columns.  I suppose that when all else fails, RYFM. (*)


Further comments:

My original solution seems quite silly to me now, because of the
complicated structure that I needed to build.  I have not found
a use for the indices yet.  I am afraid that it will be just an
amusing exercise.

As before, the rank operator plays an essential role in each
of the above solutions.  But in these two solutions above,
strong primitives are used (sort and grade down)

                                                Lee Dickey

(*) Reference: ``Computer Wimp'', by John Baer. Ten Speed Press,
Berkeley (1983), ISBN 0-89815-101-5, p. 204.



*========================================
# programming in J

+------------------
| Mark Keil
| <1991Sep18.055706.29046@apollo.hp.com>

Ok, I've gotten J from ISI (for the MAC), and I've looked through the
dictionary and tutorial, and tried some of the examples.
I've also just played with it some. It's interesting.

Now, I'd like to write some simple programs. But I'm a bit lost...
The dictionary doesn't address prose & style.
(And yes, I'll order programming in J [real soon now :-])

I liked APL, and I know how to program in it, and I'm looking for
how to do in J what I used to do in APL .

So, how do I

    branch? Is this possible?
    do conditionals

    What is the equivelent (if any) of )fns
                                       )vars
                                       )grp



    Is J a superset of APL?
    Can it read An APL workspace? And and run it?
    Is there a translators giude (APL -> J)

    Are the any workspaces for J that I can ftp?

    do nested arrays? (actually I never used them in APL, but I've heard about
                       them and figured that J must be able to do them? :-)

Other:

    Roger & Ken & CO. , May I suggest that you include a printable
    registration & order form on the distrubution media (all
    media, including ftp). It will make it easier for people to
    register and order.

Thanks,


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

Mark Keil:
       branch? Is this possible?

You can branch, $. =. (whatever), but this is also quite a bit more
powerful than branching, and it's faster if you precalculate how many
iterations you need (or which permutation of statements you're going
to execute, or whatever).

       do conditionals

J has lots of conditionals.

Let's see...

   f^:(boolean_scalar) x
is f x  if boolean_scalar is 1,
is   x  if boolean_scalar is 0

Actually, 'power' is quite a bit more powerful than that and may serve
to replace the loop you may have been trying to construct.

  f^:3 x
is f(f(f(x))), for example.  [And if you've got a well behaved
function, y =. f^:_1 x  means that x equals f y].

  f^:(i. 4) x
returns the entire history:  x  (f x)  (f f x)  (f f f x)

Another form of conditional is
choice [^:(boolean_scalar) default

Which returns default if the boolean is 0, and choice if it's one.

Another, more general form of conditional is indexing:

   >(boolean_scalar) { default ;< choice

The advantage of this one is that you can have more than two options.
For example:

   >(index_scalar) { choice0 ; choice1 ; choice2 ; choice3 ;< choice4

And then there's gerunds...  With gerunds, you can do things similar
to "switch" statements or "while" loops of other languages.  And more.

Here's an example of a switch ("Agenda") statement:

    function0 ` function1 @. (boolean_scalar_function) data

Here, the boolean function selects which of the two declared functions
get applied to the data.  For example, a mildly verbose way to find
absolute value might be

   - ` ] @. (0&<"0) _2 _1 0 1 2
2 1 0 1 2

   A slightly different form of this sort of conditional is
   (index) f0 ` f1 `: 5  data

Here, the index selects which function to apply to the data.  Normal
rules for scalar extention between index and data if you've declared
the derived function to have some non-infinite rank.

       What is the equivelent (if any) of )fns
                                          )vars
                                          )grp

Well, since you can load from multiple workspaces at the same time
(with the same function) there isn't much need for APL's rather
inflexible groups.  But ')fns' and ')vars' can be determined using
   nl =. 4!:1
nl 3  lists the fns, and nl 2 lists the vars.

       Is J a superset of APL?

There is a a lot in the intersection of J and APL.  It's probably
easier to define in J things which are present in APL that were left
out of J than it is to define in APL things which are new to J.

       Can it read An APL workspace? And and run it?

Well... ask again next year.

       Is there a translators guide (APL -> J)

Not that I know of.  (I presume you mean a cross reference chart,
holding entries like

    APL             J

X reshape Y      x $, y
etc.

       [can J] do nested arrays? (actually I never used them in APL,
       but I've heard about them and figured that J must be able to do
       them? :-)

Yes, I used nested arrays several times in this post.  Though again
you can do things with J's nested arrays that are difficult to do with
APL's nested arrays.



 