Atop and Over are 2-modifiers that extend the idea of "apply this, then that" in two different ways. They're modelled after the mathematical notation fβg to compose two functions, and both do the same thing when there's one argument: either FβG x
or FβG x
is F G x
.
Cmp |
Cmp π© |
π¨ Cmp π© |
Unified | On list |
---|---|---|---|---|
FβG |
F G π© |
F π¨ G π© |
{π½π¨πΎπ©} |
F GΒ΄π© |
FβG |
F G π© |
(G π¨) F G π© |
{(πΎπ¨)π½πΎπ©} |
FΒ΄GΒ¨π© |
When there are two arguments, we might say Atop treats the right operand πΎ
as primary and Over treats π½
as primaryβthe primary operand becomes dyadic while the other is always monadic. Atop applies πΎ
directly, making it more like mathematical composition if we suppose that πΎ
is a function that can take a pair of arguments. Over instead makes two calls to apply πΎ
separately to both arguments, then passes the results to π½
.
Of the two modifiers on this page, Atop is more common but less impactful. The composition FβG
is equivalent to the 2-train F G
(the trains page has hints on when you'd choose one or the other). Its definition {Fπ¨Gπ©}
means that G
is applied to one or two arguments and F
is applied monadically to the result. It's sort of a "default way" to compose two functions. Keeps tacit programming syntax running smoothly, without making noise about it. Not like that busybody βΈ
. Some examples:
βββ
is useful with one argument: ββ l
is a list of indices for l
.
ββΓ·
is useful with two arguments: βaΓ·b
is the integer part when dividing a
by b
, often paired with the remainder b|a
.
βββ
is useful with one or two arguments. From right to left, we have Classify/Index-of (β
) to convert values to indices, and Group Indices to group the indices. Er, that sounds good but what it actually does is to group indices of Group's argument, which correspond to indices of the original π©
, according to their values as returned by β
. Without a left argument, this means indices of π©
are grouped corresponding to β·π©
, and if π¨
is provided the groups correspond to π¨
instead.
βββ "bbeabee" β¨ β¨ 0 1 4 β© β¨ 2 5 6 β© β¨ 3 β© β© "abcde" βββ "bbeabee" β¨ β¨ 3 β© β¨ 0 1 4 β© β¨β© β¨β© β¨ 2 5 6 β© β©
Once you get used to Over, it's painful to go without it. I'd use it all the time in C if I could.
Usually Over is used just for the dyadic meaning. If you have a composition that only works with one argument it's typical to write it with Atop (β
). And cases that work with one or two arguments do come up from time to time, but they're fairly rare, so the examples below are just for two arguments.
A classic is the function β‘ββ§
, which tests whether π¨
is a reordering of π©
. The idea is to sort both arrays with β§
to remove the ordering information, then see if they match.
"BQN" β‘ββ§ "QNB" 1 "BQN" β‘ββ§ "BBQ" 0
Another example is /ββ₯
, used to filter elements in a high-rank array. Alone, /
won't do this because there's no automatic choice of ordering for the results. Applying Deshape (β₯
) to both chooses index order.
β’ a β "qBrs"β"QtuN" ββ β΅"qBrs QtuN" β a < 'a' # Capital letters ββ β΅ 0 1 0 0 1 0 0 1 β (a<'a') / a # Not allowed Error: /: Simple π¨ must have rank 0 or 1 (2β‘=π¨) (a<'a') /ββ₯ a "BQN"
Over is closely connected with the Under modifier, which performs all the same steps but then undoes πΎ
afterwards.