aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2022-04-11 22:32:10 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2022-04-11 22:32:56 -0400
commit0fe07c5912c42fca1f4a9010d240ac0116a671a2 (patch)
treecab3ac5af015ee7e579dd7cab994ce98c4d666ff
parent846425fabe9b4c5c9bbe2be0c785fd1662a0daaa (diff)
Documentation for Atop and Over
-rw-r--r--doc/README.md1
-rw-r--r--doc/compose.md53
-rw-r--r--doc/primitive.md22
-rw-r--r--docs/doc/compose.html140
-rw-r--r--docs/doc/index.html1
-rw-r--r--docs/doc/primitive.html4
-rw-r--r--docs/help/atop.html2
-rw-r--r--docs/help/over.html2
-rw-r--r--help/atop.md2
-rw-r--r--help/over.md2
10 files changed, 216 insertions, 13 deletions
diff --git a/doc/README.md b/doc/README.md
index 4d7e41a6..4f8c49cf 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -41,6 +41,7 @@ Primitives:
- [Array depth](depth.md) (`≡` and `⚇`)
- [Array dimensions](shape.md) (`≢=≠`)
- [Assert and Catch](assert.md) (`!` and `⎊`)
+- [Atop and Over](compose.md) (`∘○`)
- [Deshape and Reshape](reshape.md) (`⥊`)
- [Enclose](enclose.md) (`<`)
- [Find](find.md) (`⍷`)
diff --git a/doc/compose.md b/doc/compose.md
new file mode 100644
index 00000000..c848b9d5
--- /dev/null
+++ b/doc/compose.md
@@ -0,0 +1,53 @@
+*View this file with results and syntax highlighting [here](https://mlochbaum.github.io/BQN/doc/compose.html).*
+
+# Atop and Over
+
+<!--GEN combinator.bqn
+DrawComp ≍"∘○"
+-->
+
+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: `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 `𝔽`.
+
+## Atop
+
+Of the two modifiers on this page, Atop is more common but less impactful. The composition `F∘G` is equivalent to the 2-[train](train.md) `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 could be considered a "default way" to compose two functions. Keeps [tacit](tacit.md) 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](arithmetic.md#additional-arithmetic) `b|a`.
+
+`⊔∘⊐` is useful with one or two arguments. From right to left, we have [Classify](selfcmp.md#classify)/[Index-of](search.md#index-of) (`⊐`) to convert values to indices, and [Group Indices](group.md) 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"
+
+ "abcde" ⊔∘⊐ "bbeabee"
+
+## Over
+
+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
+
+ "BQN" ≡○∧ "QNB"
+ "BQN" ≡○∧ "BBQ"
+
+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](reshape.md) (`⥊`) to both chooses index order.
+
+ ⊢ a ← "qBrs"≍"QtuN"
+
+ a < 'a' # Capital letters
+
+ (a<'a') / a # Not allowed
+
+ (a<'a') /○⥊ a
+
+Over is closely connected with the Under modifier, which performs all the same steps but then undoes `𝔾` afterwards.
diff --git a/doc/primitive.md b/doc/primitive.md
index d81188c2..03634235 100644
--- a/doc/primitive.md
+++ b/doc/primitive.md
@@ -65,17 +65,17 @@ Functions that have significant differences from APL equivalents or don't appear
*Combinators* only control the application of functions. Because a non-function operand applies as a constant function, some combinators have extra meanings when passed a constant. For example, `0˜` is identical to `0˙`—a constant function that always returns 0—and `0⊸<` is the function that tests whether its right argument is greater than 0.
-Glyph | Name(s) | Definition | Description
-------|-------------|--------------------------------|---------------------------------------
-`˙` | Constant | `{𝕩⋄𝕗}` | Return a function that returns the operand
-`˜` | Self/Swap | `{𝕩𝔽𝕨⊣𝕩}` | Duplicate one argument or exchange two
-`∘` | Atop | `{𝔽𝕨𝔾𝕩}` | Apply `𝔾` to both arguments and `𝔽` to the result
-`○` | Over | `{(𝔾𝕨)𝔽𝔾𝕩}` | Apply `𝔾` to each argument and `𝔽` to the results
-`⊸` | Before/Bind | `{(𝔽𝕨⊣𝕩)𝔾𝕩}` | `𝔾`'s left argument comes from `𝔽`
-`⟜` | After/Bind | `{(𝕨⊣𝕩)𝔽𝔾𝕩}` | `𝔽`'s right argument comes from `𝔾`
-`⌾` | Under | `{𝔾⁼∘𝔽○𝔾}` OR `{(𝔾𝕩)↩𝕨𝔽○𝔾𝕩⋄𝕩}` | Apply `𝔽` over `𝔾`, then undo `𝔾`
-`⊘` | Valences | `{𝔽𝕩;𝕨𝔾𝕩}` | Apply `𝔽` if there's one argument but `𝔾` if there are two
-`◶` | Choose | `{f←(𝕨𝔽𝕩)⊑𝕘 ⋄ 𝕨F𝕩}` | Select one of the functions in list `𝕘` based on `𝔽`
+Glyph | Name(s) | Definition | Description
+------|--------------------|--------------------------------|---------------------------------------
+`˙` | Constant | `{𝕩⋄𝕗}` | Return a function that returns the operand
+`˜` | Self/Swap | `{𝕩𝔽𝕨⊣𝕩}` | Duplicate one argument or exchange two
+`∘` | [Atop](compose.md) | `{𝔽𝕨𝔾𝕩}` | Apply `𝔾` to both arguments and `𝔽` to the result
+`○` | [Over](compose.md) | `{(𝔾𝕨)𝔽𝔾𝕩}` | Apply `𝔾` to each argument and `𝔽` to the results
+`⊸` | Before/Bind | `{(𝔽𝕨⊣𝕩)𝔾𝕩}` | `𝔾`'s left argument comes from `𝔽`
+`⟜` | After/Bind | `{(𝕨⊣𝕩)𝔽𝔾𝕩}` | `𝔽`'s right argument comes from `𝔾`
+`⌾` | Under | `{𝔾⁼∘𝔽○𝔾}` OR `{(𝔾𝕩)↩𝕨𝔽○𝔾𝕩⋄𝕩}` | Apply `𝔽` over `𝔾`, then undo `𝔾`
+`⊘` | Valences | `{𝔽𝕩;𝕨𝔾𝕩}` | Apply `𝔽` if there's one argument but `𝔾` if there are two
+`◶` | Choose | `{f←(𝕨𝔽𝕩)⊑𝕘 ⋄ 𝕨F𝕩}` | Select one of the functions in list `𝕘` based on `𝔽`
Choose isn't really a combinator since it calls the function `⊑`, and Under is not a true combinator since it has an "undo" step at the end. This step might be implemented using the left operand's inverse (*computational* Under) or its structural properties (*structural* Under).
diff --git a/docs/doc/compose.html b/docs/doc/compose.html
new file mode 100644
index 00000000..4458ea3c
--- /dev/null
+++ b/docs/doc/compose.html
@@ -0,0 +1,140 @@
+<head>
+ <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/>
+ <link href="../style.css" rel="stylesheet"/>
+ <title>BQN: Atop and Over</title>
+</head>
+<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
+<h1 id="atop-and-over"><a class="header" href="#atop-and-over">Atop and Over</a></h1>
+<svg viewBox='-51 0 672 270'>
+ <g font-size='20px' text-anchor='middle' transform='translate(145,20)'>
+ <rect class='code' stroke-width='1' rx='12' x='-120.4' y='1' width='240.8' height='205'/>
+ <text dy='0.32em' y='223' fill='currentColor'>Atop</text>
+ <g font-size='21px' font-family='BQN,monospace' transform='translate(-60.87,25)'>
+ <text dy='0.32em' y='155' font-size='19px'><tspan class='Function'>𝔽</tspan><tspan class='Modifier2'>∘</tspan><tspan class='Function'>𝔾</tspan> <tspan class='Value'>𝕩</tspan></text>
+ <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L0 57'/>
+ <path class='yellow' style='fill:none' stroke-width='2' d='M0 57L0 114'/>
+ <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/>
+ <circle r='12' class='code' stroke-width='0' cx='0' cy='57'/>
+ <circle r='12' class='code' stroke-width='0' cx='0' cy='114'/>
+ <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔽</tspan></text>
+ <text dy='0.32em' x='0' y='57'><tspan class='Function'>𝔾</tspan></text>
+ <text dy='0.32em' x='0' y='114'><tspan class='Value'>𝕩</tspan></text>
+ </g>
+ <g font-size='21px' font-family='BQN,monospace' transform='translate(60.87,25)'>
+ <text dy='0.32em' y='155' font-size='19px'><tspan class='Value'>𝕨</tspan> <tspan class='Function'>𝔽</tspan><tspan class='Modifier2'>∘</tspan><tspan class='Function'>𝔾</tspan> <tspan class='Value'>𝕩</tspan></text>
+ <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L0 57'/>
+ <path class='yellow' style='fill:none' stroke-width='2' d='M0 57L-32 114'/>
+ <path class='yellow' style='fill:none' stroke-width='2' d='M0 57L32 114'/>
+ <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/>
+ <circle r='12' class='code' stroke-width='0' cx='0' cy='57'/>
+ <circle r='12' class='code' stroke-width='0' cx='-32' cy='114'/>
+ <circle r='12' class='code' stroke-width='0' cx='32' cy='114'/>
+ <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔽</tspan></text>
+ <text dy='0.32em' x='0' y='57'><tspan class='Function'>𝔾</tspan></text>
+ <text dy='0.32em' x='-32' y='114'><tspan class='Value'>𝕨</tspan></text>
+ <text dy='0.32em' x='32' y='114'><tspan class='Value'>𝕩</tspan></text>
+ </g>
+ </g>
+ <g font-size='20px' text-anchor='middle' transform='translate(425,20)'>
+ <rect class='code' stroke-width='1' rx='12' x='-120.4' y='1' width='240.8' height='205'/>
+ <text dy='0.32em' y='223' fill='currentColor'>Over</text>
+ <g font-size='21px' font-family='BQN,monospace' transform='translate(-60.87,25)'>
+ <text dy='0.32em' y='155' font-size='19px'><tspan class='Function'>𝔽</tspan><tspan class='Modifier2'>○</tspan><tspan class='Function'>𝔾</tspan> <tspan class='Value'>𝕩</tspan></text>
+ <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L0 57'/>
+ <path class='yellow' style='fill:none' stroke-width='2' d='M0 57L0 114'/>
+ <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/>
+ <circle r='12' class='code' stroke-width='0' cx='0' cy='57'/>
+ <circle r='12' class='code' stroke-width='0' cx='0' cy='114'/>
+ <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔽</tspan></text>
+ <text dy='0.32em' x='0' y='57'><tspan class='Function'>𝔾</tspan></text>
+ <text dy='0.32em' x='0' y='114'><tspan class='Value'>𝕩</tspan></text>
+ </g>
+ <g font-size='21px' font-family='BQN,monospace' transform='translate(60.87,25)'>
+ <text dy='0.32em' y='155' font-size='19px'><tspan class='Value'>𝕨</tspan> <tspan class='Function'>𝔽</tspan><tspan class='Modifier2'>○</tspan><tspan class='Function'>𝔾</tspan> <tspan class='Value'>𝕩</tspan></text>
+ <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L-32 57'/>
+ <path class='yellow' style='fill:none' stroke-width='2' d='M-32 57L-32 114'/>
+ <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L32 57'/>
+ <path class='yellow' style='fill:none' stroke-width='2' d='M32 57L32 114'/>
+ <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/>
+ <circle r='12' class='code' stroke-width='0' cx='-32' cy='57'/>
+ <circle r='12' class='code' stroke-width='0' cx='32' cy='57'/>
+ <circle r='12' class='code' stroke-width='0' cx='-32' cy='114'/>
+ <circle r='12' class='code' stroke-width='0' cx='32' cy='114'/>
+ <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔽</tspan></text>
+ <text dy='0.32em' x='-32' y='57'><tspan class='Function'>𝔾</tspan></text>
+ <text dy='0.32em' x='32' y='57'><tspan class='Function'>𝔾</tspan></text>
+ <text dy='0.32em' x='-32' y='114'><tspan class='Value'>𝕨</tspan></text>
+ <text dy='0.32em' x='32' y='114'><tspan class='Value'>𝕩</tspan></text>
+ </g>
+ </g>
+</svg>
+
+<p>Atop and Over are 2-modifiers that extend the idea of &quot;apply this, then that&quot; 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: <code><span class='Function'>F</span><span class='Modifier2'>∘</span><span class='Function'>G</span> <span class='Value'>x</span></code> or <code><span class='Function'>F</span><span class='Modifier2'>○</span><span class='Function'>G</span> <span class='Value'>x</span></code> is <code><span class='Function'>F</span> <span class='Function'>G</span> <span class='Value'>x</span></code>.</p>
+<table>
+<thead>
+<tr>
+<th><code><span class='Function'>Cmp</span></code></th>
+<th><code><span class='Function'>Cmp</span> <span class='Value'>𝕩</span></code></th>
+<th align="center"><code><span class='Value'>𝕨</span> <span class='Function'>Cmp</span> <span class='Value'>𝕩</span></code></th>
+<th align="center">Unified</th>
+<th align="center">On list</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code><span class='Function'>F</span><span class='Modifier2'>∘</span><span class='Function'>G</span></code></td>
+<td><code><span class='Function'>F</span> <span class='Function'>G</span> <span class='Value'>𝕩</span></code></td>
+<td align="center"><code><span class='Function'>F</span> <span class='Value'>𝕨</span> <span class='Function'>G</span> <span class='Value'>𝕩</span></code></td>
+<td align="center"><code><span class='Brace'>{</span><span class='Function'>𝔽</span><span class='Value'>𝕨</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code></td>
+<td align="center"><code><span class='Function'>F</span> <span class='Function'>G</span><span class='Modifier'>´</span><span class='Value'>𝕩</span></code></td>
+</tr>
+<tr>
+<td><code><span class='Function'>F</span><span class='Modifier2'>○</span><span class='Function'>G</span></code></td>
+<td><code><span class='Function'>F</span> <span class='Function'>G</span> <span class='Value'>𝕩</span></code></td>
+<td align="center"><code><span class='Paren'>(</span><span class='Function'>G</span> <span class='Value'>𝕨</span><span class='Paren'>)</span> <span class='Function'>F</span> <span class='Function'>G</span> <span class='Value'>𝕩</span></code></td>
+<td align="center"><code><span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>𝔾</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>𝔽𝔾</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code></td>
+<td align="center"><code><span class='Function'>F</span><span class='Modifier'>´</span><span class='Function'>G</span><span class='Modifier'>¨</span><span class='Value'>𝕩</span></code></td>
+</tr>
+</tbody>
+</table>
+<p>When there are two arguments, we might say Atop treats the right operand <code><span class='Function'>𝔾</span></code> as primary and Over treats <code><span class='Function'>𝔽</span></code> as primary—the primary operand becomes dyadic while the other is always monadic. Atop applies <code><span class='Function'>𝔾</span></code> directly, making it more like mathematical composition if we suppose that <code><span class='Function'>𝔾</span></code> is a function that can take a pair of arguments. Over instead makes two calls to apply <code><span class='Function'>𝔾</span></code> separately to both arguments, then passes the results to <code><span class='Function'>𝔽</span></code>.</p>
+<h2 id="atop"><a class="header" href="#atop">Atop</a></h2>
+<p>Of the two modifiers on this page, Atop is more common but less impactful. The composition <code><span class='Function'>F</span><span class='Modifier2'>∘</span><span class='Function'>G</span></code> is equivalent to the 2-<a href="train.html">train</a> <code><span class='Function'>F</span> <span class='Function'>G</span></code> (the trains page has hints on when you'd choose one or the other). Its definition <code><span class='Brace'>{</span><span class='Function'>F</span><span class='Value'>𝕨</span><span class='Function'>G</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> means that <code><span class='Function'>G</span></code> is applied to one or two arguments and <code><span class='Function'>F</span></code> is applied monadically to the result. It could be considered a &quot;default way&quot; to compose two functions. Keeps <a href="tacit.html">tacit</a> programming syntax running smoothly, without making noise about it. Not like that busybody <code><span class='Modifier2'>⊸</span></code>. Some examples:</p>
+<p><code><span class='Function'>↕</span><span class='Modifier2'>∘</span><span class='Function'>≠</span></code> is useful with one argument: <code><span class='Function'>↕≠</span><span class='Value'>l</span></code> is a list of indices for <code><span class='Value'>l</span></code>.</p>
+<p><code><span class='Function'>⌊</span><span class='Modifier2'>∘</span><span class='Function'>÷</span></code> is useful with two arguments: <code><span class='Function'>⌊</span><span class='Value'>a</span><span class='Function'>÷</span><span class='Value'>b</span></code> is the integer part when dividing <code><span class='Value'>a</span></code> by <code><span class='Value'>b</span></code>, often paired with the <a href="arithmetic.html#additional-arithmetic">remainder</a> <code><span class='Value'>b</span><span class='Function'>|</span><span class='Value'>a</span></code>.</p>
+<p><code><span class='Function'>⊔</span><span class='Modifier2'>∘</span><span class='Function'>⊐</span></code> is useful with one or two arguments. From right to left, we have <a href="selfcmp.html#classify">Classify</a>/<a href="search.html#index-of">Index-of</a> (<code><span class='Function'>⊐</span></code>) to convert values to indices, and <a href="group.html">Group Indices</a> to group the indices. Er, that sounds good but what it <em>actually</em> does is to group indices of Group's argument, which correspond to indices of the original <code><span class='Value'>𝕩</span></code>, according to their values as returned by <code><span class='Function'>⊐</span></code>. Without a left argument, this means indices of <code><span class='Value'>𝕩</span></code> are grouped corresponding to <code><span class='Function'>⍷</span><span class='Value'>𝕩</span></code>, and if <code><span class='Value'>𝕨</span></code> is provided the groups correspond to <code><span class='Value'>𝕨</span></code> instead.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqU4oiY4oqQICJiYmVhYmVlIgoKImFiY2RlIiDiipTiiJjiipAgImJiZWFiZWUi">↗️</a><pre> <span class='Function'>⊔</span><span class='Modifier2'>∘</span><span class='Function'>⊐</span> <span class='String'>&quot;bbeabee&quot;</span>
+⟨ ⟨ 0 1 4 ⟩ ⟨ 2 5 6 ⟩ ⟨ 3 ⟩ ⟩
+
+ <span class='String'>&quot;abcde&quot;</span> <span class='Function'>⊔</span><span class='Modifier2'>∘</span><span class='Function'>⊐</span> <span class='String'>&quot;bbeabee&quot;</span>
+⟨ ⟨ 3 ⟩ ⟨ 0 1 4 ⟩ ⟨⟩ ⟨⟩ ⟨ 2 5 6 ⟩ ⟩
+</pre>
+<h2 id="over"><a class="header" href="#over">Over</a></h2>
+<p>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.</p>
+<p>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 (<code><span class='Modifier2'>∘</span></code>). 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.</p>
+<p>A classic is the function <code><span class='Function'>≡</span><span class='Modifier2'>○</span><span class='Function'>∧</span></code>, which tests whether <code><span class='Value'>𝕨</span></code> is a reordering of <code><span class='Value'>𝕩</span></code>. The idea is to sort both arrays with <code><span class='Function'>∧</span></code> to remove the ordering information</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IkJRTiIg4omh4peL4oinICJRTkIiCiJCUU4iIOKJoeKXi+KIpyAiQkJRIg==">↗️</a><pre> <span class='String'>&quot;BQN&quot;</span> <span class='Function'>≡</span><span class='Modifier2'>○</span><span class='Function'>∧</span> <span class='String'>&quot;QNB&quot;</span>
+1
+ <span class='String'>&quot;BQN&quot;</span> <span class='Function'>≡</span><span class='Modifier2'>○</span><span class='Function'>∧</span> <span class='String'>&quot;BBQ&quot;</span>
+0
+</pre>
+<p>Another example is <code><span class='Function'>/</span><span class='Modifier2'>○</span><span class='Function'>⥊</span></code>, used to filter elements in a high-rank array. Alone, <code><span class='Function'>/</span></code> won't do this because there's no automatic choice of ordering for the results. Applying <a href="reshape.html">Deshape</a> (<code><span class='Function'>⥊</span></code>) to both chooses index order.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGEg4oaQICJxQnJzIuKJjSJRdHVOIgoKYSA8ICdhJyAgIyBDYXBpdGFsIGxldHRlcnMKCihhPCdhJykgLyBhICAjIE5vdCBhbGxvd2VkCgooYTwnYScpIC/il4vipYogYQ==">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='String'>&quot;qBrs&quot;</span><span class='Function'>≍</span><span class='String'>&quot;QtuN&quot;</span>
+┌─
+╵"qBrs
+ QtuN"
+ ┘
+
+ <span class='Value'>a</span> <span class='Function'>&lt;</span> <span class='String'>'a'</span> <span class='Comment'># Capital letters
+</span>┌─
+╵ 0 1 0 0
+ 1 0 0 1
+ ┘
+
+ <span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>&lt;</span><span class='String'>'a'</span><span class='Paren'>)</span> <span class='Function'>/</span> <span class='Value'>a</span> <span class='Comment'># Not allowed
+</span><span class='Error'>Error: 𝕨/𝕩: Components of 𝕨 must have rank 0 or 1</span>
+
+ <span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>&lt;</span><span class='String'>'a'</span><span class='Paren'>)</span> <span class='Function'>/</span><span class='Modifier2'>○</span><span class='Function'>⥊</span> <span class='Value'>a</span>
+"BQN"
+</pre>
+<p>Over is closely connected with the Under modifier, which performs all the same steps but then undoes <code><span class='Function'>𝔾</span></code> afterwards.</p>
diff --git a/docs/doc/index.html b/docs/doc/index.html
index 49567105..821de18a 100644
--- a/docs/doc/index.html
+++ b/docs/doc/index.html
@@ -47,6 +47,7 @@
<li><a href="depth.html">Array depth</a> (<code><span class='Function'>≡</span></code> and <code><span class='Modifier2'>⚇</span></code>)</li>
<li><a href="shape.html">Array dimensions</a> (<code><span class='Function'>≢=≠</span></code>)</li>
<li><a href="assert.html">Assert and Catch</a> (<code><span class='Function'>!</span></code> and <code><span class='Modifier2'>⎊</span></code>)</li>
+<li><a href="compose.html">Atop and Over</a> (<code><span class='Modifier2'>∘○</span></code>)</li>
<li><a href="reshape.html">Deshape and Reshape</a> (<code><span class='Function'>⥊</span></code>)</li>
<li><a href="enclose.html">Enclose</a> (<code><span class='Function'>&lt;</span></code>)</li>
<li><a href="find.html">Find</a> (<code><span class='Function'>⍷</span></code>)</li>
diff --git a/docs/doc/primitive.html b/docs/doc/primitive.html
index 4def02cf..dda31281 100644
--- a/docs/doc/primitive.html
+++ b/docs/doc/primitive.html
@@ -437,13 +437,13 @@
</tr>
<tr>
<td><code><span class='Modifier2'>∘</span></code></td>
-<td>Atop</td>
+<td><a href="compose.html">Atop</a></td>
<td><code><span class='Brace'>{</span><span class='Function'>𝔽</span><span class='Value'>𝕨</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code></td>
<td>Apply <code><span class='Function'>𝔾</span></code> to both arguments and <code><span class='Function'>𝔽</span></code> to the result</td>
</tr>
<tr>
<td><code><span class='Modifier2'>○</span></code></td>
-<td>Over</td>
+<td><a href="compose.html">Over</a></td>
<td><code><span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>𝔾</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>𝔽𝔾</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code></td>
<td>Apply <code><span class='Function'>𝔾</span></code> to each argument and <code><span class='Function'>𝔽</span></code> to the results</td>
</tr>
diff --git a/docs/help/atop.html b/docs/help/atop.html
index 02764808..04827555 100644
--- a/docs/help/atop.html
+++ b/docs/help/atop.html
@@ -6,6 +6,7 @@
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">help</a></div>
<h1 id="ring-operator-"><a class="header" href="#ring-operator-">Ring Operator (<code><span class='Modifier2'>∘</span></code>)</a></h1>
<h2 id="𝔽𝔾-𝕩-atop"><a class="header" href="#𝔽𝔾-𝕩-atop"><code><span class='Function'>𝔽</span><span class='Modifier2'>∘</span><span class='Function'>𝔾</span> <span class='Value'>𝕩</span></code>: Atop</a></h2>
+<p><a class="fulldoc" href="../doc/compose.html">→full documentation</a></p>
<p>Apply <code><span class='Function'>𝔾</span></code> to <code><span class='Value'>𝕩</span></code>, then apply <code><span class='Function'>𝔽</span></code> (<code><span class='Function'>𝔽</span> <span class='Function'>𝔾</span> <span class='Value'>𝕩</span></code>).</p>
<p><code><span class='Function'>𝔽</span></code> and <code><span class='Function'>𝔾</span></code> must be monadic.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=LeKImC0gNQoKLSAtIDU=">↗️</a><pre> <span class='Function'>-</span><span class='Modifier2'>∘</span><span class='Function'>-</span> <span class='Number'>5</span>
@@ -15,6 +16,7 @@
5
</pre>
<h2 id="𝕨-𝔽𝔾-𝕩-dyadic-atop"><a class="header" href="#𝕨-𝔽𝔾-𝕩-dyadic-atop"><code><span class='Value'>𝕨</span> <span class='Function'>𝔽</span><span class='Modifier2'>∘</span><span class='Function'>𝔾</span> <span class='Value'>𝕩</span></code>: Dyadic Atop</a></h2>
+<p><a class="fulldoc" href="../doc/compose.html">→full documentation</a></p>
<p>Apply <code><span class='Function'>𝔾</span></code> to <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code>, then apply <code><span class='Function'>𝔽</span></code> (<code><span class='Function'>𝔽</span> <span class='Paren'>(</span><span class='Value'>𝕨</span> <span class='Function'>𝔾</span> <span class='Value'>𝕩</span><span class='Paren'>)</span></code>).</p>
<p><code><span class='Function'>𝔽</span></code> must be monadic, and <code><span class='Function'>𝔾</span></code> must be dyadic.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MSAt4oiYKyAyCgoxIC0gKyAyCgotIDEgKyAy">↗️</a><pre> <span class='Number'>1</span> <span class='Function'>-</span><span class='Modifier2'>∘</span><span class='Function'>+</span> <span class='Number'>2</span>
diff --git a/docs/help/over.html b/docs/help/over.html
index 8fe4c1eb..f7c86560 100644
--- a/docs/help/over.html
+++ b/docs/help/over.html
@@ -6,6 +6,7 @@
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">help</a></div>
<h1 id="circle-"><a class="header" href="#circle-">Circle (<code><span class='Modifier2'>○</span></code>)</a></h1>
<h2 id="𝔽𝔾-𝕩-atop"><a class="header" href="#𝔽𝔾-𝕩-atop"><code><span class='Function'>𝔽</span><span class='Modifier2'>○</span><span class='Function'>𝔾</span> <span class='Value'>𝕩</span></code>: Atop</a></h2>
+<p><a class="fulldoc" href="../doc/compose.html">→full documentation</a></p>
<p>Apply <code><span class='Function'>𝔾</span></code> to <code><span class='Value'>𝕩</span></code>, then apply <code><span class='Function'>𝔽</span></code> (<code><span class='Function'>𝔽</span> <span class='Function'>𝔾</span> <span class='Value'>𝕩</span></code>).</p>
<p><code><span class='Function'>𝔽</span></code> and <code><span class='Function'>𝔾</span></code> must be monadic.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=LeKXiy0gNQoKLSAtIDU=">↗️</a><pre> <span class='Function'>-</span><span class='Modifier2'>○</span><span class='Function'>-</span> <span class='Number'>5</span>
@@ -15,6 +16,7 @@
5
</pre>
<h2 id="𝕨-𝔽𝔾-𝕩-over"><a class="header" href="#𝕨-𝔽𝔾-𝕩-over"><code><span class='Value'>𝕨</span> <span class='Function'>𝔽</span><span class='Modifier2'>○</span><span class='Function'>𝔾</span> <span class='Value'>𝕩</span></code>: Over</a></h2>
+<p><a class="fulldoc" href="../doc/compose.html">→full documentation</a></p>
<p>Apply <code><span class='Function'>𝔾</span></code> to <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code>, then apply <code><span class='Function'>𝔽</span></code> to them (<code><span class='Paren'>(</span><span class='Function'>𝔾</span> <span class='Value'>𝕨</span><span class='Paren'>)</span> <span class='Function'>𝔽</span> <span class='Paren'>(</span><span class='Function'>𝔾</span> <span class='Value'>𝕩</span><span class='Paren'>)</span></code>).</p>
<p><code><span class='Function'>𝔽</span></code> must be dyadic, <code><span class='Function'>𝔾</span></code> must be monadic.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MSAr4peLLSAyCgoxICsgLSAyCgooLSAxKSArICgtIDIp">↗️</a><pre> <span class='Number'>1</span> <span class='Function'>+</span><span class='Modifier2'>○</span><span class='Function'>-</span> <span class='Number'>2</span>
diff --git a/help/atop.md b/help/atop.md
index 1f141483..cd1204ed 100644
--- a/help/atop.md
+++ b/help/atop.md
@@ -3,6 +3,7 @@
# Ring Operator (`∘`)
## `𝔽∘𝔾 𝕩`: Atop
+[→full documentation](../doc/compose.md)
Apply `𝔾` to `𝕩`, then apply `𝔽` (`𝔽 𝔾 𝕩`).
@@ -15,6 +16,7 @@ Apply `𝔾` to `𝕩`, then apply `𝔽` (`𝔽 𝔾 𝕩`).
## `𝕨 𝔽∘𝔾 𝕩`: Dyadic Atop
+[→full documentation](../doc/compose.md)
Apply `𝔾` to `𝕨` and `𝕩`, then apply `𝔽` (`𝔽 (𝕨 𝔾 𝕩)`).
diff --git a/help/over.md b/help/over.md
index 3a9022ae..c915a207 100644
--- a/help/over.md
+++ b/help/over.md
@@ -3,6 +3,7 @@
# Circle (`○`)
## `𝔽○𝔾 𝕩`: Atop
+[→full documentation](../doc/compose.md)
Apply `𝔾` to `𝕩`, then apply `𝔽` (`𝔽 𝔾 𝕩`).
@@ -15,6 +16,7 @@ Apply `𝔾` to `𝕩`, then apply `𝔽` (`𝔽 𝔾 𝕩`).
## `𝕨 𝔽○𝔾 𝕩`: Over
+[→full documentation](../doc/compose.md)
Apply `𝔾` to `𝕨` and `𝕩`, then apply `𝔽` to them (`(𝔾 𝕨) 𝔽 (𝔾 𝕩)`).