I’ve been using the J programming language on and off (mostly off), for the past couple years, and I still find myself failing to grasp the “array-oriented” approach.
Recently I wanted to find the discrete derivative, or the forward difference of a list of integers. This boils down to finding differences, or deltas, between each successive pair of list elements. So, for a list of integers,
1 2 4 7 11, the list of deltas would be
1 2 3 4.
My first stab at building a verb that does this looked like this:
(-/"1@:}.@:(],._1&|.)) 1 2 4 7 11 1 2 3 4
The idea is that we take our list, rotate it once to the left, and stitch it onto itself. This gives us a list of tuples of each pair of subsequent numbers, except for the first tuple which holds our first and last list values. We drop that tuple and map minus over the remaining pairs.
This solution seems overly verbose and complicated for something as seemingly fundamental as calculating differences between subsequent list values.
I asked for help on #JLang Twitter, and learned about the “cut” verb, specifically the
:._3 form of cut, which executes a verb over subarrays, or “regular tilings” of its input. Armed with this knowledge, we can map minus over all length two tilings of our list:
2(-~/;._3) 1 2 4 7 11 1 2 3 4
I was happy with this solution, but #JLang Twitter pried my mind open even further and made me realize that I still haven’t fully grasped what it means to work in an “array oriented” mindset.
It was explained to me that I should work with the entire array as a unit, rather than operate on each over the elements individually. What I’m really after is the “beheaded” (
}.) array minus the “curtailed” (
(}. - }:) 1 2 4 7 11 1 2 3 4
This is the shortest, clearest, and, in hindsight, most obvious solution. It’s clear to me that I still need to work on getting into the “array-oriented” mindset when working with J, but hopefully with enough exposure to solutions liks this, I’ll get there.
Now we’re thinking with arrays!