aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/commentary/why.html20
-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
7 files changed, 136 insertions, 109 deletions
diff --git a/docs/commentary/why.html b/docs/commentary/why.html
index 9ab7e0a0..1fe07371 100644
--- a/docs/commentary/why.html
+++ b/docs/commentary/why.html
@@ -11,9 +11,9 @@
<p>BQN has no intention of being the last word in programming, but could be a practical and elegant tool in your kit—even if only used to inform your use of another language. Give it a try!</p>
<h2 id="versus-apl-and-j"><a class="header" href="#versus-apl-and-j">Versus APL and J</a></h2>
<p>Here are some more specific comparisons against the two most similar languages to BQN. I'll try to bring up the areas where BQN can be considered worse, but my focus here is definitely on BQN's strong points—I'm not trying to offer an unbiased account.</p>
-<p>BQN is more like APL, but adopts some of the developments made by J as well. However, it's much simpler than both, with fewer and less overloaded primitives as well as less special syntax (J has fewer syntactic rules, but more special cases handled during execution that I think <em>should</em> have been implemented with syntax).</p>
+<p>BQN is more like APL, but adopts some of the developments made by J as well. However, it's much simpler than both, with fewer and less overloaded primitives as well as less special syntax (J has fewer syntactic rules, but more special cases handled during execution that I think <em>should</em> have been designed as syntax).</p>
<p>The major differences are listed on <a href="../index.html#whats-the-language-like">the front page</a> (&quot;But it's redesigned…&quot;): <a href="../doc/based.html">based arrays</a>, <a href="../doc/arrayrepr.html">list notation</a>, <a href="../doc/context.html">context-free grammar</a> and <a href="../doc/functional.html">first-class functions</a>, <a href="../doc/primitive.html">reworked primitives</a>, and dedicated <a href="../doc/namespace.html">namespace syntax</a>.</p>
-<p>In addition to these, BQN's <a href="../doc/block.html">block system</a> extends APL dfns with headers, adding some very useful functionality: the header specifies block type and argument names, and also allows for simple pattern matching when used with multiple block bodies.</p>
+<p>In addition to these, BQN's <a href="../doc/block.html">block system</a> extends APL dfns with headers, adding some very useful functionality: the header specifies block type and argument names, and also allows for some pattern matching when used with multiple block bodies.</p>
<p>Since this section gets into the details, it's worth highlighting stranding, a feature I think of as an obvious improvement but that many BQN newcomers see as an obvious sign that I don't know what I'm doing! My full argument for this decision is <a href="../doc/arrayrepr.html#why-not-whitespace">here</a>; the two key points are that stranding is a source of ambiguity that can strike at any time, requiring a correction with <code><span class='Function'>⊢</span></code> or <code><span class='Bracket'>]</span></code>, and that typing <code><span class='Ligature'>‿</span></code> is really not hard I promise.</p>
<p>BQN's heavier-weight <code><span class='Bracket'>⟨⟩</span></code> syntax for lists also has its own advantages, because it can be formatted nicely across multiple lines, and also allows functions and modifiers to be used easily as elements. Being able to easily map over a list of functions is surprisingly useful!</p>
<p>BQN has no built-in control structures, which can be quite an adjustment coming from certain styles of APL or J. The <a href="../doc/control.html">control structures</a> page gives some ways to write in a more imperative style, but it's definitely not the same.</p>
@@ -21,7 +21,7 @@
<ul>
<li>The index origin is 0.</li>
<li>APL and J use approximate comparison in primitives, controlled by a value called the comparison tolerance (<code><span class='Value'>⎕</span><span class='Function'>CT</span></code> in APL). The choice of which primitives use it and how is kind of arbitrary, and a nonzero comparison tolerance can lead to confusion, bugs, and unavoidable performance problems in some primitives. Nonetheless, I planned to add tolerant comparison to BQN—until I realized that after a year spent programming in BQN I'd hardly noticed its absence, and no one had asked for it either.</li>
-<li>Random number generation isn't a primitive, but instead uses the global generator <code><span class='Value'>•rand</span></code> or an initialized generator <code><span class='Function'>•MakeRand</span></code>. This makes managing independent generators easier, and with namespaces <a href="../spec/system.html#random-generation">you get</a> several convenient functions for different use cases.</li>
+<li>Random number generation isn't a primitive: instead there's a global generator <code><span class='Value'>•rand</span></code> and initialized generators with <code><span class='Function'>•MakeRand</span></code>. This makes managing independent generators easier, and with namespaces <a href="../spec/system.html#random-generation">you get</a> several convenient functions for different use cases.</li>
</ul>
<p>Some factors specific to APL or J are given in the sections below.</p>
<h3 id="apl"><a class="header" href="#apl">APL</a></h3>
@@ -29,10 +29,10 @@
<p>BQN cleans up some awkward syntax left over from when each APL operator was special: the outer product is written <code><span class='Function'>Fn</span><span class='Modifier'>⌜</span></code> rather than <code><span class='Modifier2'>∘</span><span class='Value'>.fn</span></code>, and reduction <code><span class='Function'>Fn</span><span class='Modifier'>´</span> <span class='Value'>arr</span></code> is separated from compress <code><span class='Value'>b</span><span class='Function'>/</span><span class='Value'>arr</span></code> instead of <a href="https://aplwiki.com/wiki/Function-operator_overloading">overloading</a>.</p>
<p>BQN adopts <a href="../doc/leading.html">leading axis theory</a> as developed in SHARP APL and applied in A+ and J. With this it can collapse APL pairs such as <code><span class='Function'>⌽</span><span class='Value'>⊖</span></code> and <code><span class='Function'>/</span><span class='Value'>⌿</span></code> to one primitive each, and remove APL's complicated function axis (such as <code><span class='Function'>⌽</span><span class='Bracket'>[</span><span class='Number'>2</span><span class='Bracket'>]</span></code>) mechanism. The Rank modifier <code><span class='Modifier2'>⎉</span></code> then applies these primitives to non-leading axes. While this method is required in J and also favored by many users of Dyalog APL, it definitely doesn't enjoy universal support—it can be harder to learn, and less convenient for some common cases. Summing rows with <code><span class='Function'>+/</span></code> in APL is quite convenient, and BQN's <code><span class='Function'>+</span><span class='Modifier'>˝</span><span class='Modifier2'>⎉</span><span class='Number'>1</span></code>, or <code><span class='Function'>+</span><span class='Modifier'>˝˘</span></code> for matrices, just aren't as nice.</p>
<p>Arguably BQN cuts down the set of primitives too much. Base conversion <code><span class='Value'>⊥⊤</span></code>, partitioning <code><span class='Value'>⊂⊆</span></code>, and matrix division <code><span class='Value'>⌹</span></code> are commonly asked-for primitives, but they don't match <a href="primitive.html">my conception</a> of a primitive. And while each can be implemented (with short snippets, other than <code><span class='Value'>⌹</span></code> which requires a library), there's definitely a convenience loss. But there's always <a href="../doc/rebqn.html">ReBQN</a>…</p>
-<p>BQN's Power modifier <code><span class='Modifier2'>⍟</span></code> allows an array operand to specify multiple results, for example <code><span class='Function'>Fn</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Function'>↕</span><span class='Number'>4</span><span class='Paren'>)</span></code> to get 0 up to 3 iterations. Intermediate results are saved, so the number of calls only depends on the highest iteration number present. On the other hand, BQN has no direct equivalent of Power Limit <code><span class='Value'>⍣</span><span class='Function'>≡</span></code>, requiring it to be <a href="https://mlochbaum.github.io/bqncrate/?q=power%20limit">implemented manually</a>.</p>
-<p>An APL selective assignment <code><span class='Value'>arr</span><span class='Bracket'>[</span><span class='Number'>2</span> <span class='Number'>3</span><span class='Bracket'>]</span><span class='Function'>+</span><span class='Gets'>←</span><span class='Number'>1</span></code> should usually be written with Under in BQN: <code><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span><span class='Paren'>)</span><span class='Value'>arr</span></code> (but the correspondence might not always be so direct). You can think of this as a very fancy At (<code><span class='String'>@</span></code>) operator, that lets you pull out an arbitrary part of an array.</p>
+<p>BQN's version of the Power modifier <code><span class='Modifier2'>⍟</span></code> allows an array operand to specify multiple results, for example <code><span class='Function'>Fn</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Function'>↕</span><span class='Number'>4</span><span class='Paren'>)</span></code> to get 0 up to 3 iterations. Intermediate results are saved, so the number of calls only depends on the highest iteration number present. On the other hand, BQN has no direct equivalent of Power Limit <code><span class='Value'>⍣</span><span class='Function'>≡</span></code>, requiring it to be <a href="https://mlochbaum.github.io/bqncrate/?q=power%20limit">implemented manually</a>.</p>
+<p>An APL selective assignment <code><span class='Value'>arr</span><span class='Bracket'>[</span><span class='Number'>2</span> <span class='Number'>3</span><span class='Bracket'>]</span><span class='Function'>+</span><span class='Gets'>←</span><span class='Number'>1</span></code> should usually be written with <a href="../doc/under.html">Under</a> in BQN: <code><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span><span class='Paren'>)</span><span class='Value'>arr</span></code> (but the correspondence might not always be so direct). You can think of this as a very fancy At (<code><span class='String'>@</span></code>) operator, that lets you pull out an arbitrary part of an array.</p>
<p>Dfns are adjusted in a few ways that make them more useful for general-purpose programming. A BQN block always runs to the last statement, so a block like <code><span class='Brace'>{</span><span class='Function'>Update</span> <span class='Value'>𝕩</span> <span class='Separator'>⋄</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Value'>x</span><span class='Brace'>}</span></code> won't return early. Writing modification with <code><span class='Gets'>↩</span></code> makes it clearer which variable's which. Dfns also do a weird shadowing thing where <code><span class='Value'>a</span><span class='Gets'>←</span><span class='Number'>1</span><span class='Separator'>⋄</span><span class='Value'>a</span><span class='Gets'>←</span><span class='Number'>2</span></code> makes two different variables; in BQN this is an error because the second should use <code><span class='Gets'>↩</span></code>. Tradfns are removed entirely, along with control structures.</p>
-<p>BQN doesn't have an exact replacement for dfn guards, although the predicate <code><span class='Head'>?</span></code> can look similar: <code><span class='Brace'>{</span><span class='Number'>2</span><span class='Function'>|</span><span class='Value'>⍵</span> <span class='Head'>:</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×</span><span class='Value'>⍵</span> <span class='Separator'>⋄</span> <span class='Value'>⍵</span><span class='Function'>÷</span><span class='Number'>2</span><span class='Brace'>}</span></code> is equivalent to <code><span class='Brace'>{</span><span class='Number'>2</span><span class='Function'>|</span><span class='Value'>𝕩</span> <span class='Head'>?</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×</span><span class='Value'>𝕩</span> <span class='Head'>;</span> <span class='Value'>𝕩</span><span class='Function'>÷</span><span class='Number'>2</span><span class='Brace'>}</span></code>. But note that where APL uses the statement separator <code><span class='Separator'>⋄</span></code>, BQN uses the body separator <code><span class='Head'>;</span></code>. This means that the if-true branch in BQN can consist of multiple statements (including additional predicates), but also that the if-false branch can't access variables defined in or before the condition. In both cases the &quot;better&quot; behavior can be obtained with an extra set of braces and possibly assigning names to arguments <code><span class='Value'>⍵</span></code>/<code><span class='Value'>𝕩</span></code>. I think guards end up being cleaner when they work, and predicates are more versatile.</p>
+<p>BQN doesn't have an exact replacement for dfn guards, although the <a href="../doc/block.html#predicates">predicate</a> <code><span class='Head'>?</span></code> can look similar: <code><span class='Brace'>{</span><span class='Number'>2</span><span class='Function'>|</span><span class='Value'>⍵</span> <span class='Head'>:</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×</span><span class='Value'>⍵</span> <span class='Separator'>⋄</span> <span class='Value'>⍵</span><span class='Function'>÷</span><span class='Number'>2</span><span class='Brace'>}</span></code> is equivalent to <code><span class='Brace'>{</span><span class='Number'>2</span><span class='Function'>|</span><span class='Value'>𝕩</span> <span class='Head'>?</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×</span><span class='Value'>𝕩</span> <span class='Head'>;</span> <span class='Value'>𝕩</span><span class='Function'>÷</span><span class='Number'>2</span><span class='Brace'>}</span></code>. But note that where APL uses the statement separator <code><span class='Separator'>⋄</span></code>, BQN uses the body separator <code><span class='Head'>;</span></code>. This means that the if-true branch in BQN can consist of multiple statements (including additional predicates), but also that the if-false branch can't access variables defined in or before the condition. In both cases the &quot;better&quot; behavior can be obtained with an extra set of braces and possibly assigning names to arguments <code><span class='Value'>⍵</span></code>/<code><span class='Value'>𝕩</span></code>. I think guards end up being cleaner when they work, and predicates are more versatile.</p>
<p>BQN's namespaces have a dedicated syntax, are <em>much</em> easier to create than Dyalog namespaces, and have better performance. I use them all the time, and they feel like a natural part of the language.</p>
<h3 id="j"><a class="header" href="#j">J</a></h3>
<p><em>See also the <a href="../doc/fromJ.html">BQN-J dictionary</a>. J is under development again and a moving target. I stopped using it completely shortly after starting work on BQN in 2020, and while I try to keep up to date on language changes, some remarks here might not fit with the experience you'd get starting with J today.</em></p>
@@ -40,15 +40,15 @@
<p>The biggest difference could be in file loading. If you write a script that depends on other files, and want it to work regardless of the directory it's called from, you need to deal with this. In J, <code><span class='Function'>&gt;</span><span class='Brace'>{</span><span class='Head'>:</span><span class='Number'>4</span><span class='Function'>!</span><span class='Head'>:</span><span class='Number'>3</span> <span class='String'>''</span></code> gives the name of the most recently loaded script (the current one, if you put it before any imports), but to make it into a utility you need this glob of what's-going-on:</p>
<pre><span class='Value'>cur_script</span> <span class='Function'>=</span><span class='Head'>:</span> <span class='Brace'>{{</span><span class='Paren'>(</span><span class='Number'>4</span><span class='Function'>!</span><span class='Head'>:</span><span class='Number'>3</span><span class='Value'>$</span><span class='Number'>0</span><span class='Paren'>)</span> <span class='Brace'>{</span><span class='Head'>::</span><span class='Value'>~</span> <span class='Number'>4</span><span class='Function'>!</span><span class='Head'>:</span><span class='Number'>4</span><span class='Function'>&lt;</span><span class='String'>'y'</span><span class='Brace'>}}</span>
</pre>
-<p>In BQN it's <code><span class='Value'>•path</span></code>. And usually you don't need it because <code><span class='Function'>•Import</span></code> resolves paths relative to the file containing it.</p>
+<p>In BQN it's <code><span class='Value'>•path</span></code>. And usually you don't need it because <code><span class='Function'>•Import</span></code> resolves paths relative to the file containing it (if you want to use the shell's current directory, you have to use <code><span class='Value'>•wdpath</span></code> explicitly).</p>
<p>J uses numeric codes; BQN uses mostly names. So J's <code><span class='Number'>1</span><span class='Value'>&amp;o.</span></code> is BQN's <code><span class='Value'>•math.</span><span class='Function'>Sin</span></code>, and <code><span class='Number'>6</span><span class='Function'>!</span><span class='Head'>:</span><span class='Number'>9</span></code> corresponds to BQN's <code><span class='Function'>•MonoTime</span></code>.</p>
<p>J uses bytestrings by default, making Unicode handling a significant difficulty (<a href="https://code.jsoftware.com/wiki/Vocabulary/uco">see</a> <code><span class='Value'>u</span><span class='Head'>:</span></code>). BQN strings are lists of codepoints, so you don't have to worry about how they're encoded or fight to avoid splitting up UTF-8 bytes that need to go together.</p>
<p>But J has its type advantages as well. I miss complex number support in BQN, as it's an optional extension that we haven't yet implemented. And BQN has a hard rule that only one numeric type is exposed to the programmer, which means high-precision integers and rationals aren't allowed at all for a float-based implementation. I think this rule is worth it because J's implicit type conversion is hard to predict and an unexpected numeric type can cause sporadic or subtle program errors.</p>
<p>BQN uses a modifier <code><span class='Modifier2'>⟜</span></code> for J's hook, adding <code><span class='Modifier2'>⊸</span></code> for a reversed version (which I use nearly twice as often). This frees up the 2-train, which is made equivalent to Atop (<code><span class='Modifier2'>∘</span></code>). It's the system Roger Hui came to advocate, since he argued in favor of a hook conjunction <a href="https://code.jsoftware.com/wiki/Essays/Hook_Conjunction%3F">here</a> and made 2-train an Atop when he brought it to Dyalog APL. As an example, the J hook <code><span class='Paren'>(</span><span class='Comment'>#~0&amp;&lt;:)</span></code> to remove negative numbers becomes <code><span class='Number'>0</span><span class='Modifier2'>⊸</span><span class='Function'>≤</span><span class='Modifier2'>⊸</span><span class='Function'>/</span></code> in BQN. Hooks are also the topic of <a href="https://www.arraycast.com/episodes/episode17-tacit4-the-dyadic-hook">Array Cast episode 14</a>, where the panel points out that in J, adding a verb at the far left of a dyadic train changes the rest of the train from dyadic to monadic or vice-versa, an effect that doesn't happen in BQN.</p>
-<p>J locales are not first-class values, and BQN namespaces are. I think BQN's namespaces are a lot more convenient to construct, although it is lacking an inheritance mechanism (but J's path system can become confusing quickly). More importantly, BQN namespaces (and closures) are garbage collected. J locales leak unless manually freed by the programmer. More generally, J has no mutable data at all, and to simulate it properly you'd have to write your own tracing garbage collection as the J interpreter doesn't have any. I discussed this issue some in <a href="http://www.jsoftware.com/pipermail/programming/2021-April/058006.html">this J forum thread</a>.</p>
+<p>J locales are not first-class values, and BQN namespaces are. I think BQN's namespaces are a lot more convenient to construct, although it is lacking an inheritance mechanism (but J's path system can become confusing quickly). More importantly, BQN namespaces (and closures) are garbage collected. J locales leak unless manually freed by the programmer. J has no mutable data at all; to simulate it properly you'd have to write your own tracing garbage collector, as the J interpreter doesn't have one.</p>
<p>In J, each function has a built-in rank attribute: for example the ranks of <code><span class='Function'>+</span></code> are <code><span class='Number'>0</span> <span class='Number'>0</span> <span class='Number'>0</span></code>. This rank is accessed by the &quot;close&quot; compositions <code><span class='String'>@</span></code>, <code><span class='Value'>&amp;</span></code>, and <code><span class='Value'>&amp;.</span></code>. Choosing the shorter form for the close compositions—for example <code><span class='String'>@</span></code> rather than <code><span class='String'>@</span><span class='Head'>:</span></code>—is often considered a mistake within the J community. And function ranks are unreliable: consider that the ranks of <code><span class='Bracket'>]</span><span class='String'>@</span><span class='Head'>:</span><span class='Function'>+</span></code>, a function that always has the same result as <code><span class='Function'>+</span></code>, are <code><span class='Modifier2'>_</span> <span class='Modifier2'>_</span> <span class='Modifier2'>_</span></code>. In BQN there aren't any close compositions at all, and no function ranks. J's <code><span class='Value'>&amp;.</span><span class='Function'>&gt;</span></code> is simply <code><span class='Modifier'>¨</span></code>, and other close compositions, in my opinion, just aren't needed.</p>
-<p>J has several adverbs (key, prefix, infix, outfix…) to slice up an argument in various ways and apply a verb to those parts. In BQN, I rejected this approach: there are 1-modifiers for basic iteration patterns, and functions such as <a href="../doc/group.html">Group</a> (<code><span class='Function'>⊔</span></code>) that do the slicing but don't apply anything. So <code><span class='Function'>&lt;/</span><span class='Value'>.~a</span></code> is <code><span class='Function'>⊐</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span><span class='Value'>a</span></code>, but <code><span class='Value'>fn</span><span class='Function'>/</span><span class='Value'>.~a</span></code> is <code><span class='Function'>&gt;Fn</span><span class='Modifier'>¨</span><span class='Function'>⊐</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span><span class='Value'>a</span></code> (I also reject J's implicit merge except for the Rank modifier, as I don't think function results should be homogeneous by default). BQN's approach composes better, and is more predictable from a performance perspective.</p>
-<p>Gerunds are J's answer to BQN's first-class functions. For example J's <code><span class='Paren'>(</span><span class='Value'>%&amp;</span><span class='Number'>2</span><span class='Paren'>)</span><span class='Modifier'>`</span><span class='Paren'>(</span><span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Value'>*</span><span class='Bracket'>]</span><span class='Paren'>)</span><span class='String'>@</span><span class='Value'>.</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Value'>&amp;</span><span class='Function'>|</span><span class='Paren'>)</span></code> would be written <code><span class='Number'>2</span><span class='Modifier2'>⊸</span><span class='Function'>|</span><span class='Modifier2'>◶</span><span class='Bracket'>⟨</span><span class='Function'>÷</span><span class='Modifier2'>⟜</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×⊢</span><span class='Bracket'>⟩</span></code> with a list of functions. I think lists of functions are a big improvement, since there's no need to convert between gerund and function, and no worries about arrays that just happen to be valid gerunds (worried about losing the ability to construct gerunds? Constructing tacit functions in BQN is much easier). The usability gap widens because passing J functions around either as values or gerunds has presents some highly idiosyncratic challenges, discussed below.</p>
+<p>J has several adverbs (key, prefix, infix, outfix…) to slice up an argument in various ways and apply a verb to those parts. In BQN, I rejected this approach: there are modifiers for basic iteration patterns, and functions such as <a href="../doc/group.html">Group</a> (<code><span class='Function'>⊔</span></code>) that do the slicing but don't apply anything. So <code><span class='Function'>&lt;/</span><span class='Value'>.~a</span></code> is <code><span class='Function'>⊐</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span><span class='Value'>a</span></code>, but <code><span class='Value'>fn</span><span class='Function'>/</span><span class='Value'>.~a</span></code> is <code><span class='Function'>&gt;Fn</span><span class='Modifier'>¨</span><span class='Function'>⊐</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span><span class='Value'>a</span></code> (I also reject J's implicit merge except for the Rank modifier, as I don't think function results should be assumed homogeneous by default). BQN's approach composes better, and is more predictable from a performance perspective.</p>
+<p>Gerunds are J's answer to BQN's first-class functions. For example J's <code><span class='Paren'>(</span><span class='Value'>%&amp;</span><span class='Number'>2</span><span class='Paren'>)</span><span class='Modifier'>`</span><span class='Paren'>(</span><span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Value'>*</span><span class='Bracket'>]</span><span class='Paren'>)</span><span class='String'>@</span><span class='Value'>.</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Value'>&amp;</span><span class='Function'>|</span><span class='Paren'>)</span></code> would be written <code><span class='Number'>2</span><span class='Modifier2'>⊸</span><span class='Function'>|</span><span class='Modifier2'>◶</span><span class='Bracket'>⟨</span><span class='Function'>÷</span><span class='Modifier2'>⟜</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×⊢</span><span class='Bracket'>⟩</span></code> with a list of functions. I think lists of functions are a big improvement, since there's no need to convert between gerund and function, and no worries about arrays that just happen to be valid gerunds (worried about losing the ability to construct gerunds? Constructing tacit functions in BQN is much easier). Unrelated to these fundamental issues, passing J functions around either as values or gerunds presents some idiosyncratic challenges, discussed below.</p>
<h4 id="named-functions"><a class="header" href="#named-functions">Named functions</a></h4>
<p>Its impact on the programmer is smaller than a lot of the issues above, but this section describes a behavior that I find pretty hard to justify. What does the identifier <code><span class='Value'>fn</span></code> indicate in a J expression? The value of <code><span class='Value'>fn</span></code> in the current scope, one might suppose. Nope—only if the value is a noun. Let's make it a function.</p>
<pre> <span class='Value'>fn</span> <span class='Function'>=</span><span class='Head'>:</span> <span class='Function'>-</span>
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>