I like learning new programming languages. It’s like a whole new way of thinking. I thought I’d have another look at J (an ASCII descendent of APL). APL and J clearly enshrine a way of thinking that is unusual amongst programming languages, and that alone makes them worth learning. I last looked at J about 10 years ago. My head exploded. This time the tutorials seem to have a tiny bit more explanation to them.
I learnt something that I wasn’t expecting (invaluable). I learnt that if you take two single digit numbers and multiple them and take the last digit of the answer, then you get the same last digit if you subtract each of the starting number from 10 and do the same thing. 3 × 4 = 12; 7 × 6 = 42. Note that 7 is 3 from 10 and 6 is 4 from 10; we could say that 7 and 6 were the complements in 10 of 3 and 4.
Learning this new thing happened as I was bashing away at the J prompt. One of the examples that comes with J produces an addition table with code like this:
(i.5) +/ (i.5). And you can produce a coloured quilt pattern with
viewmat (i.5) +/ (i.5) (or at least you can once you’ve remembered to type «require ‘graph’» first):
So I thought that a multiplication table mod 10 would be a good idea. It shows the last digit of a multiplication. The code for that is easy:
viewmat 10 | (i.11) */ (i.11):
The first thing I noticed was that there was a reflection symmetry along the main-diagonal. That’s easy to explain, multiplication is commutative so x × y = y × x.
The next thing I noticed suprised me. There was a reflection symmetry along the other diagonal (the counter-diagonal). I wasn’t expecting that at all. I thought about this for a bit. So what I seem to be seeing is that:
a ⊗ b = (10 – a) ⊗ (10 – b)
where ⊗ denotes multiplication in the ring of integers modulo 10. Well that’s easy to see with a bit of algebra:
(10 – a) ⊗ (10 – b) = (-a) ⊗ (-b) = a ⊗ b
or without using a ring:
(10 – a) × (10 – b) | 10 = 100 – 10×a – 10×b + a×b | 10
by multiplying out; and we can see that 100 and 10×a and 10×b are all 0 | 10, so the right hand side reduces to:
a×b | 10
Another way of thinking about this is that adding 10 to a number obviously isn’t going to affect the last digit of a multiplication. Nor is taking away 10. So subtracting a number from 10 is just like negating it; and negating both numbers obviously doesn’t change the answer when you multiply them together. We can see this repeating pattern in J with
viewmat 10 | (i:10) */ (i:10) which gives the table for integers from -10 to 10:
Aside: I find the above image a bit disturbing to look at. Some part of my brain wants to believe that it has left-right and top-bottom mirror symmetry (which it almost does have) and is fighting with the bit of brain that can see that it doesn’t have mirror symmetry.
A larger repeating version can be seen with the code
viewmat 10 | (i:40) */ (i:40):
Further aside: I produced these pictures by saving them as BMP files using
savemat_jviewmat_ in J and converting them to much smaller PNG format using the excellent netpbm suite. In the BMP files all the blues got swopped for reds and vice-versa. Someone got confused as to whether the colours were specified RGB or BGR, so I had to channel swop them back again. Of course that’s pretty easy to do using netpbm. Bottom line: BMP sucks.
So the thing that impresses me about J was that I was just playing around with it casually and discovered for myself this little fact about numbers that I hadn’t known before. This is how it should be when we’re using a tool for learning. It reminds me of the way you can discover things about geometry by playing around with Logo. It makes me want to use computers as an exploratory tool for teaching children maths through discovery.
J itself still makes me think my head is about to explode.
If J intrigues you from this taste, perhaps you ought follow along with me: Learning J part I.