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.
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.
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
0 1 2 3 4 5 6 7 8 9
.
p: 6
2 ^ 3
<: 5
>:
which adds one instead.
1 4 0 7 0 0 3 # 6 7 8 9 10 11 12
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
3 5
. (The adverb ~
switches the arguments.)
1 p: 8
p:
is used for other number-theoretic functions, such as 5 p: 15
which gives the Euler totient function φ(15)=8.
1&p:
p:
into a monad by fixing the left argument 1
.
(f g) y
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.
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
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
/
creates a table by applying the preceding verb, in this case +
, to each possible pair of inputs.
15 16 17 25 26 27
_5
3j4
(f g h) y
f
and h
are monads and g
is a dyad, it means (f y) g (h y)
.
3 % 4
0.75
.
< 2 3 4
2 3 4
, so it can be manipulated as a single thing. Boxes can be nested, and >
unpacks a box.
3 ; 4
*:5
25
in this case.
(*: ^: 3) 5
*:
is applied three times, so we get 390625
.
+/ 5 6 7
/
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
f
is a dyad and g
is a monad, it means (g x) f (g y)
.
x (f g) y
f
is a dyad and g
is a monad, it means x f (g y)
.
x (f g h) y
f
, g
and h
are all dyads, it means (x f y) g (x h y)
.
{:
{.
gives the first item.
| 5j_12
5 < 3
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
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
x
and sets its value to 3.
f @ g
f
and g
are monads, this creates a new monad, "f after g".
3 = 3
0 +: 0
p^:q y
q y
determines how many times the verb p
is applied to y
.
}. 4 5 6 7
5 6 7
.
4,5
4 5
.
1 4 { 6 7 8 9 10 11
$:
iterate
. It can therefore be used for recursion.
f ` g
(>: ` <: ` *: @. ]) 2
@.
determines which verb from the gerund is applied. Because ] 2
outputs 2, the verb *:
is applied which gives 4.
0:
_9:
up to 9:
.
+/ "0 (4 5 6)
"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.
Problem A from Nieuw Archief voor Wiskunde 2020–1 asks for which n the map from Z/nZ to itself given by k↦k(k+1)/2 is a permutation, and for those n what the sign of the permutation is.
C.!.2(0 1 3 2)
-:6
4 | 11
9 3 9 4 9 </. 5 6 7 8 9
<
is applied to each group. So we get 5 7 9 6 8
(</.~C.!.2@(|(-:*>:)@i.)"0)}.i.20
1 2 3 5 6 7 9 10 11 12 13 14 15 17 18 19 4 8 16
From a function such as f(x,y,z)=x/(y+z) we can make a new function f(x,y,z)+f(y,z,x)+f(z,x,y) which we’ll call the cyclic sum.
(+`-`^)/5 7 2 1 3 1
/
is applied to a gerund, it will cycle through its verbs when inserting, giving us 5 + (7 - (2 ^ (1 + (3 - 1)))) = 4.
'abc'
*:1 :'u@:u'3
1 :
denotes an adverb, whose definition is given in string form. In this case, we modified the squaring verb *:
so that it is applied twice, yielding (32)2 which is 81.
We will now confirm a certain positive integer solution to the equation x/(y+z) + y/(z+x) + z/(x+y) = 4.
f=:(%`+)/ cs=:1 :'+/@:(u"1)@:({~(|+/~@:i.)@:#)' x=:154476802108746166441951315019919837485664325669565431700026634898253202035277999x y=:36875131794129999827197811565225474825492979968971970996283137471637224634055579x z=:4373612677928697257861252602371390152816537558161613618621437993378423467772036x f cs x,y,z