J for Newbies

by Martin Kreuzer

This is a small collection of remarks and observations to help one get started from scratch with J programming.

It was begun in early summer of 2009 with the intension of eventually (and hopefully) bridge the gap between a complete "dummy" state and being able to digest the vast mass of material made available by JSoftware, especially contained in their forums.

J – what is that..?

The J programming language has been developed in the early 1990s by Ken Iverson and Roger Hui and grew from APL (also by Dr Iverson) and other sources. While APL uses special characters, J requires only the basic ASCII character set.

Citing the JSoftware site: "J is a modern, high-level, general-purpose, high-performance programming language. …
J is particularly strong in the mathematical, statistical, and logical analysis of data. It is a powerful tool in building new and better solutions to old problems and even better at finding solutions where the problem is not already well understood."

Downloading J

Citing the JSoftware site: "The best way to get started with J is to install a system … Note that J systems can be installed and distributed for free." — For downloading the latest stable version, visit the JSoftware download page; there you'll find versions for different software/hardware platforms.

Installing J

Mac

[Am not (yet) familiar with that platform.]

Windows

Installation is straight-forward; run the downloaded executable (which comes in 32-bit or 64-bit flavour), answer a few questions on the way, and finally (manually) create desktop links to start menue entries for JWD and JConsole.

Linux

[As I am drawing from my own experience, a Linux newbie is assumed.]

Save the downloaded file (j602a_linux32.sh in my case) to some directory (e.g. home dir ~myself/jsoft/j/v6.02a/).
Then open a Root terminal; you need to visit that directory and make the downloaded file executable by
# cd ~myself/jsoft/j/v6.02a/
# ls -al
# chmod +x j*.sh
Call for a directory listing a second time
# ls -al
to check that the file attributes have indeed changed as intended:
-rwxr-xr-x 1 myself myself 4226887 2009-06-01 10:41 j602a_linux32.sh
Then run the script by entering [this is a Debian system]
# ./j*.sh
System should answer with something like
Run with parameter: -install
 for a standard install of j602 in your home folder.
Run with parameter: -install your_path
 to install j602 in the folder of your choice.
Let's install (for the sake of it) to dir /opt:
# ./j*.sh -install /opt
If the install process ends without error, system responds with
Run Jwd with command: /opt/j602/bin/jwd
Run JConsole with command: /opt/j602/bin/jconsole
Jwd problems and info: /opt/j602/help.htm

To be able to start JConsole from any place, you will want to change to a directory which is in the PATH and create a symbolic link (e.g. jc) pointing to the executable:
# cd /usr/bin/
# ln -s /opt/j602/bin/jconsole jc

JWD needs Java to run. You probably need to modify the shell script jwd. Open it in a simple text editor
# cd /opt/j602/bin/
# nano jwd
and replace the line
java -Xss8000000 -jar bin/j.jar "s@"
with one containing the full path to Java RE on your system; in my case it was changed to
/usr/share/java/jre1.6.0_13/bin/java -Xss8000000 -jar bin/j.jar "s@"
[Might be a clumsy solution, but it works.]

To easily raise JWD you could create a launcher on your desktop, containing the command sh /opt/j602/bin/jwd.
Suitable icons can be found under /j602/bin/icons.

Running JConsole under Linux

Most of what is decribed here is also valid when using JConsole on a Windows platform (running it in a Virtual DOS window) or using the (Java based) GUI pendant JWD.

Entry and Exit

Now you're all set. Let's get acquainted with JConsole. To start it in a terminal window type
$ jc

The cursor has moved to the right;
   _
that's where you enter J commands.

The results will be printed right away (starting at the left screen edge),
   'Hello, world!'
Hello, world!
as J is an interpreted language, which means you are not bothered with compiling and linking.

If you have seen enough, simply issue this command
   exit ''
$ _
to leave JConsole at any time returning to previous shell level. (Yes, the command needs a parameter; in this case we used an empty string.)

First experiments

The command i. is called "Index generator"; this will generate the first dozen integers:
   i.12
0 1 2 3 4 5 6 7 8 9 10 11

The above command can easily be modified for e.g. covering the interval [−6..+6]:
   _6 + i.13
_6 _5 _4 _3 _2 _1 0 1 2 3 4 5 6
Note that negative integers appear with a leading underscore. Covering [3..4] and stepping in quarter units is achieved by
   3 + 0.25 * i.5
3 3.25 3.5 3.75 4

If you like the row of integers to start with 1, put >: ("Increment") in front:
   >: i.12
1 2 3 4 5 6 7 8 9 10 11 12

Use |. ("Reverse") or a negative argument to have them print in descending order:
   |. >: i.12
12 11 10 9 8 7 6 5 4 3 2 1
   >: i._12
12 11 10 9 8 7 6 5 4 3 2 1

Simple calculations

Not doing the system much justice, one may use the console as a simple calculator. It helps to get acquainted with J notation, though.
   14 + 2 * 3
20
is probably what you expected.
Now consider this:
   3 * 4 - 1 
9
To keep things simple, there's no operator precedence in J. That means 3 gets multiplied with the remainder of the expression i.e. 4 - 1. To get what you possibly wanted you have to modify the above to read
   (3 * 4) - 1 
11

As the slash / is used for very different stuff, the percentage sign % is used as division operator:
   12 % 3 - 1
