Decreasing sequences

It occurred to me that I could think of two ways to generate a decreasing sequence. The built-in i. will do this:

   i. _7
6 5 4 3 2 1 0

But I could see a way to do it with self-reference $: or with iterate ^::

   (<:^:*^:a:) 7
7 6 5 4 3 2 1 0

This essentially says “iterate gathering results” ^:a: “while non-zero” ^:* “decrement” <:. This differs slightly from i. _7 because it includes the number 7, but whatever.

The self-reference $: method is a little longer:

   0:`(, $:@<:) @.* 7
7 6 5 4 3 2 1 0

Like any recursive function, we need a base case and an inductive case. Sentences like


in J give you case analysis, so a sentence like:

0:`f @.*

is a strong clue that your base case maps 0 to 0 and runs all positive numbers through f, and that’s what’s happening here. So the next step is understanding , $:@<:. This is about as simple as self-reference can get: we’re making a hook (it means the same as ] , $:@<: if forks make more sense to you than hooks) basically using , to append the current value with the result of the recursive call. $:@<: says “apply myself after decrementing the argument”.

This suggests an obvious way to get the increasing list, by just flipping around the arguments to , append:

   0:`($:@<: , ]) @.* 7
0 1 2 3 4 5 6 7

I’m sure the self-reference version is worse in performance terms, but there isn’t as straightforward a way to flip it around like this, so this counts as an advantage here.

Detecting palindromes

This is one thing where Prolog usually has a significant advantage over other languages, because you can make the relationship between palindromes and reflection explicit:

 palindrome(X) :- reverse(X, X).

However, J is still able to beat this:

palindrome =: -: |.

Match the value with its reflection.