Strings of verbs that are not parseable with the usual dyadic–monadic machinery are called trains.
(%+/) is a train of two verbs; the first verb is
% (division), the second is
+/ (the verb
+ modified by the adverb
/ to produce the sum-list verb).
A train of two verbs
f g is called a hook (or bident, but that isn’t used as much). When used monadically
(f g) x is the same as
x f g x. Notice the repetition of the x operand.
(+-)7 NB. 7 - 7 = 0 0 (*-)2 NB. 2 * -2 _4 (**:)3 NB. * is times and *: is square 27
(%+/) n is the same as
n % +/ n which if n is a list then this rescales the list so that the sum of the result is 1:
i. 5 0 1 2 3 4 (%+/)i.5 0 0.1 0.2 0.3 0.4
Dyadic hooks are boring,
x (f g) y is the same as
x f g y.
A 3-element train,
f g h, is called a fork (or, again less often, trident). The monadic case
(f g h) y is the same as
(f y) g (h y), and the dyadic case
x (f g h) y is the same as
(x f y) g (x h y).
This is all tolerably well explained in Appendix F of the J dictionary.
The mnemonic that I use for remembering the difference between monadic and dyadic tridents is that the monadic case is just the same as the dyadic case but with x removed. Dyadic:
(x f y) g (x h y); Monadic:
(f y) g (h y).
Recall the parsing rules of Appendix E, and observe that larger sequences of verbs get decomposed into hooks and forks.
b c d e is
b (c d e); that is, the hook of
b and the fork
c d e.
a b c d e is a fork of a fork:
a b (c d e).
The classic pedagogical fork computes the average of a list:
avg =: +/ % # avg 6 7 8 7 avg 1 2 4 8 16 6.2 avg 2 ^ i. 5 6.2
Observe that the repetition of operands is useful and can avoid temporaries.
i.11 */ i.11 produces a multiplication table. We can use the fact that a bident duplicates its operand:
(*/ g) i. 11 will do if we can find a monadic g that does nothing. Both
] are monadic identities. So we can get the same multiplication table with
(*/]) i. 11. As it happens this simple duplication is so useful that there’s an adverb,
~ (twiddles), to do it.
u~ y is
y u y. So
*/~ i. 11 also produces the same table.
Suppose we wanted to compute triangular numbers. tri(n) = (n×(n+1))/2. Perhaps we would like to use J to solve Gauss’s little school problem. Note that n×(n+1) can be computed with a bident:
>: is the successor function). Now all we have to do is halve the answer. The currying conjunction
& comes in handy. The monadic
%&2 halves its operand;
%&2 y is the same as
y%2. We can use
@ to compose these two:
tri =: %&2 @ (*>:) tri i.10 0 1 3 6 10 15 21 28 36 45
In fact the brackets aren’t necessary. We can get rid of the brackets around the bident by using the monadic identity,
[, in a trident:
tri =: %&2 @ [*>:
It’s a little shorter, but I’m not convinced that it’s any neater.
I tried this form, and it works, but not for the reasons that I thought it did. The spacing I’ve used above suggests I have a trident on the right, a curried divide operator on the left, and I’ve joined them with
@. We can use J to see how it’s actually been parsed:
%&2 @ [*>: +-------------+-+--+ |+-------+-+-+|*|>:| ||+-+-+-+|@|[|| | | |||%|&|2|| | || | | ||+-+-+-+| | || | | |+-------+-+-+| | | +-------------+-+--+
The kinda scary looking boxes are just another way to write brackets (in this case). So
%&2 @ [*>: turns out to be parsed as
((%&2)@[)*>:. Lesson: be careful. This is actually computing (n/2)×(n+1); of course this is mathematically the same as (n×(n+1))/2 but the latter can be done in integer arithmetic whereas the former requires fractions. Good job halving is an exact operation in IEEE arithmetic.
%&2@[*>: gets parsed as it does is that the trident reduction cannot take place if there is a conjunction to the left of the potential trident. When the stack has the four terms
@ [ * >: on it,
@ is a conjunction so
[ * >: will not be reduced to a trident. The conjunctions get reduced first.
Conjunctions get reduced left to right.
(%&2)@[. Referring to the parsing table again we see that’s because a conjunction won’t be reduced if there is a conjunction immediately to its left.
[ is monadic identity, the
%&2@[ is not necessary. We can just use
%&2*>:. It also turns out that dividing by 2 is sufficiently useful that there’s a primitive to do it:
-:. So we can use
tri =: -:*>:, which is just a single trident.
[:, is a magic verb used in tridents.
[: g h is the same as
f g h but without the entire f branch. So
x ([: g h) y is
g (x h y), and
([: g h) y is
g h y.
The last form of cap is found in our original triangle formula that used
tri =: %&2 @ (*>:). We can remove the
@ conjunction and replace it with a cap instead:
tri =. [: %&2 (*>:)
And this time we can replace the bracketed bident on the right with a trident that uses
tri =. [: %&2 [*>: tri +--+-------+--------+ |[:|+-+-+-+|+-+-+--+| | ||%|&|2|||[|*|>:|| | |+-+-+-+|+-+-+--+| +--+-------+--------+
This does get parsed how we (or at least I) expect, with
[ * >: on the right being reduced to a trident.
-: and, for amusement, swapping
[ we get:
tri =: [:-:]*>:
To be honest this seems like an exercise in fruitless manipulation, but I’m sure I’ll be finding all sorts of witty things we can do with forks and hooks.