Working Up to J
To do J, you must change the way you think. You must also learn many new words and other parts of speech. Working on part one today ...
Thoughts Must Change
My purpose here is to share with you my way of thinking about learning J. I’m not saying that you should work this way, but I do hope that observing my probes, fits, and starts will give you ideas about how you would learn something as bizarre as I’m finding J to be. Enjoy, I hope!
In J, one needs to think in terms of aggregates. Arrays and vectors and such are sliced and diced with verbs that do operations on the whole schmeer. You also have to learn lots of verbs and adverbs and such. As you get to envisioning the solution of your problem in an aggregate context, and as you learn the verbs that do the work, and the ways of putting them together, you begin to be able to solve problems in a very compact way.
How do I know this? Well, partly received wisdom. However, I also did a fair amount of APL, before you were born, and worked a lot with extended set theory as well. So I have some experience and understanding. I remember what it felt like, and how bizarre my dreams were. So I’ll know it when I see it.
Thinking About ... you guessed it .... Bowling
Yeah, I know, I always do bowling. Get over it. In fact, bowling looks like it might be really interesting in J. It combines some very general processing of groups of items (frames) with some interesting special rules. So I’ve been thinking about how one might do bowling in J … without really knowing the J verbs at all well. The idea is to work both sides of my brain. On the one hand I’ve spent probably 10 to 15 hours going through J tutorials and experimenting. And on this hand (head?) I’m trying to think in aggregates without much regard yet for quite how I’d express that in J.
Recall that the problem we want to solve is to compute the correct score, given a list of all the rolls of a correctly recorded game of bowling. No error handling, just the basic calculation. Thinking first about a collection of simple open frames, we might have
opensFlat =. 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5
Now of course we can just use the plus operator (+) with the insert adverb (/) to add this up:
+/ 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5
will give us 90, the correct score. That expression in J is equivalent to 4 + 5 + 4 + 5 + … + 4 + 5, by the way.
That’s not very interesting, though, because with non open frames we need to count some of the rolls more than once. That’s what makes the problem at all interesting. But suppose the rolls were arranged into frames, kind of like this:
4 5
4 5
4 5
4 5
4 5
4 5
4 5
4 5
4 5
4 5
That might be a way forward. We could compute the score for each frame, then add them up. And if we just beefed up the calculation for the frame a bit, that might do the job for us. So I fiddle a bit in J and discover that I can create that table above by using the “shape” verb, ($).
10 2 $ 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5 4 5
However, doing +/ on that is disappointing, as it returns 40 50, adding up each column. OK, transposing that list might do it. Turns out that 2 10 $ opensFlat doesn’t do it. It alternates 4 5 4 5 across both rows.
Looking further I find that |: is transpose. That does the job:
|: 10 2 $ opensFlat
4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5
Woot. Now +/ this gives a row of nines, and +/ that is 90, the answer. So, imagine how we might do this. Each frame in bowling has either
- Two rolls and no bonus (or a bonus of zero);
- Two rolls and a bonus roll;
- One roll and two bonus rolls.
The bonus rolls, of course, are just the rolls from the next frames, counted twice. No matter that, for now. So we can consider the bowling game to consist of three rows, not just two: the first roll, the second roll, and the third roll.
Careful readers will remember that we have discovered this three-ness in previous implementations in other languages.
So, I’m thinking, if I could somehow laminate an extra value onto the bottom of the roll table above, and populate it with the bonus, that would be good. Or, we might find it better to laminate two bonus rows: since we don’t know much about J yet, we can’t be sure which way might make more sense. Either way, the bonus row or rows would contain copies of the rolls from subsequent columns. Sounds interesting.
I wonder if it is possible to laminate a new row on, or anything like that. So I’ll look around. Huh. There is a thing called Laminate but that adds a new table to mine, making it another layer in the third dimension. However typing
opens , 0
produces just what I’m thinking about, three rows, first roll, second roll, and a row of zeros.
Therefore, given opensFlat, the rolls for a game where every frame has two rolls (notice that we have not dealt with strikes yet), we can produce our three-row array thusly:
(|: 2 10 $ opensFlat) , 0
4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5
0 0 0 0 0 0 0 0 0 0
This is a good thing.
Why is This a Good Thing?
It’s a good thing because we’ve done a little thinking in aggregate terms, thought of an approach to bowling using aggregates, and learned a bit about a few J verbs and adverbs.
There’s plenty left to do, of course. But I feel I’m on a course to think about manipulating vectors and arrays to get what I want. It gives a little context to my experiments with J. I might even try doing at least some of my experiments with the tutorials using my little idea here.
At the same time, I’m not married to this idea at all. There may be much more J-like ways to do this. That’s fine. Right now, I just one one way to do it in J. After that, I can find another.
One More Remark -- What I'm NOT Doing.
I have looked at the J solution to bowling in the article here, but I’ve not tried very hard to dig into it. I looked enough to see that it uses verbs and syntax that are over my head at the moment. In addition, I am trying to build understanding, and right now my focus is on understanding J verbs and usage on the one hand, and thinking this way on the other. So I really don’t want to be handed a solution to decode: I want to build it up in bits that I understand.
Your mileage might vary, and if I were in a hurry to score some bowling, I might go the other way. As I’m here to learn, this works for me.