6
(One gets used to it – promised.)

We can do squares by using *:
   *: i.6
0 1 4 9 16 25
or square roots %: (and, at the same time, apply some formatting):
   6j2": %: 1 + i.6
  1.00 1.41 1.73 2.00 2.24 2.45
The term ": means "Format …", and (what would be a complex number in a different context) 6j2 "… with a field width of 6, showing 2 decimal places".

We can do cubes (have a look what happens if you omit the parentheses)
   (i.6)^3
0 1 8 27 64 125
or powers of base 3
   3^i.6
1 3 9 27 81 243
or powers of stranger bases
   ^i.6
1 2.71828 7.38906 20.0855 54.5982 148.413
(From the second item returned you might have guessed that these are the first powers of Euler's number e = 2.71... .)
You may by now have also noticed that you can use the command line history as usual. (In JWD you'd use [Ctrl_Shift] [Up] or [Down].)

Further reading

If you made it here, you will likely be able to catch on with the help of this excellent treatise:

[lant]  Linda Alvord / Norman Thomson:  "Easy J"  (2002-Oct)
This concise, non-exhaustive paper teaches the basics of the language (while offering a lot of examples) and properly introduces to the J language terminology.

Programming in J

A first J script

Consider this simple physics problem (this is also dealt with in lant, p. 8):
A body is falling straight down from a high bridge.
Question: What will be its speed toward the water surface after it travelled a distance of 1, 2, 3, ... , 12 meters..?
Solution: v = sqrt (2*g*s),
where v is the speed (m/s), g is the gravitational acceleration constant (9.81 m/s/s), s is the distance travelled (m).

Open a simple text editor, and save the file as e.g. ~myself/j/fall.j.
#!/usr/bin/jc

NB. Consider this simple physics problem:
NB. A body is falling straight down from a high bridge; 
NB. what will be its speed toward the water surface after 
NB. it travelled a distance of 1, 2, 3, ... , 12 meters..?
NB. Solution: v = sqrt (2*g*s), where 
NB. v is the speed (m/s), 
NB. g the gravitational acceleration constant (9.81 m/s/s), 
NB. s the distance travelled.

NB. set constants
g=:9.81
s=:>:i.12

NB. calculate speed 
v=:%:2*g*s

NB. format
sf=:5j0":s
vf=:5j1":v

NB. output formatted speed values
echo sf
echo vf

NB. leave
exit ''
The first line asks the shell to raise JConsole. (A similar line you will find e.g. in Perl or shell scripts.) All the lines starting with NB. [nb: from Latin "nota bene"] are J comments. We set some constants, calculate the speed from the distance, and output the formatted values.

Running the script (you will have to make it executable first) will produce
$ ./fall.j
    1    2    3    4    5    6    7    8    9   10   11   12
  4.4  6.3  7.7  8.9  9.9 10.8 11.7 12.5 13.3 14.0 14.7 15.3
$ _

Applying some small changes to the script, i.e. adding a table header, labelling the rows of numbers, adding a second speed row for convenience, using "Left" [ as statement separator and "Append" , for string concatenation
...

NB. calculate speed (m/s)
v=:%:2*g*s

NB. convert speed (mi/h)
NB. 3.28 ft/m | 5,280 ft/sm | 3,600 s/h
m2ft=:3.28 [ sm2ft=:5280 [ h2s=:3600
vc=:v*m2ft*h2s%sm2ft

NB. format
sf=:5j0":s
vf=:5j1":v
vcf=:5j0":vc

NB. print table header
echo '--- Falling Speed vs Distance travelled ---'

NB. output formatted speed values
echo 'Distance (m)',sf
echo ' Speed (m/s)  ',vf
echo 'Speed (mi/h)',vcf

NB. leave
exit ''
will yield a more readable result:
$ ./fall.j
--- Falling Speed vs Distance travelled ---
Distance (m)    1    2    3    4    5    6    7    8    9   10   11   12
 Speed (m/s)    4.4  6.3  7.7  8.9  9.9 10.8 11.7 12.5 13.3 14.0 14.7 15.3
Speed (mi/h)   10   14   17   20   22   24   26   28   30   31   33   34
$ _
(Notice the massive speed gain at motion start; passing the 10 meter mark, the body is already travelling at over 30 miles an hour.)

You might want to re-use those conversion constants; let's save them therefore in a separate file e.g. ~myself/j/prex.j:
NB. file "prex.j"
NB. Externally predefined stuff for use with J scripts

NB. Gravity
NB. Earth's mean gravitational acceleration constant g = 9.81 m/s/s
g=:9.81

NB. Length conversion
NB. meter -> feet | statute mile -> feet | nautical mile -> feet | nautical mile -> kilometers
NB.     3.28 ft/m |          5,280 ft/sm |           6,080 ft/nm |                 1.852 km/nm
m2ft=:3.28 [ sm2ft=:5280 [ nm2ft=:6080  [ nm2km=:1.852

NB. Time conversion
NB. hour -> seconds
NB.       3,600 s/h
h2s=:3600

An additional line at the beginning of our script fall.j loads the external file
#!/usr/bin/jc

NB. get predefined stuff
load './prex.j'
...

and we can thus use the conversion constants as before (without the need to have the definitions here).
...
NB. convert speed (mi/h)
vc=:v*m2ft*h2s%sm2ft
...

[To be continued …]