Programming in J

I’ll discuss my progress with J. This page was last updated on April 20th, 2019.

If you want to learn J, you can use the tutorial and vocabulary overview on the official website, or just install and try things out in the J console. The Mandelbrot program below crashes in 807 but not in the 901 beta.

Introduction

Functions are referred to as “verbs” and they can be modified with “adverbs”. Verbs that take one argument are called monads and those that take two arguments dyads. One symbol can have several meanings depending on the context, for example monadic # counts a list, dyadic # creates copies of something. Parentheses are placed on the right, so 2*3 + 4 means 2*(3 + 4) which gives 14.

A list of Mersenne primes

I’ll explain the program (#~1&p:)<:2^p:i.10 which lists the first few Mersenne primes (prime numbers of the form 2p − 1, where p is prime).

i. 10
Gives the list 0 1 2 3 4 5 6 7 8 9.
p: 6
Gives the 7th prime, 17.
2 ^ 3
Gives 23=8.
<: 5
Gives 5−1=4. Similarly, there is >: which adds one instead.
1 4 0 7 0 0 3 # 6 7 8 9 10 11 12
Gives a list of copies 6 7 7 7 7 9 9 9 9 9 9 9 12 12 12. This also allows you to create a sublist by only using ones and zeros in the left argument.
3 4 5 #~ 1 0 1
Gives the sublist 3 5. (The adverb ~ switches the arguments.)
1 p: 8
Gives 1 or 0 depending on whether 8 is a prime number. The dyad p: is used for other number-theoretic functions, such as 5 p: 15 which gives the Euler totient function φ(15)=8.
1&p:
Turns the dyad p: into a monad by fixing the left argument 1.
(f g) y
When f is a dyad and g is a monad, it means y f (g y).
(#~1&p:)<:2^p:i.20x
3 7 31 127 8191 131071 524287 2147483647 230584300921369395. The x is for arbitrary-precision integers.

The Mandelbrot set

For a complex number c, let f(z) = z2 + c. If the list of numbers 0, f(0), f(f(0)), f(f(f(0))), … remains bounded, we say that c is in the Mandelbrot set, M. The following program creates a table of ones and zeros in the shape of M:

2<|>{:(([;(+*:))&>)/^:9(];])_2j2+90%~(0j_1&*+/])i.360

It creates a table of complex numbers, makes two copies, and then repeatedly squares the right table and adds the left table to it, component-wise. Then it takes the right table and compares the absolute value of its components to 2 to see if they have escaped.

5 ] 4
Gives 4, the value on the right. Similarly, 5 [ 4 gives 5. When used as a monad, both [ and ] are the identity function.
10 20 +/ 5 6 7
The adverb / creates a table by applying the preceding verb, in this case +, to each possible pair of inputs.
15 16 17
25 26 27
_5
The number −5.
3j4
The complex number 3+4i.
(f g h) y
When f and h are monads and g is a dyad, it means (f y) g (h y).
3 % 4
Division, so it's 0.75.
< 2 3 4
Packs its input in a box, 2 3 4, so it can be manipulated as a single thing. Boxes can be nested, and > unpacks a box.
3 ; 4
Packs both inputs in boxes and makes a list containing those boxes.
*:5
Squares its input, so 25 in this case.
(*: ^: 3) 5
The verb *: is applied three times, so we get 390625.
+/ 5 6 7
The adverb / inserts the preceding verb, in this case +, in between the values of the list. So we get 5+6+7 which is 18.
x (f & g) y
When f is a dyad and g is a monad, it means (g x) f (g y).
x (f g) y
When f is a dyad and g is a monad, it means x f (g y).
x (f g h) y
When f, g and h are all dyads, it means (x f y) g (x h y).
{:
Gives the last item from a list. Similarly, {. gives the first item.
| 5j_12
Gives the absolute value of the complex number 5 − 12i, so 13.
5 < 3
Gives 1 or 0 depending on whether it is true that 5 is less than 3.

If you install the package “graphics/viewmat” from the tools menu of the J console, you can create an image like so:

require 'viewmat'
viewmat 2<|>{:(([;(+*:))&>)/^:9(];])_2j2+90%~(0j_1&*+/])i.360

Monochrome rendering of M

The above program has a fixed number of iterations. The version below checks if the sequence has escaped after every iteration. The number of iterations then determines the color of the pixel.

require 'viewmat'
grid =: _2j2+90%~(0j_1&*+/])i.360
iterate =: $:@(>:@{.,1&{,(+*:)/@}.)^:(2&<@|@{:+:20&=@{.)
colormap =: (255+1184256&*)`(16752640&[)@.(14&<)`0:@.(20&=)"0
viewrgb colormap {. @ iterate @ (0:,],]) "0 grid
x =: 3
This defines a variable x and sets its value to 3.
f @ g
When f and g are monads, this creates a new monad, "f after g".
3 = 3
This gives 1 or 0 depending on whether 3 is equal to 3.
0 +: 0
Nor: gives 1 if and only if both inputs are zero.
p^:q y
The value of q y determines how many times the verb p is applied to y.
}. 4 5 6 7
Gives all but the first value, 5 6 7.
4,5
Creates a list 4 5.
1 4 { 6 7 8 9 10 11
Selects the 2nd and 5th values which are 7 and 10.
$:
This refers to the largest verb that contains it. In this case iterate. It can therefore be used for recursion.
f ` g
Creates a gerund, which is a kind of list of verbs.
(>: ` <: ` *: @. ]) 2
The verb to the right of @. determines which verb from the gerund is applied. Because ] 2 outputs 2, the verb *: is applied which gives 4.
0:
Always outputs 0. There are similar verbs from _9: up to 9:.
+/ "0 (4 5 6)
The "0 makes sure the verb is applied to each individual element (rank 0) instead of the list/table/… as a whole.

The tool viewrgb colores each pixel according to the number at the corresponding position in the table. The digits in base 256 represent the values for red/green/blue respectively.

Colored rendering of M