Adverbs: each, over, scan and prior
An adverb takes a verb and returns a new verb that applies it differently. Six of them cover nearly everything, and they compose with every verb you know, which is why the vocabulary stays small.
Over ( / ) — collapse a list to a value
+/ 1 2 3 4 / 10
*/ 1 2 3 4 / 24
|/ 1 2 3 4 / 4
&/ 1 2 3 4 / 1
{x+y*y}/0 1 2 3 / 14 -- any dyadic function foldsWith a left argument, that value seeds the fold:
100 +/ 1 2 3 / 106Scan ( \ ) — the running version of over
+\ 1 2 3 4 / 1 3 6 10 -- running sum
|\ 3 1 4 1 5 / 3 3 4 4 5 -- running maximum
&\ 3 1 4 1 5 / 3 1 1 1 1 -- running minimum
*\ 1 2 3 4 / 1 2 6 24|\px is the high-water mark of a price series, so px - |\px is the drawdown at every point, and &/px - |\px is the maximum drawdown. No loop, no state, one pass.
px: 100 104 101 108 99 103
|\ px / 100 104 104 108 108 108
px - |\ px / 0 0 -3 0 -9 -5
&/ px - |\ px / -9 -- max drawdownEach ( ' ) — apply item by item
Most verbs are already elementwise, so ' is for when the items are themselves lists:
#'("ab";"cde";"") / 2 3 0 -- length of each item
|'(1 2;3 4 5) / (2 1;5 4 3) -- reverse each
(+/)'(1 2;3 4 5) / 3 12 -- sum each#'x works; # ' x does not. The space separates the adverb from the verb it is meant to modify, and you get a wrong answer rather than an error. When the verb is itself derived, parenthesise it: (+/)'x.
Each-prior ( ': ) — compare neighbours
-':1 3 6 10 / 1 2 3 4 -- successive differences
deltas 1 3 6 10 / 1 2 3 4 -- the library name for it
,':1 3 6 10 / (,1;3 1;6 3;10 6) -- the pairs it actually forms
1_{x-y}':1 3 6 10 / 2 3 4 -- a lambda: x current, y prior,': shows the pairing: element i is f[x_i; x_i-1], so current first, prior second. -': knows its own identity and seeds the first element with 0, which is why it gives 1 2 3 4. A user lambda does not: its first element is seeded with 0W, so {x-y}':1 3 6 10 starts with a huge negative number. Drop it with 1_, or seed it yourself with a left argument: 1{x-y}':1 3 6 10.
This is the natural way to express "how much did it move" over a series, and it pairs with scan: +\ and -': are inverses.
Each-right ( /: ) and each-left ( \: )
These fix one argument and sweep the other, giving the outer-product idiom:
1 2 3+/:10 20 / (11 12 13;21 22 23) -- each-RIGHT: one row per right item
1 2 3+\:10 20 / (11 21;12 22;13 23) -- each-LEFT: one row per left item
(!3)=\:!3 / (1 0 0;0 1 0;0 0 1) -- identity matrixComposing them
The point of adverbs is that they stack. A weighted average is a fold over a product; a correlation is three folds; a moving sum is a scan and a difference:
w: 1 2 3 4
v: 10 20 30 40
(+/ w * v) % +/ w / 30.0 -- weighted mean, written out
wavg[w; v] / 30.0 -- ... and the library verb for it+/x*y is recognised by the compiler and compiled to a single fused dot-product primitive, so no intermediate product vector is ever written. The same is true of +/x<y, x@&m and +/(a+s*b)@&m. Chapter 8 lists them.