aboutsummaryrefslogtreecommitdiff
path: root/docs/doc
diff options
context:
space:
mode:
Diffstat (limited to 'docs/doc')
-rw-r--r--docs/doc/fromDyalog.html45
-rw-r--r--docs/doc/fromJ.html16
-rw-r--r--docs/doc/functional.html12
-rw-r--r--docs/doc/glossary.html58
-rw-r--r--docs/doc/group.html66
-rw-r--r--docs/doc/map.html28
6 files changed, 126 insertions, 99 deletions
diff --git a/docs/doc/fromDyalog.html b/docs/doc/fromDyalog.html
index ea036ec9..1e36dada 100644
--- a/docs/doc/fromDyalog.html
+++ b/docs/doc/fromDyalog.html
@@ -35,8 +35,7 @@
</tr>
</tbody>
</table>
-<p>BQN shares the terms &quot;cell&quot; and &quot;major cell&quot; with Dyalog, and uses
-&quot;element&quot; (which may mean different things to different Dyalog users) <em>not</em> for a 0-cell but for the value it contains.</p>
+<p>BQN shares the terms &quot;<a href="array.html#cells">cell</a>&quot; and &quot;major cell&quot; with Dyalog, and uses &quot;element&quot; (which may mean different things to different Dyalog users) <em>not</em> for a 0-cell but for the value it contains.</p>
<h3 id="roles"><a class="header" href="#roles">Roles</a></h3>
<p>Dyalog uses value types (array, function, and so on) to determine syntax while BQN uses a separate concept called syntactic roles. See <a href="context.html">context-free grammar</a>.</p>
<table>
@@ -71,7 +70,7 @@
</table>
<h2 id="syntax"><a class="header" href="#syntax">Syntax</a></h2>
<p>BQN comments are written with <code><span class='Comment'>#</span></code>, not <code><span class='Value'>⍝</span></code>. BQN strings use double quotes <code><span class='String'>&quot;&quot;</span></code> while single quotes <code><span class='String'>''</span></code> enclose a character.</p>
-<p>BQN's functions use <code><span class='Brace'>{}</span></code>, like Dyalog's dfns. The names for inputs and self-reference are different:</p>
+<p>BQN's <a href="block.html">block</a> functions use <code><span class='Brace'>{}</span></code>, like Dyalog's dfns. The names for inputs and self-reference are different:</p>
<table>
<thead>
<tr>
@@ -106,11 +105,11 @@
</tr>
</tbody>
</table>
-<p>BQN doesn't have guards: it uses modifiers or <a href="control.html">control structures</a> instead. However, BQN function and modifier blocks have headers that allow pattern matching. See the <a href="block.html">block</a> documentation.</p>
+<p>Blocks don't have guards exactly, but headers and predicates support some similar functionality (first-class functions can also be used for <a href="control.html">control structures</a>). Headers can also be used to make a block more explicit about its inputs, more like a tradfn.</p>
<p>The assignment arrow <code><span class='Gets'>←</span></code> defines a new variable in a block, while <code><span class='Gets'>↩</span></code> modifies an existing one.</p>
-<p>BQN uses the ligature character <code><span class='Ligature'>‿</span></code> for stranding, instead of plain juxtaposition. It also has a <a href="arrayrepr.html#brackets">list notation</a> using <code><span class='Bracket'>⟨⟩</span></code>.</p>
+<p>BQN uses the ligature character <code><span class='Ligature'>‿</span></code> for stranding, instead of plain juxtaposition. It also has a <a href="arrayrepr.html#brackets">list notation</a> using <code><span class='Bracket'>⟨⟩</span></code>, and <code><span class='Bracket'>[]</span></code> for higher-rank arrays.</p>
<h2 id="for-reading"><a class="header" href="#for-reading">For reading</a></h2>
-<p>Here are some closest equivalents in Dyalog APL for the BQN functions that don't use the same glyphs as APL. Correspondence can be approximate, and <code><span class='Function'>⌽</span></code> is just used as a decorator to mean &quot;reverse some things&quot;.</p>
+<p>Here are some closest equivalents in Dyalog APL for the BQN functions that don't use the same glyphs. Correspondence can be approximate, and <code><span class='Function'>⌽</span></code> is just used as a decorator to mean &quot;reverse some things&quot;.</p>
<table>
<thead>
<tr>
@@ -265,16 +264,34 @@
<td align="center"><code><span class='Modifier'>¨</span></code></td>
<td align="center"><code><span class='Modifier2'>∘</span><span class='Value'>.</span></code></td>
<td align="center"><code><span class='Value'>⌿</span></code></td>
-<td align="center"><code><span class='Value'>⍤</span></code></td>
+<td align="center"><code><span class='Value'>⍤</span><span class='Function'>A</span></code></td>
<td align="center"><code><span class='Value'>⍣</span></code></td>
<td align="center"><code><span class='Value'>⍨</span></code></td>
-<td align="center"><code><span class='Value'>⍤</span></code></td>
+<td align="center"><code><span class='Value'>⍤f</span></code></td>
<td align="center"><code><span class='Value'>⍥</span></code></td>
<td align="center"><code><span class='Modifier2'>∘</span></code></td>
</tr>
</tbody>
</table>
-<p>In BQN <code><span class='Modifier2'>⎉</span></code> is Rank and <code><span class='Modifier2'>∘</span></code> is Atop. Dyalog's Atop (<code><span class='Value'>⍤</span></code>) and Over (<code><span class='Value'>⍥</span></code>) were added in version 18.0.</p>
+<p>Some other BQN modifiers have been proposed as future Dyalog extensions:</p>
+<table>
+<thead>
+<tr>
+<th align="center">BQN</th>
+<th align="center"><code><span class='Modifier2'>⌾</span></code></th>
+<th align="center"><code><span class='Modifier2'>⚇</span></code></th>
+<th align="center"><code><span class='Modifier2'>⊸</span></code></th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td align="center">Dyalog proposed</td>
+<td align="center"><code><span class='Value'>⍢</span></code> <a href="https://aplwiki.com/wiki/Under">Under</a></td>
+<td align="center"><code><span class='Value'>⍥</span></code> Depth</td>
+<td align="center"><code><span class='Value'>⍛</span></code> <a href="https://aplwiki.com/wiki/Reverse_Compose">Reverse Compose</a></td>
+</tr>
+</tbody>
+</table>
<h2 id="for-writing"><a class="header" href="#for-writing">For writing</a></h2>
<p>The tables below give approximate implementations of Dyalog primitives for the ones that aren't the same. First- and last-axis pairs are also mostly omitted. BQN just has the first-axis form, and you can get the last-axis form with <code><span class='Modifier2'>⎉</span><span class='Number'>1</span></code>.</p>
<p>The form <code><span class='Function'>F</span><span class='Value'>⍣</span><span class='Function'>G</span></code> (Power with a function right operand; Power limit) must be implemented with recursion instead of primitives because it performs unbounded iteration. The modifier <code><span class='Modifier2'>_while_</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Function'>𝔽</span><span class='Modifier2'>⍟</span><span class='Function'>𝔾</span><span class='Modifier2'>∘</span><span class='Function'>𝔽</span><span class='Modifier2'>_𝕣_</span><span class='Function'>𝔾</span><span class='Modifier2'>∘</span><span class='Function'>𝔽</span><span class='Modifier2'>⍟</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> provides similar functionality without risk of stack overflow. It's discussed <a href="control.html#low-stack-version">here</a> and called as <code><span class='Function'>Fn</span> <span class='Modifier2'>_while_</span> <span class='Function'>Cond</span> <span class='Value'>arg</span></code>.</p>
@@ -283,7 +300,7 @@
<tr><th> Glyph </th><th> Monadic </th><th> Dyadic </th> </tr>
<tr><td> <code><span class='Value'>*</span></code> </td><td colspan=2><code><span class='Function'>⋆</span></code></td> </tr>
<tr><td> <code><span class='Modifier2'>⍟</span></code> </td><td colspan=2><code><span class='Function'>⋆</span><span class='Modifier'>⁼</span></code></td> </tr>
-<tr><td> <code><span class='Function'>!</span></code> </td><td><code><span class='Function'>×</span><span class='Modifier'>´</span><span class='Number'>1</span><span class='Function'>+↕</span></code> </td><td> <code><span class='Function'>-</span><span class='Modifier'>˜</span><span class='Paren'>(</span><span class='Function'>+÷</span><span class='Modifier2'>○</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Paren'>)</span><span class='Function'>⊢</span><span class='Paren'>)</span><span class='Number'>1</span><span class='Function'>+↕</span><span class='Modifier2'>∘</span><span class='Function'>⊣</span></code></td></tr>
+<tr><td> <code><span class='Function'>!</span></code> </td><td><code><span class='Function'>×</span><span class='Modifier'>´</span><span class='Number'>1</span><span class='Function'>+↕</span></code> </td><td> <code><span class='Paren'>(</span><span class='Function'>-÷</span><span class='Modifier2'>○</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Paren'>)</span><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Paren'>)</span><span class='Modifier2'>⟜</span><span class='Function'>↕</span><span class='Modifier'>˜</span></code></td></tr>
<tr><td> <code><span class='Modifier2'>○</span></code> </td><td> <code><span class='Number'>π</span><span class='Modifier2'>⊸</span><span class='Function'>×</span></code> </td><td> <code><span class='Value'>•math</span></code></td> </tr>
<tr><td> <code><span class='Value'>~</span></code> </td><td> <code><span class='Function'>¬</span></code> </td><td> <code><span class='Function'>¬</span><span class='Modifier2'>∘</span><span class='Function'>∊/⊣</span></code></td> </tr>
<tr><td> <code><span class='Head'>?</span></code> </td><td> <code><span class='Value'>•rand.</span><span class='Function'>Range</span><span class='Modifier2'>⚇</span><span class='Number'>0</span></code> </td><td> <code><span class='Value'>•rand.</span><span class='Function'>Deal</span></code></td></tr>
@@ -294,10 +311,10 @@
<tr><td> <code><span class='Value'>⍪</span></code> </td><td> <code><span class='Function'>⥊</span><span class='Modifier'>˘</span></code> </td><td> <code><span class='Function'>∾</span></code></td> </tr>
<tr><td> <code><span class='Function'>⌽</span></code> </td><td colspan=2><code><span class='Function'>⌽</span><span class='Modifier2'>⎉</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span></code></td> </tr>
<tr><td> <code><span class='Function'>↑</span></code> </td><td> <code><span class='Function'>></span></code> </td><td> <code><span class='Function'>↑</span></code></td> </tr>
-<tr><td> <code><span class='Function'>↓</span></code> </td><td> <code><span class='Function'><</span><span class='Modifier'>˘</span></code> </td><td> <code><span class='Function'>↑</span></code></td> </tr>
+<tr><td> <code><span class='Function'>↓</span></code> </td><td> <code><span class='Function'><</span><span class='Modifier'>˘</span></code> </td><td> <code><span class='Function'>↓</span></code></td> </tr>
<tr><td> <code><span class='Value'>⊂</span></code> </td><td> <code><span class='Function'><</span></code> </td><td> <code><span class='Function'>+</span><span class='Modifier'>`</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span></code></td> </tr>
<tr><td> <code><span class='Value'>⊆</span></code> </td><td> <code><span class='Function'><</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Number'>0</span><span class='Function'><≡</span><span class='Paren'>)</span></code> </td><td> <code><span class='Paren'>(</span><span class='Function'>¬-</span><span class='Modifier'>˜</span><span class='Function'>⊢×</span><span class='Nothing'>·</span><span class='Function'>+</span><span class='Modifier'>`</span><span class='Function'>»</span><span class='Modifier2'>⊸</span><span class='Function'>></span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span></code></td></tr>
-<tr><td> <code><span class='Function'>∊</span></code> </td><td> <code><span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>∾𝕊</span><span class='Modifier'>¨</span><span class='Paren'>)</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Number'>0</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> <code><span class='Function'>∊</span></code></td> </tr>
+<tr><td> <code><span class='Function'>∊</span></code> </td><td> <code><span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>∾𝕊</span><span class='Modifier'>¨</span><span class='Paren'>)</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Number'>0</span><span class='Function'><≡</span><span class='Paren'>)</span><span class='Function'>⥊</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> </td><td> <code><span class='Function'>∊</span></code></td> </tr>
<tr><td> <code><span class='Value'>⊃</span></code> </td><td colspan=2><code><span class='Function'>⊑</span></code></td> </tr>
<tr><td> <code><span class='Value'>⍀</span></code> </td><td> </td><td> <code><span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Value'>𝕨</span><span class='Modifier2'>⊸</span><span class='Function'>/</span><span class='Paren'>)</span><span class='Value'>𝕨</span><span class='Function'>≠</span><span class='Modifier2'>⊸</span><span class='Function'>↑</span><span class='Number'>0</span><span class='Function'>↑</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code></td></tr>
<tr><td> <code><span class='Value'>∩</span></code> </td><td> </td><td> <code><span class='Function'>∊/⊣</span></code></td> </tr>
@@ -310,8 +327,8 @@
<tr><td> <code><span class='Value'>⍎</span></code> </td><td colspan=2><code><span class='Function'>•BQN</span></code></td> </tr>
<tr><td> <code><span class='Value'>⍕</span></code> </td><td colspan=2><code><span class='Function'>•Fmt</span></code></td> </tr>
<tr><td> <code><span class='Value'>⊥</span></code> </td><td> </td><td> <code><span class='Brace'>{</span><span class='Function'>+</span><span class='Modifier2'>⟜</span><span class='Paren'>(</span><span class='Value'>𝕨</span><span class='Modifier2'>⊸</span><span class='Function'>×</span><span class='Paren'>)</span><span class='Modifier'>´</span><span class='Function'>⌽</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> </td></tr>
-<tr><td> <code><span class='Value'>⊤</span></code> </td><td> </td><td> <code><span class='Brace'>{</span><span class='Function'>></span><span class='Value'>𝕨</span><span class='Function'>|⌊</span><span class='Modifier2'>∘</span><span class='Function'>÷</span><span class='Modifier'>`</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</span><span class='Value'>𝕨</span><span class='Function'>«</span><span class='Modifier'>˜</span><span class='Function'><</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code></td></tr>
-<tr><td> <code><span class='Value'>⌹</span></code> </td><td><code><span class='Function'>Inverse</span></code> from <a href="https://github.com/mlochbaum/bqn-libs/blob/master/matrix.bqn">here</a></td><td><code><span class='Function'>Solve</span></code></td></tr>
+<tr><td> <code><span class='Value'>⊤</span></code> </td><td> </td><td> <code><span class='Brace'>{</span><span class='Value'>𝕨</span><span class='Function'>|>⌊</span><span class='Modifier2'>∘</span><span class='Function'>÷</span><span class='Modifier'>`</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</span><span class='Value'>𝕨</span><span class='Function'>«</span><span class='Modifier'>˜</span><span class='Function'><</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code></td></tr>
+<tr><td> <code><span class='Value'>⌹</span></code> </td><td><code><span class='Function'>Inverse</span></code>, </td><td> <code><span class='Function'>Solve</span></code> from <a href="https://github.com/mlochbaum/bqn-libs/blob/master/matrix.bqn">here</a></td></tr>
<tr><td> <code><span class='Value'>⌷</span></code> </td><td> N/A </td><td> <code><span class='Function'>⊏</span></code></td> </tr>
</table>
diff --git a/docs/doc/fromJ.html b/docs/doc/fromJ.html
index 338a17d5..489240d8 100644
--- a/docs/doc/fromJ.html
+++ b/docs/doc/fromJ.html
@@ -10,10 +10,10 @@
<h2 id="terminology"><a class="header" href="#terminology">Terminology</a></h2>
<h3 id="array-model"><a class="header" href="#array-model">Array model</a></h3>
<p>BQN uses the <a href="based.html">based array model</a>, which is fundamentally different from J's flat array model. BQN uses non-array values such as characters and numbers, called &quot;atoms&quot;, while in J every noun is an array. A BQN array can contain any values in any mixture, while a J array must be uniformly numbers, characters, or boxes (BQN doesn't use boxes).</p>
-<p>The J terms &quot;atom&quot; and &quot;element&quot; are used to mean different things by different authors. In BQN, an atom or rank-0 array is called a &quot;unit&quot;, and the values contained in an array—which may or may not be arrays—are called &quot;elements&quot;. Each element is contained in a 0-cell, or rank-0 subarray. BQN uses the term &quot;major cell&quot; for what J calls an &quot;item&quot; of an array: a cell with rank one less than that array. BQN shares the terms &quot;list&quot; and &quot;table&quot; for rank-1 and rank-2 arrays with J.</p>
+<p>The J terms &quot;atom&quot; and &quot;element&quot; are used to mean different things by different authors. In BQN, a rank-0 array or atom is called a &quot;unit&quot;, and the values contained in an array—which may or may not be arrays—are called &quot;elements&quot;. Each element is contained in a 0-cell, or rank-0 subarray. BQN uses the term &quot;major cell&quot; for what J calls an &quot;item&quot; of an array: a cell with rank one less than that array. BQN shares the terms &quot;list&quot; and &quot;table&quot; for rank-1 and rank-2 arrays with J.</p>
<p>BQN uses &quot;<a href="depth.html">depth</a>&quot; rather than &quot;boxing level&quot;. BQN gives atoms depth 0, so that the depth of a BQN array is one higher than the boxing level of the corresponding J array.</p>
<h3 id="roles"><a class="header" href="#roles">Roles</a></h3>
-<p>In J, the part of speech is an inherent property of a value, while in BQN it is determined by how the value is used in a particular expression, and can be different from the value's type. See <a href="context.html">context-free grammar</a>.</p>
+<p>In J, the part of speech is an inherent property of a value, while in BQN it's determined by how the value is used in a particular expression, and can be different from the value's type. See <a href="context.html">context-free grammar</a>.</p>
<table>
<thead>
<tr>
@@ -58,7 +58,7 @@
<tr>
<td><code><span class='String'>'</span></code></td>
<td><code><span class='String'>&quot;</span></code></td>
-<td><code><span class='String'>'</span></code> creates characters</td>
+<td><code><span class='String'>'</span></code> for character atoms</td>
</tr>
<tr>
<td><code><span class='Function'>=</span><span class='Value'>.</span></code> and <code><span class='Function'>=</span><span class='Head'>:</span></code></td>
@@ -107,7 +107,7 @@
</tr>
</tbody>
</table>
-<p>BQN's explicit functions and modifiers are called &quot;blocks&quot;, and have a more sophisticated syntax than J; see <a href="block.html">the documentation</a>. BQN uses <a href="lexical.html">lexical scope</a>, and has no global variables. BQN also has a <a href="arrayrepr.html#brackets">list notation</a> using <code><span class='Bracket'>⟨⟩</span></code>.</p>
+<p>BQN's explicit functions and modifiers are called <a href="block.html">blocks</a>, and have a more sophisticated syntax than J. BQN uses <a href="lexical.html">lexical scope</a>, and has no global variables. BQN also has a <a href="arrayrepr.html#brackets">list notation</a> using <code><span class='Bracket'>⟨⟩</span></code>, and <code><span class='Bracket'>[]</span></code> for higher-rank arrays.</p>
<h2 id="for-reading"><a class="header" href="#for-reading">For reading</a></h2>
<p>J analogues of BQN primitive functions are given below. They are not always the same; usually this is because BQN has extra functionality relative to J, although in some cases it has less or different functionality.</p>
<p>Functions <code><span class='Function'>+</span></code> <code><span class='Function'>-</span></code> <code><span class='Function'>|</span></code> <code><span class='Function'>&lt;</span></code> <code><span class='Function'>&gt;</span></code> are the same in both languages.</p>
@@ -485,8 +485,8 @@
</tr>
<tr>
<td><code><span class='Value'>%.</span></code></td>
-<td><code><span class='Function'>Inverse</span></code> from <a href="https://github.com/mlochbaum/bqn-libs/blob/master/matrix.bqn">here</a></td>
-<td><code><span class='Function'>Solve</span></code></td>
+<td><code><span class='Function'>Inverse</span></code>,</td>
+<td><code><span class='Function'>Solve</span></code> from <a href="https://github.com/mlochbaum/bqn-libs/blob/master/matrix.bqn">here</a></td>
</tr>
<tr>
<td><code><span class='Value'>$</span></code></td>
@@ -516,7 +516,7 @@
<tr>
<td><code><span class='Separator'>,</span><span class='Head'>:</span></code></td>
<td><code><span class='Function'>≍</span></code></td>
-<td></td>
+<td><code><span class='Function'>≍</span></code></td>
</tr>
<tr>
<td><code><span class='Head'>;</span></code></td>
@@ -541,7 +541,7 @@
<tr>
<td><code><span class='Function'>!</span></code></td>
<td><code><span class='Function'>×</span><span class='Modifier'>´</span><span class='Number'>1</span><span class='Function'>+↕</span></code></td>
-<td><code><span class='Function'>-</span><span class='Modifier'>˜</span><span class='Paren'>(</span><span class='Function'>+÷</span><span class='Modifier2'>○</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Paren'>)</span><span class='Function'>⊢</span><span class='Paren'>)</span><span class='Number'>1</span><span class='Function'>+↕</span><span class='Modifier2'>∘</span><span class='Function'>⊣</span></code></td>
+<td><code><span class='Paren'>(</span><span class='Function'>-÷</span><span class='Modifier2'>○</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Paren'>)</span><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Paren'>)</span><span class='Modifier2'>⟜</span><span class='Function'>↕</span><span class='Modifier'>˜</span></code></td>
</tr>
<tr>
<td><code><span class='Function'>/</span><span class='Head'>:</span></code></td>
diff --git a/docs/doc/functional.html b/docs/doc/functional.html
index d7fbad61..ea4d18ca 100644
--- a/docs/doc/functional.html
+++ b/docs/doc/functional.html
@@ -6,8 +6,8 @@
<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="functional-programming"><a class="header" href="#functional-programming">Functional programming</a></h1>
<p>BQN boasts of its functional capabilities, including first-class functions. What sort of functional support does it have, and how can a BQN programmer exercise these and out themself as a Schemer at heart?</p>
-<p>First, let's be clear about what the terms we're using mean. A language has <em>first-class functions</em> when functions (however they are defined) can be used in all the same ways as &quot;ordinary&quot; values like numbers and so on, such as being passed as an argument or placed in a list. Lisp and JavaScript have first-class functions, C has unsafe first-class functions via function pointers, and Java 7 and APL don't have them as functions can't be placed in lists or used as arguments. This doesn't mean every operation is supported on functions: for instance, numbers can be added, compared, and sorted; while functions could perhaps be added to give a train, comparing or sorting them as functions (not representations) isn't computable, and BQN doesn't support any of the three operations when passing functions as arguments.</p>
-<p>Traditionally, APL has worked around its lack of first-class functions with operators, that is, second-order functions. Arrays in APL are first class while functions are second class and operators are third class, and each class can act on the ones before it. However, the three-tier system has some obvious limitations that we'll discuss, and BQN removes these by making every type first class.</p>
+<p>First, let's be clear about what the terms we're using mean. A language has <em>first-class functions</em> when functions (however they are defined) can be used in all the same ways as &quot;ordinary&quot; values like numbers and so on, such as being passed as an argument or placed in a list. Lisp and JavaScript have first-class functions, and C has unsafe first-class functions via function pointers. Java 7 and APL don't have them, as functions can't be placed in lists or used as arguments. This doesn't mean every operation is supported on functions: for instance, numbers can be added, compared, and sorted; while functions could perhaps be added to give a train, comparing or sorting them as functions (not representations) isn't computable, and BQN doesn't support any of the three operations when passing functions as arguments.</p>
+<p>Traditionally, APL has worked around its lack of first-class functions with operators, that is, second-order functions. Arrays in APL are first class while functions are second class and operators are third class, and each class can act on the ones above it. However, the three-tier system has some obvious limitations that we'll discuss, and BQN removes these by making every type first class.</p>
<svg viewBox='0 0 512 512'>
<g font-size='18px' text-anchor='middle' fill='currentColor'>
<text font-size='24' x='256' y='38'>"Functional programming"</text>
@@ -59,8 +59,8 @@
</g>
</svg>
-<p>The term <em>functional programming</em> is more contentious, and has many meanings some of which can be vague. Here I use it for what might be called <em>first-class functional programming</em>, programming that makes significant use of first-class functions; in this usage, Scheme is probably the archetypal functional programming language. However, other definitions are also worth mentioning. APL is often called a functional programming language on the grounds that functions can be assigned and manipulated, and called recursively, all characteristics it shares with Lisp. I prefer the term <em>function-level programming</em> for this usage. A newer usage, which I call <em>pure functional programming</em>, restricts the term &quot;function&quot; to mathematical functions, which have no side effects, so that functional programming is programming with no side effects, often using monads to accumulate effects as part of arguments and results instead. Finally, <em>typed functional programming</em> is closely associated with pure functional programming and refers to languages influenced by type theory such as <a href="https://www.haskell.org/">Haskell</a>, <a href="https://fsharp.org/">F#</a>, and <a href="https://www.idris-lang.org/">Idris</a> (the last of which even supports <em><a href="https://en.wikipedia.org/wiki/Dependent_type">dependently-typed</a> functional programming</em>, but I already said &quot;finally&quot; so we'll stop there). Of these, BQN supports first-class functional and function-level programming, allows but doesn't encourage pure functional programming, and does not support typed functional programming, as it's dynamically and not statically typed.</p>
-<p>Another topic we are interested in is <em>lexical scoping</em> and <em>closures</em>. <a href="lexical.html">Lexical scoping</a> means that the realm in which a variable exists is determined by its containing context (in BQN, the surrounding set of curly braces <code><span class='Brace'>{}</span></code>, if any) within the source code. A closure is really an implementation mechanism, but it's often used to refer to a property of lexical scoping that appears when functions defined in a particular block can be accessed after the block finishes execution. For example, they might be returned from a function or assigned to a variable outside of that function's scope. In this case the functions can still access variables in the original scope. I consider this property to be a requirement for a correct lexical scoping implementation, but it's traditionally not a part of APL: implementation might not have lexical scoping (for example, J and I believe <a href="https://aplwiki.com/wiki/A+">A+</a> use static scoping where functions can't access variables in containing scopes) or might cut off the scope once execution ends, leading to value errors that one wouldn't predict from the rules of lexical scoping.</p>
+<p>The term <em>functional programming</em> is more contentious, and has many meanings some of which can be vague. Here I use it for what might be called <em>first-class functional programming</em>, programming that makes significant use of first-class functions; in this usage, Scheme is probably the archetypal functional programming language. However, other definitions are also worth mentioning. APL is often called a functional programming language on the grounds that functions can be assigned and manipulated, and called recursively, all characteristics it shares with Lisp. I prefer the term <em>function-level programming</em> for this usage. A newer usage, which I call <em>pure functional programming</em>, restricts the term &quot;function&quot; to mathematical functions, which have no side effects, so that functional programming is programming with no side effects, often using monads to accumulate effects as part of arguments and results instead. Finally, <em>typed functional programming</em> is closely associated with pure functional programming and refers to languages influenced by type theory such as <a href="https://www.haskell.org/">Haskell</a>, <a href="https://fsharp.org/">F#</a>, and <a href="https://www.idris-lang.org/">Idris</a> (the last of which even supports <em><a href="https://en.wikipedia.org/wiki/Dependent_type">dependently-typed</a> functional programming</em>, but I already said &quot;finally&quot; so we'll stop there). Of these, BQN supports first-class functional and function-level programming, allows but doesn't encourage pure functional programming, and doesn't support typed functional programming, as it's dynamically and not statically typed.</p>
+<p>Another topic we're interested in is <em>lexical scoping</em> and <em>closures</em>. <a href="lexical.html">Lexical scoping</a> means that the realm in which a variable exists is determined by its containing context (in BQN, the surrounding set of curly braces <code><span class='Brace'>{}</span></code>, if any) within the source code. A closure is really an implementation mechanism, but it's often used to refer to a property of lexical scoping that appears when functions defined in a particular block can be accessed after the block finishes execution. For example, they might be returned from a function or assigned to a variable outside of that function's scope. In this case the functions can still access variables in the original scope. I consider this property to be a requirement for a correct lexical scoping implementation, but it's traditionally not a part of APL: implementation might not have lexical scoping (for example, J and K use static scoping where functions can't access variables in containing scopes) or might cut off the scope once execution ends, leading to value errors that one wouldn't predict from the rules of lexical scoping.</p>
<h2 id="functions-in-apl"><a class="header" href="#functions-in-apl">Functions in APL</a></h2>
<p>This seems like a good place for a brief and entirely optional discussion of how APL handles functions and why it does it this way. As mentioned above, APL's functions are second class rather than first class. But the barriers to making functions first-class objects have been entirely syntactic and conceptual, not technical. In fact, the J language has for a long time had <a href="http://www.jsoftware.com/pipermail/programming/2013-January/031260.html">a bug</a> that allows an array containing a function to be created: by selecting from the array, the function itself can even be passed through tacit functions as an argument!</p>
<p>The primary reason why APL doesn't allow functions to be passed as arguments is probably syntax: in particular, there's no way to say that a function should be used as the left argument to another function, as an expression like <code><span class='Function'>F</span> <span class='Function'>G</span> <span class='Value'>x</span></code> with functions <code><span class='Function'>F</span></code> and <code><span class='Function'>G</span></code> and an array <code><span class='Value'>x</span></code> will simply be evaluated as two monadic function applications. However, there's no syntactic rule that prevents a function from returning a function, and Dyalog APL for example allows this (so <code><span class='Value'>⍎</span><span class='String'>'+'</span></code> returns the function <code><span class='Function'>+</span></code>). Dyalog's <code><span class='Value'>⎕</span><span class='Function'>OR</span></code> is another interesting phenomenon in this context: it creates an array from a function or operator, which can then be used as an element or argument like any array. The mechanism is essentially the same as BQN's first class functions, and in fact <code><span class='Value'>⎕</span><span class='Function'>OR</span></code>s even share a form of BQN's <a href="../commentary/problems.html#syntactic-type-erasure">syntactic type erasure</a>, as a <code><span class='Value'>⎕</span><span class='Function'>OR</span></code> of a function passed as an operand magically becomes a function again. But outside of this property, it's cumbersome and slow to convert functions to and from <code><span class='Value'>⎕</span><span class='Function'>OR</span></code>s, so they don't work very well as a first-class function mechanism.</p>
@@ -86,7 +86,7 @@
<span class='Function'>ExpLin</span> <span class='Number'>5</span>
9.591409142295225
</pre>
-<p>A tricker but more compact method is to use the 1-modifier <code><span class='Brace'>{</span><span class='Function'>𝔽</span><span class='Brace'>}</span></code>, as the input to a modifier can have a subject or function role but its output always has a function role.</p>
+<p>A tricker but more compact method is to use the 1-modifier <code><span class='Brace'>{</span><span class='Function'>𝔽</span><span class='Brace'>}</span></code>, as a modifier's operand can have a subject or function role but its output always has a function role.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KExpbiBleHApe/CdlL19IDU=">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>Lin</span> <span class='Value'>exp</span><span class='Paren'>)</span><span class='Brace'>{</span><span class='Function'>𝔽</span><span class='Brace'>}</span> <span class='Number'>5</span>
9.591409142295225
</pre>
@@ -119,7 +119,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+o4oiaLCAy4oq44omNLCDiiqIt4ouG4p+pIHvwnZWO8J2VqX3CqCA5">↗️</a><pre> <span class='Bracket'>⟨</span><span class='Function'>√</span><span class='Separator'>,</span> <span class='Number'>2</span><span class='Modifier2'>⊸</span><span class='Function'>≍</span><span class='Separator'>,</span> <span class='Function'>⊢-⋆</span><span class='Bracket'>⟩</span> <span class='Brace'>{</span><span class='Function'>𝕎</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier'>¨</span> <span class='Number'>9</span>
⟨ 3 ⟨ 2 9 ⟩ ¯8094.083927575384 ⟩
</pre>
-<p>The 2-modifier Choose (<code><span class='Modifier2'>◶</span></code>) relies on arrays of functions to… function. It's very closely related to Pick <code><span class='Function'>⊑</span></code>, and in fact when the left operand and the elements of the right operand are all data there's no real difference: Choose returns the constant function <code><span class='Value'>𝕗</span><span class='Function'>⊑</span><span class='Value'>𝕘</span></code>.</p>
+<p>The 2-modifier <a href="choose.html">Choose</a> (<code><span class='Modifier2'>◶</span></code>) relies on arrays of functions to… function. It's very closely related to <a href="pick.html">Pick</a> <code><span class='Function'>⊑</span></code>, and in fact when the left operand and the elements of the right operand are all data there's no real difference: Choose results in the constant function <code><span class='Value'>𝕗</span><span class='Function'>⊑</span><span class='Value'>𝕘</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MuKXtiJhYmNkZWYiICJhcmci">↗️</a><pre> <span class='Number'>2</span><span class='Modifier2'>◶</span><span class='String'>&quot;abcdef&quot;</span> <span class='String'>&quot;arg&quot;</span>
'c'
</pre>
diff --git a/docs/doc/glossary.html b/docs/doc/glossary.html
index 13581749..3588a8d8 100644
--- a/docs/doc/glossary.html
+++ b/docs/doc/glossary.html
@@ -37,34 +37,23 @@
<li><strong>Real number</strong> (more accurately, approximate doubly-extended real number): A number with no complex part.</li>
<li><strong>Complex number</strong>: A real number plus <em>i</em> (one of the square roots of -1) times another real number.</li>
</ul>
-<h2 id="roles"><a class="header" href="#roles">Roles</a></h2>
-<ul>
-<li><a href="expression.html#syntactic-role"><strong>Syntactic role</strong></a>: One of four possible types for an expression, which are determined by the expression itself and not outside context and describe how it interacts with other parts of the syntax.</li>
-</ul>
-<p>The possible roles are:</p>
-<ul>
-<li><strong>Subject</strong>: Can be passed to a function or modifier.</li>
-<li><strong>Function</strong>: Can be called on subjects or passed to a modifier.</li>
-<li><strong>1-modifier</strong>: Can be called on one subject or function.</li>
-<li><strong>2-modifier</strong>: Can be called on two subjects or functions.</li>
-</ul>
<h2 id="arrays"><a class="header" href="#arrays">Arrays</a></h2>
<ul>
<li><a href="array.html"><strong>Array</strong></a>: A multidimensional collection of values.</li>
<li><a href="array.html#elements"><strong>Element</strong></a>: One of the values contained in an array.</li>
<li><a href="array.html#rectangles"><strong>Axis</strong></a>: One dimension or direction in an array.</li>
<li><a href="array.html#dimensions"><strong>Rank</strong></a>: The number of dimensions an array has.</li>
-<li><a href="shape.html"><strong>Shape</strong></a>: The number of elements an array has along each dimension.</li>
-<li><a href="shape.html"><strong>Length</strong></a>: The number of elements an array has along the first dimension, or 1 if it has rank 0.</li>
+<li><a href="shape.html"><strong>Shape</strong></a>: The number of positions an array has along each dimension.</li>
+<li><a href="shape.html"><strong>Length</strong></a>: The number of positions an array has along the first dimension, or 1 if it has rank 0.</li>
<li><a href="depth.html"><strong>Depth</strong></a>: The greatest number of times an element can be selected from a value before reaching an atom.</li>
<li><a href="fill.html"><strong>Fill</strong></a>: A &quot;prototypical&quot; array element used in certain operations; it's an inferred property of an array.</li>
</ul>
<ul>
-<li><strong>Empty</strong>: Having no elements. An array is empty if its shape contains 0.</li>
-<li><a href="array.html#cells"><strong>Cell</strong></a>: An array containing all elements of the original array whose indices share a particular prefix.</li>
+<li><a href="array.html#elements"><strong>Empty</strong></a>: Having no elements. An array is empty if its shape contains 0.</li>
+<li><a href="array.html#cells"><strong>Cell</strong></a>: An array selected from a larger array, containing all elements whose indices share a particular prefix.</li>
<li><a href="array.html#cells"><strong>k-Cell</strong></a>: A cell of rank <em>k</em>.</li>
<li><a href="array.html#cells"><strong>Major cell</strong></a>: A cell with rank one less than the original array.</li>
-<li><a href="leading.html#leading-axis-agreement"><strong>Agreement</strong></a>: The way elements are paired when a function maps over two arrays.</li>
+<li><a href="leading.html#leading-axis-agreement"><strong>Agreement</strong></a>: The way elements are paired when mapping over two arrays together (for example by Each).</li>
<li><a href="rank.html#frame-and-cells"><strong>Frame</strong></a>: A prefix of an array's shape, used for agreement with the Rank modifier.</li>
</ul>
<ul>
@@ -102,15 +91,6 @@
<li><strong>Error</strong>: A condition that stops compilation or execution (see <a href="assert.html">assert</a>).</li>
<li><strong>Inferred property</strong>: A property of a value that is derived by BQN based on constraints. If it can't be derived then the value won't have the property. Includes identity values, fill elements, and behavior of Undo and Under.</li>
</ul>
-<h2 id="namespaces"><a class="header" href="#namespaces">Namespaces</a></h2>
-<ul>
-<li><a href="namespace.html"><strong>Namespace</strong></a>: A container for variables, some of which are exposed as fields.</li>
-<li><strong>Field</strong>: One of the variables accessible from outside a namespace.</li>
-<li><strong>Access</strong>: To get the current value of a field from a namespace.</li>
-<li><a href="namespace.html#exports"><strong>Export</strong></a>: Declare a variable to be accessible from the outside, that is, make it a field.</li>
-<li><a href="oop.html"><strong>Object</strong></a>: Informal term for a namespace that holds mutable state.</li>
-<li><a href="namespace.html#imports"><strong>Alias</strong></a>: A different &quot;outside&quot; name chosen for a field in a destructuring assignment.</li>
-</ul>
<h2 id="tokens"><a class="header" href="#tokens">Tokens</a></h2>
<ul>
<li><strong>Token formation</strong> or tokenization: Splitting source code into a sequence of tokens.</li>
@@ -124,14 +104,25 @@
<li><a href="syntax.html#constants"><strong>Character literal</strong></a>: A literal written with single quotes <code><span class='String'>''</span></code>, indicating a string.</li>
<li><a href="syntax.html#constants"><strong>Null literal</strong></a>: The literal <code><span class='String'>@</span></code>, indicating the null character (code point 0).</li>
</ul>
-<h2 id="parsing"><a class="header" href="#parsing">Parsing</a></h2>
+<h2 id="grammar"><a class="header" href="#grammar">Grammar</a></h2>
<ul>
-<li><strong>Parsing</strong>: Analysis of the tokens of a program, which determines which actions will be taken to evaluate it.</li>
-<li><a href="syntax.html#expressions"><strong>Expression</strong></a>: A piece of code that defines a (not necessarily constant) variable.</li>
+<li><a href="syntax.html#expressions"><strong>Expression</strong></a>: A piece of code that describes the computation of a value.</li>
<li><a href="expression.html#nothing"><strong>Nothing</strong></a>: A special value-like entity that comes from <code><span class='Nothing'>·</span></code>, <code><span class='Value'>𝕨</span></code> in a function with no left argument, or a function called on nothing.</li>
<li><strong>Statement</strong>: An expression, nothing (<code><span class='Nothing'>·</span></code>), or an export (<code><span class='Value'>var</span><span class='Gets'>⇐</span></code>).</li>
<li><a href="arrayrepr.html#strands"><strong>Ligature</strong></a>: The character <code><span class='Ligature'>‿</span></code>.</li>
<li><a href="arrayrepr.html#brackets"><strong>List notation</strong></a>: The angle brackets <code><span class='Bracket'>⟨⟩</span></code> or ligatures used to indicate a list.</li>
+<li><a href="arrayrepr.html#high-rank-arrays"><strong>Array notation</strong></a>: The square brackets <code><span class='Bracket'>[]</span></code> used to form high-rank arrays.</li>
+</ul>
+<h3 id="roles"><a class="header" href="#roles">Roles</a></h3>
+<ul>
+<li><a href="expression.html#syntactic-role"><strong>Syntactic role</strong></a>: One of four possible types for an expression, which are determined by the text of the expression, not outside context. The role describes how it interacts with other parts of the syntax.</li>
+</ul>
+<p>The possible roles are:</p>
+<ul>
+<li><strong>Subject</strong>: Can be passed to a function or modifier.</li>
+<li><strong>Function</strong>: Can be called on subjects or passed to a modifier.</li>
+<li><strong>1-modifier</strong>: Can be called on one subject or function.</li>
+<li><strong>2-modifier</strong>: Can be called on two subjects or functions.</li>
</ul>
<h2 id="assignment-and-scoping"><a class="header" href="#assignment-and-scoping">Assignment and scoping</a></h2>
<ul>
@@ -147,7 +138,7 @@
<h2 id="blocks"><a class="header" href="#blocks">Blocks</a></h2>
<ul>
<li><a href="block.html"><strong>Block</strong></a>: A syntactic element surrounded in curly braces <code><span class='Brace'>{}</span></code>, which encapsulates code.</li>
-<li><a href="block.html#headerless-blocks"><strong>Immediate block</strong></a>: A block that is evaluated and returns a value immediately; it has a subject role.</li>
+<li><a href="block.html#headerless-blocks"><strong>Immediate block</strong></a>: A block that's evaluated giving a result immediately; it has a subject role.</li>
<li><strong>Block function</strong>: A block defining a function.</li>
<li><strong>Block modifier</strong>: A block defining a 1- or 2-modifier.</li>
<li><a href="block.html#operands"><strong>Immediate modifier</strong></a>: A modifier that's evaluated as soon as it receives its operands.</li>
@@ -158,3 +149,12 @@
<li><a href="block.html#predicates"><strong>Predicate</strong></a>: An expression followed by <code><span class='Head'>?</span></code>, which acts as a condition for the body to continue running.</li>
<li><a href="tacit.html"><strong>Tacit</strong></a>: Code that defines functions without using blocks.</li>
</ul>
+<h2 id="namespaces"><a class="header" href="#namespaces">Namespaces</a></h2>
+<ul>
+<li><a href="namespace.html"><strong>Namespace</strong></a>: A container for variables, some of which are exposed as fields.</li>
+<li><strong>Field</strong>: One of the variables accessible from outside a namespace.</li>
+<li><strong>Access</strong>: To get the current value of a field from a namespace.</li>
+<li><a href="namespace.html#exports"><strong>Export</strong></a>: Declare a variable to be accessible from the outside, that is, make it a field.</li>
+<li><a href="oop.html"><strong>Object</strong></a>: Informal term for a namespace that holds mutable state.</li>
+<li><a href="namespace.html#imports"><strong>Alias</strong></a>: A different &quot;outside&quot; name chosen for a field in a destructuring assignment.</li>
+</ul>
diff --git a/docs/doc/group.html b/docs/doc/group.html
index a79305cc..d9b16bb2 100644
--- a/docs/doc/group.html
+++ b/docs/doc/group.html
@@ -5,7 +5,6 @@
</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="group"><a class="header" href="#group">Group</a></h1>
-<p>BQN replaces the Key operator from J or Dyalog APL, and <a href="https://aplwiki.com/wiki/Partition_representations">many forms of partitioning</a>, with a single (ambivalent) Group function <code><span class='Function'>⊔</span></code>. This function is somewhat related to the K function <code><span class='Function'>=</span></code> of the same name, but results in an array rather than a dictionary.</p>
<svg viewBox='-344 -121.8 640 226.8'>
<g text-anchor='middle' font-family='BQN,monospace'>
<rect class='code' stroke-width='1' rx='12' x='-280' y='-102.2' width='512' height='204.4'/>
@@ -29,8 +28,10 @@
</g>
</svg>
+<p>The dyadic Group function places values into its result based on indices that tell where each should go. It's a little like a backwards version of <a href="select.html">Select</a>, but because any number of indices can point to the same place, result elements are groups, not single values from the argument.</p>
+<p>Group replaces the Key operator from J or Dyalog APL, and <a href="https://aplwiki.com/wiki/Partition_representations">many forms of partitioning</a>. It's related to the K function <code><span class='Function'>=</span></code> of the same name, but results in an array rather than a dictionary.</p>
<h2 id="definition"><a class="header" href="#definition">Definition</a></h2>
-<p>Group operates on a list of atomic-number <a href="indices.html">indices</a> <code><span class='Value'>𝕨</span></code> and an array <code><span class='Value'>𝕩</span></code>, treated as a list of its major cells, to produce a list of groups, each containing some of the cells from <code><span class='Value'>𝕩</span></code>. The two arguments have the same length, and each cell in <code><span class='Value'>𝕩</span></code> is paired with the index in <code><span class='Value'>𝕨</span></code> at the same position, which indicates which result group should include that cell.</p>
+<p>Group operates on a list of atomic-number <a href="indices.html">indices</a> <code><span class='Value'>𝕨</span></code> and an array <code><span class='Value'>𝕩</span></code>, treated as a list of its <a href="array.html#cells">major cells</a>, to produce a list of groups, each containing some of the cells from <code><span class='Value'>𝕩</span></code>. The two arguments have the same length, and each cell in <code><span class='Value'>𝕩</span></code> is paired with the index in <code><span class='Value'>𝕨</span></code> at the same position, to indicate which result group should include that cell.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MOKAvzHigL8y4oC/MOKAvzEg4omNICJhYmNkZSIgICMgQ29ycmVzcG9uZGluZyBpbmRpY2VzIGFuZCB2YWx1ZXMKCjDigL8x4oC/MuKAvzDigL8xIOKKlCAiYWJjZGUiICAjIFZhbHVlcyBncm91cGVkIGJ5IGluZGV4">↗️</a><pre> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span> <span class='Function'>≍</span> <span class='String'>&quot;abcde&quot;</span> <span class='Comment'># Corresponding indices and values
</span>┌─
╵ 0 1 2 0 1
@@ -41,13 +42,13 @@
</span>⟨ "ad" "be" "c" ⟩
</pre>
<p>A few extra options can be useful in some circumstances. First, an &quot;index&quot; of <code><span class='Number'>¯1</span></code> in <code><span class='Value'>𝕨</span></code> indicates that the corresponding cell should be dropped and not appear in the result. Second, <code><span class='Value'>𝕨</span></code> is allowed to have an extra element after the end, which gives a minimum length for the result: otherwise, the result will be just long enough to accomodate the highest index in <code><span class='Value'>𝕨</span></code> (it might seem like the last element should be treated like an index, making the minimum length one higher, but the length version usually leads to simpler arithmetic).</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MOKAv8KvMeKAvzLigL8y4oC/wq8xIOKKlCAiYWJjZGUiICAjIERyb3AgYyBhbmQgZQoKMOKAvzHigL8y4oC/MuKAvzHigL82IOKKlCAiYWJjZGUiICAjIExlbmd0aC02IHJlc3VsdA==">↗️</a><pre> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>¯1</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>¯1</span> <span class='Function'>⊔</span> <span class='String'>&quot;abcde&quot;</span> <span class='Comment'># Drop c and e
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MOKAv8KvMeKAvzLigL8y4oC/wq8xIOKKlCAiYWJjZGUiICAjIERyb3AgYiBhbmQgZQoKMOKAvzHigL8y4oC/MuKAvzHigL82IOKKlCAiYWJjZGUiICAjIExlbmd0aC02IHJlc3VsdA==">↗️</a><pre> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>¯1</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>¯1</span> <span class='Function'>⊔</span> <span class='String'>&quot;abcde&quot;</span> <span class='Comment'># Drop b and e
</span>⟨ "a" ⟨⟩ "cd" ⟩
<span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>6</span> <span class='Function'>⊔</span> <span class='String'>&quot;abcde&quot;</span> <span class='Comment'># Length-6 result
</span>⟨ "a" "be" "cd" ⟨⟩ ⟨⟩ ⟨⟩ ⟩
</pre>
-<p>A third extension is that <code><span class='Value'>𝕨</span></code> doesn't really have to be a list: if not, then it groups <code><span class='Function'>-=</span><span class='Value'>𝕨</span></code>-cells of <code><span class='Value'>𝕩</span></code> instead of just <code><span class='Number'>¯1</span></code>-cells. These cells are placed in index order. This extension isn't compatible with the second option from above, because it's usually not possible to add just one extra element to a non-list array. One usage is to group the diagonals of a table. See if you can figure out how the code below does this.</p>
+<p>A third extension is that <code><span class='Value'>𝕨</span></code> doesn't really have to be a list: if not, then it groups <code><span class='Function'>-=</span><span class='Value'>𝕨</span></code>-cells of <code><span class='Value'>𝕩</span></code> instead of just <code><span class='Number'>¯1</span></code>-cells. These cells are placed in index order. This extension isn't compatible with the second option from above, because it's usually not possible to add just one extra element to a non-list array. One usage is to group the diagonals of a table. See if you can find how the code below does this.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGEg4oaQICdhJyvipYrin5wo4oaVw5fCtCkz4oC/NQoKKCvijJzCtMK34oaVwqjiiaIp4oq44oqUIGE=">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='String'>'a'</span><span class='Function'>+⥊</span><span class='Modifier2'>⟜</span><span class='Paren'>(</span><span class='Function'>↕×</span><span class='Modifier'>´</span><span class='Paren'>)</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>5</span>
┌─
╵"abcde
@@ -59,9 +60,9 @@
⟨ "a" "bf" "cgk" "dhl" "eim" "jn" "o" ⟩
</pre>
<p>For a concrete example, we might choose to group a list of words by length. Within each group, cells maintain the ordering they had in the list originally.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=cGhyYXNlIOKGkCAiQlFOIuKAvyJ1c2VzIuKAvyJub3RhdGlvbiLigL8iYXMi4oC/ImEi4oC/InRvb2wi4oC/Im9mIuKAvyJ0aG91Z2h0IgriiY3LmCDiiaDCqOKKuOKKlCBwaHJhc2U=">↗️</a><pre> <span class='Value'>phrase</span> <span class='Gets'>←</span> <span class='String'>&quot;BQN&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;uses&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;notation&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;as&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;a&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;tool&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;of&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;thought&quot;</span>
- <span class='Function'>≍</span><span class='Modifier'>˘</span> <span class='Function'>≠</span><span class='Modifier'>¨</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span> <span class='Value'>phrase</span>
-┌─
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=cGhyYXNlIOKGkCAiQlFOIuKAvyJ1c2VzIuKAvyJub3RhdGlvbiLigL8iYXMi4oC/ImEi4oC/InRvb2wi4oC/Im9mIuKAvyJ0aG91Z2h0IgriiY3LmCDiiaDCqOKKuOKKlCBwaHJhc2UgICAjIOKJjcuYIHRvIGZvcm1hdCB2ZXJ0aWNhbGx5">↗️</a><pre> <span class='Value'>phrase</span> <span class='Gets'>←</span> <span class='String'>&quot;BQN&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;uses&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;notation&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;as&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;a&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;tool&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;of&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;thought&quot;</span>
+ <span class='Function'>≍</span><span class='Modifier'>˘</span> <span class='Function'>≠</span><span class='Modifier'>¨</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span> <span class='Value'>phrase</span> <span class='Comment'># ≍˘ to format vertically
+</span>┌─
╵ ⟨⟩
⟨ "a" ⟩
⟨ "as" "of" ⟩
@@ -109,7 +110,7 @@
<p>Here, the index 2 appears at indices 0 and 3 while the index 3 appears at index 1.</p>
<p>But <code><span class='Value'>𝕩</span></code> can also be a list of numeric arrays. In this case the indices <code><span class='Function'>↕∾≢</span><span class='Modifier'>¨</span><span class='Value'>𝕩</span></code> will be grouped by <code><span class='Value'>𝕩</span></code> according to the multidimensional grouping documented in the next section. Since the argument to <a href="range.html">Range</a> (<code><span class='Function'>↕</span></code>) is now a list, each index to be grouped is a list instead of a number. As with <code><span class='Function'>↕</span></code>, the depth of the result of Group Indices is always one greater than that of its argument. One consequence is that for an array <code><span class='Value'>a</span></code> of any rank, <code><span class='Function'>⊔⋈</span><span class='Value'>a</span></code> groups the indices <code><span class='Function'>↕≢</span><span class='Value'>a</span></code>.</p>
<h3 id="multidimensional-grouping"><a class="header" href="#multidimensional-grouping">Multidimensional grouping</a></h3>
-<p>Dyadic Group allows the right argument to be grouped along multiple axes by using a nested left argument. In this case, the left argument must be a list of numeric lists, and the result has rank <code><span class='Function'>≠</span><span class='Value'>𝕨</span></code> while its elements—as always—have the same rank as <code><span class='Value'>𝕩</span></code>. The result shape is <code><span class='Number'>1</span><span class='Function'>+⌈</span><span class='Modifier'>´¨</span><span class='Value'>𝕨</span></code>, while the shape of element <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>𝕨</span><span class='Function'>⊔</span><span class='Value'>𝕩</span></code> is <code><span class='Value'>i</span><span class='Function'>+</span><span class='Modifier'>´</span><span class='Modifier2'>∘</span><span class='Function'>=</span><span class='Modifier'>¨</span><span class='Value'>𝕨</span></code>. If every element of <code><span class='Value'>𝕨</span></code> is sorted ascending and contains only non-negative numbers, we have <code><span class='Value'>𝕩</span><span class='Function'>≡∾</span><span class='Value'>𝕨</span><span class='Function'>⊔</span><span class='Value'>𝕩</span></code>, that is, <a href="join.html#join">Join</a> is the inverse of Partition.</p>
+<p>Dyadic Group allows the right argument to be grouped along multiple axes by using a nested left argument. In this case, <code><span class='Value'>𝕨</span></code> must be a list of numeric lists, and the result has rank <code><span class='Function'>≠</span><span class='Value'>𝕨</span></code> while its elements—as always—have the same rank as <code><span class='Value'>𝕩</span></code>. The result shape is <code><span class='Number'>1</span><span class='Function'>+⌈</span><span class='Modifier'>´¨</span><span class='Value'>𝕨</span></code>, while the shape of element <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>𝕨</span><span class='Function'>⊔</span><span class='Value'>𝕩</span></code> is <code><span class='Value'>i</span><span class='Function'>+</span><span class='Modifier'>´</span><span class='Modifier2'>∘</span><span class='Function'>=</span><span class='Modifier'>¨</span><span class='Value'>𝕨</span></code>. If every element of <code><span class='Value'>𝕨</span></code> is sorted ascending and has no ¯1s, we have <code><span class='Value'>𝕩</span><span class='Function'>≡∾</span><span class='Value'>𝕨</span><span class='Function'>⊔</span><span class='Value'>𝕩</span></code>, that is, <a href="join.html#join">Join</a> is the inverse of partitioning.</p>
<p>Here we split up a rank-2 array into a rank-2 array of rank-2 arrays. Along the first axis we simply separate the first pair and second pair of rows—a partition. Along the second axis we separate odd from even indices.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oMOKAvzDigL8x4oC/MSww4oC/MeKAvzDigL8x4oC/MOKAvzHigL8w4p+pIOKKlCAoMTDDl+KGlTQpK+KMnOKGlTc=">↗️</a><pre> <span class='Bracket'>⟨</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Bracket'>⟩</span> <span class='Function'>⊔</span> <span class='Paren'>(</span><span class='Number'>10</span><span class='Function'>×↕</span><span class='Number'>4</span><span class='Paren'>)</span><span class='Function'>+</span><span class='Modifier'>⌜</span><span class='Function'>↕</span><span class='Number'>7</span>
┌─
@@ -123,27 +124,9 @@
┘ ┘
</pre>
-<p>Each group <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>𝕨</span><span class='Function'>⊔</span><span class='Value'>𝕩</span></code> is composed of the cells <code><span class='Value'>j</span><span class='Function'>&lt;</span><span class='Modifier'>¨</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> such that <code><span class='Value'>i</span><span class='Function'>≢</span><span class='Value'>j</span><span class='Function'>⊑</span><span class='Modifier'>¨</span><span class='Value'>𝕨</span></code>. The groups retain their array structure and ordering along each argument axis. Using multidimensional Replicate we can say that <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>𝕨</span><span class='Function'>⊔</span><span class='Value'>𝕩</span></code> is <code><span class='Paren'>(</span><span class='Value'>i</span><span class='Function'>=</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>/</span><span class='Value'>𝕩</span></code>.</p>
-<h2 id="properties"><a class="header" href="#properties">Properties</a></h2>
-<p>Group is closely related to the <a href="replicate.html#inverse">inverse of Indices</a>, <code><span class='Function'>/</span><span class='Modifier'>⁼</span></code>. In fact, inverse Indices called on the index argument gives the length of each group:</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4omgwqjiipQgMuKAvzPigL8x4oC/Mgov4oG84oinIDLigL8z4oC/MeKAvzI=">↗️</a><pre> <span class='Function'>≠</span><span class='Modifier'>¨</span><span class='Function'>⊔</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span>
-⟨ 0 1 2 1 ⟩
- <span class='Function'>/</span><span class='Modifier'>⁼</span><span class='Function'>∧</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span>
-⟨ 0 1 2 1 ⟩
-</pre>
-<p>A related fact is that calling Indices on the result lengths of Group sorts all the indices passed to Group (removing any ¯1s). This is a kind of counting sort.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=L+KJoMKo4oqUIDLigL8z4oC/MeKAv8KvMeKAvzI=">↗️</a><pre> <span class='Function'>/≠</span><span class='Modifier'>¨</span><span class='Function'>⊔</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>¯1</span><span class='Ligature'>‿</span><span class='Number'>2</span>
-⟨ 1 2 2 3 ⟩
-</pre>
-<p>Called dyadically, Group sorts the right argument according to the left and adds some extra structure. If this structure is removed with <a href="join.html#join">Join</a>, Group can be thought of as a kind of sorting.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oi+IDLigL8z4oC/MeKAv8KvMeKAvzIg4oqUICJhYmNkZSIKMuKAvzPigL8x4oC/wq8x4oC/MiB7RuKGkCgw4omk8J2VqCniirgvIOKLhCDwnZWo4o2L4oq44oqP4peLRvCdlal9ICJhYmNkZSI=">↗️</a><pre> <span class='Function'>∾</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>¯1</span><span class='Ligature'>‿</span><span class='Number'>2</span> <span class='Function'>⊔</span> <span class='String'>&quot;abcde&quot;</span>
-"caeb"
- <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>¯1</span><span class='Ligature'>‿</span><span class='Number'>2</span> <span class='Brace'>{</span><span class='Function'>F</span><span class='Gets'>←</span><span class='Paren'>(</span><span class='Number'>0</span><span class='Function'>≤</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>/</span> <span class='Separator'>⋄</span> <span class='Value'>𝕨</span><span class='Function'>⍋</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span><span class='Modifier2'>○</span><span class='Function'>F</span><span class='Value'>𝕩</span><span class='Brace'>}</span> <span class='String'>&quot;abcde&quot;</span>
-"caeb"
-</pre>
-<p>Group can even be implemented with the same <a href="../implementation/primitive/sort.html#counting-and-bucket-sort">techniques</a> as a bucket sort, making it branchless and fast.</p>
+<p>Each group <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>𝕨</span><span class='Function'>⊔</span><span class='Value'>𝕩</span></code> is composed of the cells <code><span class='Value'>j</span><span class='Function'>&lt;</span><span class='Modifier'>¨</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> such that <code><span class='Value'>i</span><span class='Function'>≢</span><span class='Value'>j</span><span class='Function'>⊑</span><span class='Modifier'>¨</span><span class='Value'>𝕨</span></code>. The groups retain their array structure and ordering along each argument axis. Using multidimensional <a href="replicate.html">Replicate</a> we can say that <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>𝕨</span><span class='Function'>⊔</span><span class='Value'>𝕩</span></code> is <code><span class='Paren'>(</span><span class='Value'>i</span><span class='Function'>=</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>/</span><span class='Value'>𝕩</span></code>.</p>
<h2 id="applications"><a class="header" href="#applications">Applications</a></h2>
-<p>The obvious application of Group is to group some values according to a known or computed property. If this property isn't a natural number, it can be turned into one using <a href="selfcmp.html#classify">Classify</a> (<code><span class='Function'>⊐</span></code>), which numbers the unique values in its argument by first occurrence.</p>
+<p>The most direct application of Group is to group some values according to a known or computed property. If this property isn't a natural number, it can be turned into one using <a href="selfcmp.html#classify">Classify</a> (<code><span class='Function'>⊐</span></code>), which numbers the unique values in its argument by first occurrence.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=bG4g4oaQICJQaGVscHMi4oC/IkxhdHluaW5hIuKAvyJCasO4cmdlbiLigL8iQW5kcmlhbm92IuKAvyJCasO4cm5kYWxlbiIKY28g4oaQICJVUyIgICAg4oC/IlNVIiAgICAgIOKAvyJOTyIgICAgIOKAvyJTVSIgICAgICAg4oC/Ik5PIgriiY3LmCBjbyDiipDiirjiipQgbG4=">↗️</a><pre> <span class='Value'>ln</span> <span class='Gets'>←</span> <span class='String'>&quot;Phelps&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;Latynina&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;Bjørgen&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;Andrianov&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;Bjørndalen&quot;</span>
<span class='Value'>co</span> <span class='Gets'>←</span> <span class='String'>&quot;US&quot;</span> <span class='Ligature'>‿</span><span class='String'>&quot;SU&quot;</span> <span class='Ligature'>‿</span><span class='String'>&quot;NO&quot;</span> <span class='Ligature'>‿</span><span class='String'>&quot;SU&quot;</span> <span class='Ligature'>‿</span><span class='String'>&quot;NO&quot;</span>
<span class='Function'>≍</span><span class='Modifier'>˘</span> <span class='Value'>co</span> <span class='Function'>⊐</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span> <span class='Value'>ln</span>
@@ -177,7 +160,7 @@
</pre>
<h3 id="partitioning"><a class="header" href="#partitioning">Partitioning</a></h3>
-<p>In examples we have been using a list of strings stranded together. Often it's more convenient to write the string with spaces, and split it up as part of the code. In this case, the index corresponding to each word (that is, each letter in the word) is the number of spaces before it. We can get this number of spaces from a Plus-<a href="scan.html">Scan</a> on the boolean list which is 1 at each space.</p>
+<p>Previous examples have used lists of strings stranded together. Often it's more convenient to write the string with spaces, and split it up as part of the code. In this case, the index corresponding to each word (that is, each letter in the word) is the number of spaces before it. We can get this number of spaces from a Plus-<a href="scan.html">Scan</a> on the boolean list which is 1 at each space.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=JyAnKCtg4oiYPeKKlOKKoikiQlFOIHVzZXMgbm90YXRpb24gYXMgYSB0b29sIG9mIHRob3VnaHQi">↗️</a><pre> <span class='String'>' '</span><span class='Paren'>(</span><span class='Function'>+</span><span class='Modifier'>`</span><span class='Modifier2'>∘</span><span class='Function'>=⊔⊢</span><span class='Paren'>)</span><span class='String'>&quot;BQN uses notation as a tool of thought&quot;</span>
⟨ "BQN" " uses" " notation" " as" " a" " tool" " of" " thought" ⟩
</pre>
@@ -185,25 +168,46 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=JyAnKCjiiqIty5zCrMOXK2Ap4oiYPeKKlOKKoikiQlFOIHVzZXMgbm90YXRpb24gYXMgYSB0b29sIG9mIHRob3VnaHQi">↗️</a><pre> <span class='String'>' '</span><span class='Paren'>((</span><span class='Function'>⊢-</span><span class='Modifier'>˜</span><span class='Function'>¬×+</span><span class='Modifier'>`</span><span class='Paren'>)</span><span class='Modifier2'>∘</span><span class='Function'>=⊔⊢</span><span class='Paren'>)</span><span class='String'>&quot;BQN uses notation as a tool of thought&quot;</span>
⟨ "BQN" "uses" "notation" "as" "a" "tool" "of" "thought" ⟩
</pre>
-<p>A function with structural <a href="under.html">Under</a>, such as <code><span class='Brace'>{</span><span class='Number'>¯1</span><span class='Modifier'>¨</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Value'>𝕩</span><span class='Modifier2'>⊸</span><span class='Function'>/</span><span class='Paren'>)</span><span class='Function'>+</span><span class='Modifier'>`</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code>, would also work.</p>
+<p>A function with <a href="under.html">Under</a>, such as <code><span class='Brace'>{</span><span class='Number'>¯1</span><span class='Modifier'>¨</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Value'>𝕩</span><span class='Modifier2'>⊸</span><span class='Function'>/</span><span class='Paren'>)</span><span class='Function'>+</span><span class='Modifier'>`</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code>, would also work.</p>
<p>In other cases, we might want to split on spaces, so that words are separated by any number of spaces, and extra spaces don't affect the output. Currently our function makes a new word with each space:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=JyAnKCjiiqIty5zCrMOXK2Ap4oiYPeKKlOKKoikiICBzdHJpbmcgd2l0aCAgc3BhY2VzICAgIg==">↗️</a><pre> <span class='String'>' '</span><span class='Paren'>((</span><span class='Function'>⊢-</span><span class='Modifier'>˜</span><span class='Function'>¬×+</span><span class='Modifier'>`</span><span class='Paren'>)</span><span class='Modifier2'>∘</span><span class='Function'>=⊔⊢</span><span class='Paren'>)</span><span class='String'>&quot; string with spaces &quot;</span>
⟨ ⟨⟩ ⟨⟩ "string" "with" ⟨⟩ "spaces" ⟩
</pre>
<p>Trailing spaces are ignored because Group with equal-length arguments never produces trailing empty groups—to intentionally include them you'd replace <code><span class='Function'>=</span></code> with <code><span class='Paren'>(</span><span class='Function'>=∾</span><span class='Number'>0</span><span class='Modifier'>˙</span><span class='Paren'>)</span></code>. But in string processing we probably want to avoid empty words anywhere. To make this happen, we should increase the word index only once per group of spaces. We can do this by applying Plus Scan to a list that is 1 only for a space with no space before it. This list is produced using <a href="shift.html">Shift Before</a> to get a list of previous elements. To treat the first element as though it's before a space (so that leading spaces have no effect rather than creating an initial empty group), we shift in a 1.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKKouKJjTHiirjCuzziiqIpICcgJz0iICBzdHJpbmcgd2l0aCAgc3BhY2VzICAgIiAgIyBBbGwsIHRoZW4gZmlsdGVyZWQsIHNwYWNlcwriiY3in5wo4oqiLcucwqzDl8K3K2Ax4oq4wrs84oqiKScgJz0iICBzdHJpbmcgd2l0aCAgc3BhY2VzICAgIiAgIyBNb3JlIHByb2Nlc3NpbmcKJyAnKCjiiqIty5zCrMOXwrcrYDHiirjCuzziiqIp4oiYPeKKlOKKoikiICBzdHJpbmcgd2l0aCAgc3BhY2VzICAgIiAgIyBGaW5hbCByZXN1bHQKCicgJygowqwty5ziiqLDl8K3K2DCu+KKuD4p4oiY4omg4oqU4oqiKSIgIHN0cmluZyB3aXRoICBzcGFjZXMgICAiICAjIFNsaWdodGx5IHNob3J0ZXI=">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>⊢≍</span><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>»&lt;⊢</span><span class='Paren'>)</span> <span class='String'>' '</span><span class='Function'>=</span><span class='String'>&quot; string with spaces &quot;</span> <span class='Comment'># All, then filtered, spaces
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKKouKJjTHiirjCuzziiqIpICcgJz0iICBzdHJpbmcgd2l0aCAgc3BhY2VzICAgIiAgIyBBbGwsIHRoZW4gZmlsdGVyZWQsIHNwYWNlcwoK4omN4p+cKOKKoi3LnMKsw5fCtytgMeKKuMK7POKKoiknICc9IiAgc3RyaW5nIHdpdGggIHNwYWNlcyAgICIgICMgTW9yZSBwcm9jZXNzaW5nCgonICcoKOKKoi3LnMKsw5fCtytgMeKKuMK7POKKoiniiJg94oqU4oqiKSIgIHN0cmluZyB3aXRoICBzcGFjZXMgICAiICAjIEZpbmFsIHJlc3VsdAoKJyAnKCjCrC3LnOKKosOXwrcrYMK74oq4PiniiJjiiaDiipTiiqIpIiAgc3RyaW5nIHdpdGggIHNwYWNlcyAgICIgICMgU2xpZ2h0bHkgc2hvcnRlcg==">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>⊢≍</span><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>»&lt;⊢</span><span class='Paren'>)</span> <span class='String'>' '</span><span class='Function'>=</span><span class='String'>&quot; string with spaces &quot;</span> <span class='Comment'># All, then filtered, spaces
</span>┌─
╵ 1 1 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0
+
<span class='Function'>≍</span><span class='Modifier2'>⟜</span><span class='Paren'>(</span><span class='Function'>⊢-</span><span class='Modifier'>˜</span><span class='Function'>¬×</span><span class='Nothing'>·</span><span class='Function'>+</span><span class='Modifier'>`</span><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>»&lt;⊢</span><span class='Paren'>)</span><span class='String'>' '</span><span class='Function'>=</span><span class='String'>&quot; string with spaces &quot;</span> <span class='Comment'># More processing
</span>┌─
╵ 1 1 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1
¯1 ¯1 0 0 0 0 0 0 ¯1 1 1 1 1 ¯1 ¯1 2 2 2 2 2 2 ¯1 ¯1 ¯1
+
<span class='String'>' '</span><span class='Paren'>((</span><span class='Function'>⊢-</span><span class='Modifier'>˜</span><span class='Function'>¬×</span><span class='Nothing'>·</span><span class='Function'>+</span><span class='Modifier'>`</span><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>»&lt;⊢</span><span class='Paren'>)</span><span class='Modifier2'>∘</span><span class='Function'>=⊔⊢</span><span class='Paren'>)</span><span class='String'>&quot; string with spaces &quot;</span> <span class='Comment'># Final result
</span>⟨ "string" "with" "spaces" ⟩
<span class='String'>' '</span><span class='Paren'>((</span><span class='Function'>¬-</span><span class='Modifier'>˜</span><span class='Function'>⊢×</span><span class='Nothing'>·</span><span class='Function'>+</span><span class='Modifier'>`</span><span class='Function'>»</span><span class='Modifier2'>⊸</span><span class='Function'>&gt;</span><span class='Paren'>)</span><span class='Modifier2'>∘</span><span class='Function'>≠⊔⊢</span><span class='Paren'>)</span><span class='String'>&quot; string with spaces &quot;</span> <span class='Comment'># Slightly shorter
</span>⟨ "string" "with" "spaces" ⟩
</pre>
+<h2 id="group-and-sorting"><a class="header" href="#group-and-sorting">Group and sorting</a></h2>
+<p>Group is closely related to the <a href="replicate.html#inverse">inverse of Indices</a>, <code><span class='Function'>/</span><span class='Modifier'>⁼</span></code>. Calling that function on the index argument gives the length of each group:</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4omgwqjiipQgMuKAvzPigL8x4oC/MgoKL+KBvOKIpyAy4oC/M+KAvzHigL8y">↗️</a><pre> <span class='Function'>≠</span><span class='Modifier'>¨</span><span class='Function'>⊔</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span>
+⟨ 0 1 2 1 ⟩
+
+ <span class='Function'>/</span><span class='Modifier'>⁼</span><span class='Function'>∧</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span>
+⟨ 0 1 2 1 ⟩
+</pre>
+<p>A related fact is that calling Indices on the result lengths of Group sorts all the indices passed to Group (removing any ¯1s). This is a kind of counting sort.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=L+KJoMKo4oqUIDLigL8z4oC/MeKAv8KvMeKAvzI=">↗️</a><pre> <span class='Function'>/≠</span><span class='Modifier'>¨</span><span class='Function'>⊔</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>¯1</span><span class='Ligature'>‿</span><span class='Number'>2</span>
+⟨ 1 2 2 3 ⟩
+</pre>
+<p>Called dyadically, Group sorts the right argument according to the left and adds some extra structure. If this structure is removed with <a href="join.html#join">Join</a>, Group can be thought of as a kind of sorting.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oi+IDLigL8z4oC/MeKAvzIg4oqUICJhYmNkIgoKMuKAvzPigL8x4oC/MiDijYviirjiio8gImFiY2Qi">↗️</a><pre> <span class='Function'>∾</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span> <span class='Function'>⊔</span> <span class='String'>&quot;abcd&quot;</span>
+"cadb"
+
+ <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span> <span class='Function'>⍋</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span> <span class='String'>&quot;abcd&quot;</span>
+"cadb"
+</pre>
diff --git a/docs/doc/map.html b/docs/doc/map.html
index e91b4689..652651ca 100644
--- a/docs/doc/map.html
+++ b/docs/doc/map.html
@@ -62,7 +62,13 @@
</span>⟨ "0⊑𝕩" "1⊑𝕩" "2⊑𝕩" ⟩
</pre>
<p>The applications are performed in index order: index <code><span class='Value'>…</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span></code>, then <code><span class='Value'>…</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span></code>, <code><span class='Value'>…</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>2</span></code> and so on, until <code><span class='Value'>…</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span></code>. This can affect a program where the operand has side effects, such as the following one that appends its argument to <code><span class='Value'>o</span></code>.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=b+KGkOKfqOKfqSDii4Qge2/iiL7in5w84oap8J2VqX3CqCAiaW5kZXgi4omNIm9yZGVyIiDii4Qgbw==">↗️</a><pre> <span class='Value'>o</span><span class='Gets'>←</span><span class='Bracket'>⟨⟩</span> <span class='Separator'>⋄</span> <span class='Brace'>{</span><span class='Value'>o</span><span class='Function'>∾</span><span class='Modifier2'>⟜</span><span class='Function'>&lt;</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier'>¨</span> <span class='String'>&quot;index&quot;</span><span class='Function'>≍</span><span class='String'>&quot;order&quot;</span> <span class='Separator'>⋄</span> <span class='Value'>o</span>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=WyJpbmRleCIsIm9yZGVyIl0KCm/ihpDin6jin6kg4ouEIHtv4oi+4p+cPOKGqfCdlal9wqggWyJpbmRleCIsIm9yZGVyIl0g4ouEIG8=">↗️</a><pre> <span class='Bracket'>[</span><span class='String'>&quot;index&quot;</span><span class='Separator'>,</span><span class='String'>&quot;order&quot;</span><span class='Bracket'>]</span>
+┌─
+╵"index
+ order"
+ ┘
+
+ <span class='Value'>o</span><span class='Gets'>←</span><span class='Bracket'>⟨⟩</span> <span class='Separator'>⋄</span> <span class='Brace'>{</span><span class='Value'>o</span><span class='Function'>∾</span><span class='Modifier2'>⟜</span><span class='Function'>&lt;</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier'>¨</span> <span class='Bracket'>[</span><span class='String'>&quot;index&quot;</span><span class='Separator'>,</span><span class='String'>&quot;order&quot;</span><span class='Bracket'>]</span> <span class='Separator'>⋄</span> <span class='Value'>o</span>
"indexorder"
</pre>
<p>When an array is displayed, index order is the same as the top-to-bottom, left-to-right reading order of English. It's also the same as the ordering of <a href="reshape.html#deshape">Deshape</a>'s result, so that here <code><span class='Value'>o</span></code> ends up being <code><span class='Function'>⥊</span><span class='Value'>𝕩</span></code>. The dyadic cases described in the following sections will also have a defined evaluation order, but it's not as easy to describe it in terms of the arguments: instead, the <em>result</em> elements are produced in index order.</p>
@@ -126,7 +132,7 @@
</svg>
<p>The Table modifier applies its operand function to every possible combination of one element from <code><span class='Value'>𝕨</span></code> and one from <code><span class='Value'>𝕩</span></code>, sort of like a structure-preserving and function-applying <a href="https://en.wikipedia.org/wiki/Cartesian_product">Cartesian product</a>. Below, it combines a length-3 list and a length-5 list into a shape <code><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>5</span></code> table.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IkFCQyIg4omN4oycICIwMTIzNCI=">↗️</a><pre> <span class='String'>&quot;ABC&quot;</span> <span class='Function'>≍</span><span class='Modifier'>⌜</span> <span class='String'>&quot;01234&quot;</span>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IkFCQyIg4ouI4oycICIwMTIzNCI=">↗️</a><pre> <span class='String'>&quot;ABC&quot;</span> <span class='Function'>⋈</span><span class='Modifier'>⌜</span> <span class='String'>&quot;01234&quot;</span>
┌─
╵ "A0" "A1" "A2" "A3" "A4"
"B0" "B1" "B2" "B3" "B4"
@@ -145,7 +151,7 @@
</pre>
<p>The arguments don't have to be lists (that is, rank 1). There's no restriction on their shapes at all! Much like the result shape is <code><span class='Value'>m</span><span class='Ligature'>‿</span><span class='Value'>n</span></code> if <code><span class='Value'>𝕨</span></code> is a list of length <code><span class='Value'>m</span></code> and <code><span class='Value'>𝕩</span></code> is a list of length <code><span class='Value'>n</span></code>, the result shape for an array <code><span class='Value'>𝕨</span></code> of shape <code><span class='Value'>r</span></code> and <code><span class='Value'>𝕩</span></code> of shape <code><span class='Value'>s</span></code> is <code><span class='Value'>r</span><span class='Function'>∾</span><span class='Value'>s</span></code>.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IkEgIuKAvyJCICIg4oi+4oycICJ0aGUi4oC/ImZpcnN0IuKAvyJyb3ci4omNImFuZCLigL8idGhlIuKAvyJzZWNvbmQiCgriiaIgIkEgIuKAvyJCICIg4oi+4oycICJ0aGUi4oC/ImZpcnN0IuKAvyJyb3ci4omNImFuZCLigL8idGhlIuKAvyJzZWNvbmQi">↗️</a><pre> <span class='String'>&quot;A &quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;B &quot;</span> <span class='Function'>∾</span><span class='Modifier'>⌜</span> <span class='String'>&quot;the&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;first&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;row&quot;</span><span class='Function'>≍</span><span class='String'>&quot;and&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;the&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;second&quot;</span>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IkEgIuKAvyJCICIg4oi+4oycIFsidGhlIuKAvyJmaXJzdCLigL8icm93IiwiYW5kIuKAvyJ0aGUi4oC/InNlY29uZCJdCgriiaIgIkEgIuKAvyJCICIg4oi+4oycIFsidGhlIuKAvyJmaXJzdCLigL8icm93IiwiYW5kIuKAvyJ0aGUi4oC/InNlY29uZCJd">↗️</a><pre> <span class='String'>&quot;A &quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;B &quot;</span> <span class='Function'>∾</span><span class='Modifier'>⌜</span> <span class='Bracket'>[</span><span class='String'>&quot;the&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;first&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;row&quot;</span><span class='Separator'>,</span><span class='String'>&quot;and&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;the&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;second&quot;</span><span class='Bracket'>]</span>
┌─
╎ "A the" "A first" "A row"
"A and" "A the" "A second"
@@ -154,7 +160,7 @@
"B and" "B the" "B second"
- <span class='Function'>≢</span> <span class='String'>&quot;A &quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;B &quot;</span> <span class='Function'>∾</span><span class='Modifier'>⌜</span> <span class='String'>&quot;the&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;first&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;row&quot;</span><span class='Function'>≍</span><span class='String'>&quot;and&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;the&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;second&quot;</span>
+ <span class='Function'>≢</span> <span class='String'>&quot;A &quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;B &quot;</span> <span class='Function'>∾</span><span class='Modifier'>⌜</span> <span class='Bracket'>[</span><span class='String'>&quot;the&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;first&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;row&quot;</span><span class='Separator'>,</span><span class='String'>&quot;and&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;the&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;second&quot;</span><span class='Bracket'>]</span>
⟨ 2 2 3 ⟩
</pre>
<p>Except for the more sophisticated shape, this result is exactly what you'd get if you deshaped each argument to a list. In each case, every element of <code><span class='Value'>𝕨</span></code> is visited in turn, and each time the element is paired with every element of <code><span class='Value'>𝕩</span></code>.</p>
@@ -210,31 +216,31 @@
</svg>
<p>Given two arguments of matching shapes, Each performs what's sometimes called a &quot;zip&quot;, matching each element of <code><span class='Value'>𝕨</span></code> to the corresponding element of <code><span class='Value'>𝕩</span></code>.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IkFCQ0QiIOKJjcKoICIwMTIzIg==">↗️</a><pre> <span class='String'>&quot;ABCD&quot;</span> <span class='Function'>≍</span><span class='Modifier'>¨</span> <span class='String'>&quot;0123&quot;</span>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IkFCQ0QiIOKLiMKoICIwMTIzIg==">↗️</a><pre> <span class='String'>&quot;ABCD&quot;</span> <span class='Function'>⋈</span><span class='Modifier'>¨</span> <span class='String'>&quot;0123&quot;</span>
⟨ "A0" "B1" "C2" "D3" ⟩
</pre>
<p>This makes for a lot fewer applications than Table. Only the diagonal elements from Table's result are seen, as we can check with <a href="transpose.html#reorder-axes">Reorder Axes</a>.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MOKAvzAg4o2JICJBQkNEIiDiiY3ijJwgIjAxMjMi">↗️</a><pre> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span> <span class='Function'>⍉</span> <span class='String'>&quot;ABCD&quot;</span> <span class='Function'>≍</span><span class='Modifier'>⌜</span> <span class='String'>&quot;0123&quot;</span>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MOKAvzAg4o2JICJBQkNEIiDii4jijJwgIjAxMjMi">↗️</a><pre> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span> <span class='Function'>⍉</span> <span class='String'>&quot;ABCD&quot;</span> <span class='Function'>⋈</span><span class='Modifier'>⌜</span> <span class='String'>&quot;0123&quot;</span>
⟨ "A0" "B1" "C2" "D3" ⟩
</pre>
<p>If the argument lengths don't match then Each gives an error. This differs from zip in many languages, which drops elements from the longer argument (this is natural for linked lists). This flexibility is rarely wanted in BQN, and having an error right away saves debugging time.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IkFCQyIg4omNwqggIjAxMjM0Ig==">↗️</a><pre> <span class='String'>&quot;ABC&quot;</span> <span class='Function'>≍</span><span class='Modifier'>¨</span> <span class='String'>&quot;01234&quot;</span>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IkFCQyIg4ouIwqggIjAxMjM0Ig==">↗️</a><pre> <span class='String'>&quot;ABC&quot;</span> <span class='Function'>⋈</span><span class='Modifier'>¨</span> <span class='String'>&quot;01234&quot;</span>
<span class='Error'>Error: Mapping: Expected equal shape prefix (⟨3⟩ ≡ ≢𝕨, ⟨5⟩ ≡ ≢𝕩)</span>
</pre>
<p>Arguments can have any shape as long as the axis lengths match up. As with Table, the result elements don't depend on these shapes but the result shape does.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=WzIw4oC/MzDigL8xMCw1MOKAvzQw4oC/NjBdICvin5zihpXCqCAy4oC/MeKAvzDiiY0z4oC/MuKAvzE=">↗️</a><pre> <span class='Bracket'>[</span><span class='Number'>20</span><span class='Ligature'>‿</span><span class='Number'>30</span><span class='Ligature'>‿</span><span class='Number'>10</span><span class='Separator'>,</span><span class='Number'>50</span><span class='Ligature'>‿</span><span class='Number'>40</span><span class='Ligature'>‿</span><span class='Number'>60</span><span class='Bracket'>]</span> <span class='Function'>+</span><span class='Modifier2'>⟜</span><span class='Function'>↕</span><span class='Modifier'>¨</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Function'>≍</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=WzIw4oC/MzDigL8xMCw1MOKAvzQw4oC/NjBdICvin5zihpXCqCBbMuKAvzHigL8wLDPigL8y4oC/MV0=">↗️</a><pre> <span class='Bracket'>[</span><span class='Number'>20</span><span class='Ligature'>‿</span><span class='Number'>30</span><span class='Ligature'>‿</span><span class='Number'>10</span><span class='Separator'>,</span><span class='Number'>50</span><span class='Ligature'>‿</span><span class='Number'>40</span><span class='Ligature'>‿</span><span class='Number'>60</span><span class='Bracket'>]</span> <span class='Function'>+</span><span class='Modifier2'>⟜</span><span class='Function'>↕</span><span class='Modifier'>¨</span> <span class='Bracket'>[</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Bracket'>]</span>
┌─
╵ ⟨ 20 21 ⟩ ⟨ 30 ⟩ ⟨⟩
⟨ 50 51 52 ⟩ ⟨ 40 41 ⟩ ⟨ 60 ⟩
</pre>
<p>But arguments don't have to have exactly the same shape: just the same length along corresponding axes. These axes are matched up by <a href="leading.html#leading-axis-agreement">leading axis agreement</a>, so that one argument's shape has to be a prefix of the other's. With equal ranks, the shapes do have to match as we've seen above.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4omiICgw4oC/MuKAvzbipYpAKSDiiY3CqCAw4oC/MeKlijAgICMgVG9vIHNtYWxsCgriiaIgKDDigL8y4oC/NuKlikApIOKJjcKoIDDigL8z4qWKMCAgIyBUb28gbGFyZ2UKCuKJoiAoMOKAvzLigL824qWKQCkg4omNwqggMOKAvzLipYowICAjIEp1c3QgcmlnaHQ=">↗️</a><pre> <span class='Function'>≢</span> <span class='Paren'>(</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Function'>⥊</span><span class='String'>@</span><span class='Paren'>)</span> <span class='Function'>≍</span><span class='Modifier'>¨</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Function'>⥊</span><span class='Number'>0</span> <span class='Comment'># Too small
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4omiICgw4oC/MuKAvzbipYpAKSDii4jCqCAw4oC/MeKlijAgICMgVG9vIHNtYWxsCgriiaIgKDDigL8y4oC/NuKlikApIOKLiMKoIDDigL8z4qWKMCAgIyBUb28gbGFyZ2UKCuKJoiAoMOKAvzLigL824qWKQCkg4ouIwqggMOKAvzLipYowICAjIEp1c3QgcmlnaHQ=">↗️</a><pre> <span class='Function'>≢</span> <span class='Paren'>(</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Function'>⥊</span><span class='String'>@</span><span class='Paren'>)</span> <span class='Function'>⋈</span><span class='Modifier'>¨</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Function'>⥊</span><span class='Number'>0</span> <span class='Comment'># Too small
</span><span class='Error'>Error: Mapping: Expected equal shape prefix (0‿2‿6 ≡ ≢𝕨, 0‿1 ≡ ≢𝕩)</span>
- <span class='Function'>≢</span> <span class='Paren'>(</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Function'>⥊</span><span class='String'>@</span><span class='Paren'>)</span> <span class='Function'>≍</span><span class='Modifier'>¨</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Function'>⥊</span><span class='Number'>0</span> <span class='Comment'># Too large
+ <span class='Function'>≢</span> <span class='Paren'>(</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Function'>⥊</span><span class='String'>@</span><span class='Paren'>)</span> <span class='Function'>⋈</span><span class='Modifier'>¨</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Function'>⥊</span><span class='Number'>0</span> <span class='Comment'># Too large
</span><span class='Error'>Error: Mapping: Expected equal shape prefix (0‿2‿6 ≡ ≢𝕨, 0‿3 ≡ ≢𝕩)</span>
- <span class='Function'>≢</span> <span class='Paren'>(</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Function'>⥊</span><span class='String'>@</span><span class='Paren'>)</span> <span class='Function'>≍</span><span class='Modifier'>¨</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Function'>⥊</span><span class='Number'>0</span> <span class='Comment'># Just right
+ <span class='Function'>≢</span> <span class='Paren'>(</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Function'>⥊</span><span class='String'>@</span><span class='Paren'>)</span> <span class='Function'>⋈</span><span class='Modifier'>¨</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Function'>⥊</span><span class='Number'>0</span> <span class='Comment'># Just right
</span>⟨ 0 2 6 ⟩
</pre>