aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2021-08-11 17:21:31 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2021-08-11 17:25:04 -0400
commit2afb23928e1984d475cc460e1672e8f6fa0e4dbe (patch)
treeebd2cc514294d30b6fa4b36c2ee638326f06ef72 /docs
parenteac61ca02074c218667754d5f4ef562e780bae85 (diff)
Allow clicking on header to get fragment link
Diffstat (limited to 'docs')
-rw-r--r--docs/commentary/bacon.html2
-rw-r--r--docs/commentary/fanart.html2
-rw-r--r--docs/commentary/history.html28
-rw-r--r--docs/commentary/index.html2
-rw-r--r--docs/commentary/orchard.html2
-rw-r--r--docs/commentary/primitive.html12
-rw-r--r--docs/commentary/problems.html152
-rw-r--r--docs/doc/arithmetic.html12
-rw-r--r--docs/doc/array.html14
-rw-r--r--docs/doc/arrayrepr.html26
-rw-r--r--docs/doc/assert.html4
-rw-r--r--docs/doc/based.html10
-rw-r--r--docs/doc/block.html24
-rw-r--r--docs/doc/context.html10
-rw-r--r--docs/doc/control.html24
-rw-r--r--docs/doc/couple.html8
-rw-r--r--docs/doc/depth.html8
-rw-r--r--docs/doc/embed.html8
-rw-r--r--docs/doc/enclose.html12
-rw-r--r--docs/doc/expression.html10
-rw-r--r--docs/doc/fill.html6
-rw-r--r--docs/doc/find.html4
-rw-r--r--docs/doc/fold.html14
-rw-r--r--docs/doc/fromDyalog.html14
-rw-r--r--docs/doc/fromJ.html14
-rw-r--r--docs/doc/functional.html10
-rw-r--r--docs/doc/glossary.html18
-rw-r--r--docs/doc/group.html12
-rw-r--r--docs/doc/identity.html10
-rw-r--r--docs/doc/index.html2
-rw-r--r--docs/doc/indices.html8
-rw-r--r--docs/doc/join.html6
-rw-r--r--docs/doc/leading.html18
-rw-r--r--docs/doc/lexical.html14
-rw-r--r--docs/doc/logic.html10
-rw-r--r--docs/doc/map.html8
-rw-r--r--docs/doc/match.html6
-rw-r--r--docs/doc/namespace.html8
-rw-r--r--docs/doc/oop.html14
-rw-r--r--docs/doc/order.html14
-rw-r--r--docs/doc/paradigms.html6
-rw-r--r--docs/doc/pick.html8
-rw-r--r--docs/doc/prefixes.html8
-rw-r--r--docs/doc/primitive.html6
-rw-r--r--docs/doc/range.html6
-rw-r--r--docs/doc/repeat.html10
-rw-r--r--docs/doc/replicate.html10
-rw-r--r--docs/doc/reshape.html12
-rw-r--r--docs/doc/reverse.html8
-rw-r--r--docs/doc/scan.html10
-rw-r--r--docs/doc/search.html12
-rw-r--r--docs/doc/select.html8
-rw-r--r--docs/doc/selfcmp.html12
-rw-r--r--docs/doc/shape.html6
-rw-r--r--docs/doc/shift.html12
-rw-r--r--docs/doc/syntax.html22
-rw-r--r--docs/doc/take.html8
-rw-r--r--docs/doc/train.html10
-rw-r--r--docs/doc/transpose.html10
-rw-r--r--docs/doc/types.html18
-rw-r--r--docs/doc/undo.html8
-rw-r--r--docs/doc/windows.html12
-rw-r--r--docs/editors/index.html18
-rw-r--r--docs/implementation/codfns.html10
-rw-r--r--docs/implementation/compile/dynamic.html22
-rw-r--r--docs/implementation/compile/index.html2
-rw-r--r--docs/implementation/index.html2
-rw-r--r--docs/implementation/kclaims.html10
-rw-r--r--docs/implementation/primitive/index.html2
-rw-r--r--docs/implementation/primitive/random.html6
-rw-r--r--docs/implementation/primitive/replicate.html18
-rw-r--r--docs/implementation/primitive/sort.html24
-rw-r--r--docs/implementation/vm.html28
-rw-r--r--docs/index.html16
-rw-r--r--docs/keymap.html2
-rw-r--r--docs/running.html14
-rw-r--r--docs/spec/evaluate.html8
-rw-r--r--docs/spec/grammar.html2
-rw-r--r--docs/spec/index.html2
-rw-r--r--docs/spec/inferred.html30
-rw-r--r--docs/spec/literal.html2
-rw-r--r--docs/spec/primitive.html34
-rw-r--r--docs/spec/scope.html12
-rw-r--r--docs/spec/system.html22
-rw-r--r--docs/spec/token.html2
-rw-r--r--docs/spec/types.html2
-rw-r--r--docs/style.css13
-rw-r--r--docs/tutorial/combinator.html24
-rw-r--r--docs/tutorial/expression.html16
-rw-r--r--docs/tutorial/index.html2
-rw-r--r--docs/tutorial/list.html16
-rw-r--r--docs/tutorial/variable.html14
92 files changed, 595 insertions, 582 deletions
diff --git a/docs/commentary/bacon.html b/docs/commentary/bacon.html
index d2c7ca27..d9af91a9 100644
--- a/docs/commentary/bacon.html
+++ b/docs/commentary/bacon.html
@@ -4,7 +4,7 @@
<title>BQN: How to cook bacon</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">commentary</a></div>
-<h1 id="how-to-cook-bacon">How to cook bacon</h1>
+<h1 id="how-to-cook-bacon"><a class="header" href="#how-to-cook-bacon">How to cook bacon</a></h1>
<p><em>In BQN, bacon is American, or side, bacon. The method described here works best with medium to thick cuts, and leaves the bacon uniformly cooked and crispy. If you prefer parts of your bacon chewy and underdone, seek help elsewhere.</em></p>
<p>Begin with a heated pan at least as wide as the length of the bacon. Prefer cast iron. Cook somewhat hotter than medium, but in order to avoid sticking, don't let the pan reach full heat before starting. However, there is never any need to lubricate the pan, as grease from the cooking bacon will soon serve this purpose.</p>
<p>Use metal tongs to hold and move strips of bacon during cooking. Lay three strips of bacon parallel in the center of the pan, and after a minute or two place three at a right angle to these, on top of them. After another few minutes, flip the first strips from the bottom. This is accomplished by pulling each one out from under the top strips by the end, then setting it back on top upside-down with that end on the opposite side of the pan. For more even cooking you might also rotate (<code><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>⌽</span></code>) the three strips, so that the center one ends up on one side and one of the side strips ends up in the faster-cooking center.</p>
diff --git a/docs/commentary/fanart.html b/docs/commentary/fanart.html
index 6b005248..d20de25a 100644
--- a/docs/commentary/fanart.html
+++ b/docs/commentary/fanart.html
@@ -4,7 +4,7 @@
<title>BQN art</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">commentary</a></div>
-<h1 id="bqn-art">BQN art</h1>
+<h1 id="bqn-art"><a class="header" href="#bqn-art">BQN art</a></h1>
<p><a href="https://codeberg.org/wezl">Wezl</a> has provided a view into the BQN programmer in 𝕩e's typical place of residence.</p>
<p><a href="https://ermineii.github.io/paste/#0fZExDoMwDEX3nOKPZPIZWCJ54gA18gWQuvb4dSghjtP2C2XgPcX4k3BHQ9JNCCGSJrSqrhGyl@R6N1H250w3bMD@neph3@lueAaB6lI2uQkUOJPAHm48DjDwqufIqfzMubuvy27XvszVztAnk6p4oypj48yHZubxDywIDiM4yKm13iQphYZZZyWCZe8OCqTPf@RPa6J/Qm8%23DYs7DoMwEAV7n@J1fCQMQenSYeUQlICXZCXYEHuROD4rTTWjWX@iZTHz5@CrqF5YeSOZdjL3Fz8l9XqpBefaGvrlDKNcKgSKiRfCO@0sxIy@6x8OwGZWMkWcEinZQwihGUY8fYe6vQE">Depiction</a>, <a href="https://ermineii.github.io/paste/#0jZA7DsQgDER7TuFyU/kMKUCytsgBMPIFIm27x18gJHxDdoQoeKPBHgVZUktlglCLVYdWkbWDVHg4PXWUyrunG2wAbkxl93MWCZ/GgGEn//NpwIYTMvhDJ28/8OAb7pqjuVXcPbfls6/xiuqKOglFuHZES/FCtMtCtSVOUnkIHj1sDMLAw/ByLjUMBvgYz1q7HEsYp3XYi2UiX4q62nuPlbieSk0jmij4I@k@7gc%23Fcu7CsJAEIXhfp/ikCYXcBODYBFsDD6BlWXcncSBzRg3I0Sf3hVO9R3@icTZVT@B7PgUvfKXcEJ2XDTrzF@K/M7Twltedhg5kAwzJXuJHaJa3TQdxtQV9MEr0gpXoicf2REucWYhZrRNuzcAQlJZyeMtnmJqCH2/O99wsA2q@gc">remodel</a>, <a href="https://ermineii.github.io/paste/#07ZhLbuMwDIavInTVAAV4hmwM/Cujm26qQBco0gFmk@MPqYdFSZbtboJMKsFxYPK3HuRHR87ni1maq5q9Li4yVbM2exfn2blz64aWWRuNrR/6vOKezWzMpeN2Xzxh1cd3rSBZngyfJFQrQOyVD5KkGYY9NzlXApq6LQZCx0@GcHldS7SKGIM4/laLgqpMBPDlTkCdmFdTqWAqlTlxXykXSWbtNFExZAgS614vWWYmtuR5fJ5iKK11G41e3gZqd0aNfAgK1lrUINM1JWstajwPRs0Am6ixm1ErVSuoMWlmmkzJWouakGY0awO1R0WNYgQ0aw1qTFoQFrA1rEFWYR1MwVEDGzuDqsStoQ3pqsCtoS3ApnEbtD0obbTkV@FW0yawRaXGraZNpiEqLwS6uInLy2oua94QhxSdJq4GLvGmiBvA/ffAiWCXN57OEdw8Skdpuw3afh1t4T3ikXHzT8zB21PwRpE39mwChwQcNoFDAg47wIUNIxNHx4ibBnHPQlz4p8TaXeQQkMMOcgjIYR@5sNW70WDu1zHH87X2CHMQ5rDLHI4zJ@0odGYw90TMUQZgBzqkr23matUWcn4Cd0DOUyP3XAuT31hURoqbx2tlK2FLtrNOXk7finFaU0bEUmK1kdaU2DH6pVdG/ydroXQOPpx@q7SYWad5gy9UUDUULdv1@A7gzUzBzMu@5R2YFyOMnzdc0TrLtUPaz6cuQk6R9u9BndIMVbJqxeKmRZzMAYFDIcvGzGiRnIWzwroqLY1OGSklV7HxnZ9TH@X9yUwlmt5KNcTyNGnI5h7FNorgvkXw/oMieB9FMIpg/BKMIhhF8EBFINerhRDCs1oO/qWhVxSO@qUh57lXIaHjTp3w8adbLerOpmb4@NutHN8RjfpZq5/LPw%23PY5NT8MwDIbv/RVWL2kHS8s0CYl@HKiQOMAJLki7ZIlXDKkTNZlE@fWkDGH5ZPl9nndE1jLExaI8OY4v9I3Qgbj1UTSwXgpxpNHTlygbCBiDRzRFLet92WTwN@MKIWacH1@fn1I@b/2MQKYTimlSkRwL@LV0YoVuT2oiu9zBIb/QD/k1TI5d8Eqj6Nsq5fv86t8ACXk8x@gYHGtL@rMT3qqlKEXvwYKCpa0uD32eipNFVhMWwqsQUa4t5EdILVLrLKs2EN8pQNpClzCgmUkjPMwTMRLBrt7drOrkQQ5o4MwG55RBGIbt/RvsZQ2b6gc">animation</a>.</p>
<p><em>Links contain the encoded art, which is CC-BY 4.0: see the &quot;setup JS&quot; pane.</em></p>
diff --git a/docs/commentary/history.html b/docs/commentary/history.html
index d4b01d0b..22197c09 100644
--- a/docs/commentary/history.html
+++ b/docs/commentary/history.html
@@ -4,14 +4,14 @@
<title>BQN's development history</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">commentary</a></div>
-<h1 id="bqns-development-history">BQN's development history</h1>
+<h1 id="bqns-development-history"><a class="header" href="#bqns-development-history">BQN's development history</a></h1>
<p>I (<a href="https://mlochbaum.github.io/">Marshall Lochbaum</a>) began designing BQN as a &quot;fixed APL&quot; in collaboration with my colleagues at <a href="https://aplwiki.com/wiki/Dyalog_Ltd.">Dyalog</a>, and decided to take it on as a personal project when I chose to leave the company several months later in early 2020. BQN is influenced by my array language background, previous work in programming design, studies of APL history, and design discussions before and after starting work on the language. I developed most of the novel functionality in BQN, and am at the end of the day the one who writes the spec, but it includes significant contributions from collaborators, most notably <a href="https://github.com/dzaima">dzaima</a> and <a href="https://github.com/abrudz">Adám Brudzewsky</a>.</p>
-<h3 id="background">Background</h3>
+<h3 id="background"><a class="header" href="#background">Background</a></h3>
<p>I learned <a href="https://aplwiki.com/wiki/J">J</a> as my first computer programming language in 2009, and it's been my language of choice for personal projects from then until I started working with BQN. My first exposure to APL was <a href="https://aplwiki.com/wiki/Dyalog_APL">Dyalog APL</a>, which I began learning gradually after starting work at Dyalog in 2017; while I understand every primitive in detail (I've substantially reimplemented most of them), I've never written even a medium-sized script with it. I studied APL's history and many other APL dialects while helping to create the new <a href="https://aplwiki.com/wiki/Main_Page">APL Wiki</a> in late 2019. In particular, I found <a href="https://aplwiki.com/wiki/A+">A+</a> to be a very sound design and nominally took it as the starting point for BQN. As a result, BQN draws more from a general concept of APL than any particular dialect.</p>
<p>I have been working on programming language design since 2011 or earlier. The start of my first major language, <a href="https://github.com/mlochbaum/ILanguage">I</a>, might be placed in 2012 when I published a paper on its approach to mapping, unifying J's trains and function rank. By this time I had worked with several languages including Python and Factor, and implemented little interpreters in Java, Scala, and Haskell. There are many new ideas in I and some of them have made it to BQN, but the language has served mainly as a warning: its pure and simple syntax and approach to array and tacit programming lead to a rigidity that seems to take over from any human designer. And the end result is not usable. So I sought out constructs that would give back some control, like APL's two-layer function/operator syntax and explicit functions (although Dyalog has lexical scoping, it is crippled by the lack of closures and I ended up learning proper use of lexical scoping from Javascript—I've never done real work with any actual Lisp). Another language that I envisioned before BQN, called Iridescence, goes further in this direction, with Python-like syntax that is &quot;noisy&quot; relative to APL. It remains purely theoretical (I'll implement it some day) but has already had an influence on some BQN primitives.</p>
<p>The idea of a &quot;fixed APL&quot; is always percolating in the APL community, because of its long history and strong <a href="https://aplwiki.com/wiki/Backwards_compatibility">backwards compatibility</a> requirements. BQN arose out of sessions by the Young APLers Group (YAG, unfortunately) inside Dyalog after I suggested that wild ideas for the future of APL might be a good topic for meetings (the previous order of business, right at YAG's formation, was creating the APL Wiki). At these meetings <a href="https://github.com/abrudz">Adám</a>, <a href="https://rikedyp.uk/">Richard Park</a>, <a href="https://www.dyalog.com/blog/2019/08/welcome-nathan-rogers/">Nathan Rogers</a>, and sometimes others discussed and proposed many ideas including the sketch I created that ended up as the blueprint of BQN. When I left Dyalog (putting an end to any notions of using those ideas at the company), I joined <a href="https://chat.stackexchange.com/rooms/52405/the-apl-orchard">The APL Orchard</a> forum, which most YAG members already used, to post about BQN. <a href="https://github.com/dzaima">dzaima</a> quickly began building his own BQN implementation using the existing dzaima/APL, and has discussed and contributed to most BQN design decisions since.</p>
<p><a href="https://shapecatcher.com/index.html">Shapecatcher</a> is an essential resource for finding appropriate unicode characters. I've been using it heavily, and so has everyone else interested in glyph choices.</p>
-<h2 id="timeline">Timeline</h2>
+<h2 id="timeline"><a class="header" href="#timeline">Timeline</a></h2>
<p>The table documents when I encountered features or interesting decisions in BQN. The &quot;source&quot; field indicates how I became aware of the idea while the &quot;person&quot; field gives, to the best of my knowledge, the original inventor (in blank entries and those that start with &quot;w/&quot;, I am an inventor).</p>
<table>
<thead>
@@ -201,26 +201,26 @@
</tr>
</tbody>
</table>
-<h2 id="features">Features</h2>
+<h2 id="features"><a class="header" href="#features">Features</a></h2>
<p>Discussion of specific features from the timeline above, with more detail.</p>
-<h4 id="structural-under">Structural Under</h4>
+<h4 id="structural-under"><a class="header" href="#structural-under">Structural Under</a></h4>
<p>I developed structural Under in 2017 and 2018. By <a href="https://aplwiki.com/wiki/Dyalog_user_meeting#Dyalog_.2717">Dyalog '17</a> I had figured out the basic concept, and sometime later I discovered it could be unified with J's Under operator, which was being considered for inclusion in Dyalog.</p>
-<h4 id="prefix-suffix-and-windows">Prefix, Suffix, and Windows</h4>
+<h4 id="prefix-suffix-and-windows"><a class="header" href="#prefix-suffix-and-windows">Prefix, Suffix, and Windows</a></h4>
<p>I discovered Prefix, Suffix, and Windows while thinking about Iridescence, probably in 2019. They are influenced by J's Prefix, Suffix, and Infix operators, but in Iridescence, with no distinction between functions and arrays, Prefix is just the Take function, and Suffix is Drop!</p>
-<h4 id="array-notation">Array notation</h4>
+<h4 id="array-notation"><a class="header" href="#array-notation">Array notation</a></h4>
<p>APL <a href="https://aplwiki.com/wiki/Array_notation">array notation</a> has been developed mainly by Phil Last and later Adám Brudzewsky. The big difference from array literals in other languages is the idea that newline should be a separator equivalent to <code><span class='Separator'>⋄</span></code>, as it is in ordinary APL execution including dfns. The changes I made for BQN, other than the ligature <code><span class='Ligature'>‿</span></code> discussed below, were to use dedicated bracket pairs <code><span class='Bracket'>⟨⟩</span></code> and <code><span class='Value'>[]</span></code>, and to allow <code><span class='Separator'>,</span></code> as a separator.</p>
<p>I picked out the ligature character <code><span class='Ligature'>‿</span></code> between YAG meetings, but I think Richard Park was most responsible for the idea of a &quot;shortcut&quot; list notation.</p>
-<h4 id="double-struck-special-names">Double-struck special names</h4>
+<h4 id="double-struck-special-names"><a class="header" href="#double-struck-special-names">Double-struck special names</a></h4>
<p>There was a lot of discussion about names for arguments at YAG (no one liked alpha and omega); I think Nathan Rogers suggested using Unicode's mathematical variants of latin letters and I picked out the double-struck ones. My impression is that we were approaching a general concensus that &quot;w&quot; and &quot;x&quot; were the best of several bad choices of argument letters, but that I was the first to commit to them.</p>
-<h4 id="assert-primitive">Assert primitive</h4>
+<h4 id="assert-primitive"><a class="header" href="#assert-primitive">Assert primitive</a></h4>
<p>Nathan Rogers suggested that assertion should be made a primitive to elevate it to a basic part of the language. I used J's <code><span class='Value'>assert</span></code> often enough for this idea to make sense immediately, but I think it was new to me. He suggested the dagger character; I changed this to the somewhat similar-looking <code><span class='Function'>!</span></code>. The error-trapping modifier <code><span class='Modifier2'>⎊</span></code> is identical to J's <code><span class='Value'>::</span></code>, but J only has the function <code><span class='Value'>[:</span></code> to unconditionally throw an error, with no way to set a message.</p>
-<h4 id="context-free-grammar">Context-free grammar</h4>
+<h4 id="context-free-grammar"><a class="header" href="#context-free-grammar">Context-free grammar</a></h4>
<p>In YAG meetings, I suggested adopting <a href="https://aplwiki.com/wiki/APL%5Civ">APL\iv</a>'s convention that variable case must match variable type in order to achieve a context-free grammar. Adám, a proponent of case-insensitive names, pointed out that the case might indicate the type the programmer wanted to use instead of the value's type, creating cross roles.</p>
-<h4 id="headers">Headers</h4>
+<h4 id="headers"><a class="header" href="#headers">Headers</a></h4>
<p>The idea of dfn headers is very common in the APL community, to the extent that it's hard to say which proposals lead to the form now used in BQN. A+ has headers which are similar but go outside the braces, and BQN headers aren't all that different from tradfn headers either. I found when creating BQN2NGN that ngn/apl allows dfns to include a monadic and dyadic case, separated by a semicolon. Some time later I realized that the ability to include multiple bodies is very powerful with headers because it enables a primitive sort of pattern matching, something I already wanted to squeeze into the language. I discussed this with dzaima, who added header support to dzaima/BQN almost immediately and was thus able to investigate the details of the format.</p>
-<h4 id="group">Group</h4>
+<h4 id="group"><a class="header" href="#group">Group</a></h4>
<p>I've been fiddling with the idea of function or map inversion (preimage creation, really) for several years, and in fact independently discovered something very similar to K's Group function <code><span class='Function'>=</span></code>, which is an excellent tool for languages that have dictionaries. I liked this approach as it didn't have all the ordering issues that J's Key has. However, I also didn't really want to introduce dictionaries to BQN, as they have a very strange relation to multidimensional arrays—are arrays like dictionaries with multiple keys, or dictionaries with a single vector key? I've been a proponent of <code><span class='Function'>/</span><span class='Modifier'>⁼</span></code> as a programming tool for <a href="http://www.jsoftware.com/pipermail/programming/2010-September/020302.html">much longer</a>. I'd also developed a sophisticated view of <a href="https://aplwiki.com/wiki/Partition_representations">partition representations</a> while studying an extension to Dyalog's Partitioned Enclose proposed by Adám and included in Dyalog 18.0. I finally put all this together while fighting with Key to develop BQN's compiler: I realized that if the &quot;key&quot; argument was restricted to array indices, then it would make sense for the result to be an array, and that this was simply the &quot;target indices&quot; partition representation minus the requirement that those indices be nondecreasing.</p>
-<h4 id="before--and-after-">Before <code><span class='Modifier2'>⊸</span></code> and After <code><span class='Modifier2'>⟜</span></code></h4>
+<h4 id="before--and-after-"><a class="header" href="#before--and-after-">Before <code><span class='Modifier2'>⊸</span></code> and After <code><span class='Modifier2'>⟜</span></code></a></h4>
<p>It happens that BQN's Before (<code><span class='Modifier2'>⊸</span></code>) and After (<code><span class='Modifier2'>⟜</span></code>) modifiers are identical to I's hook (<code><span class='Value'>h</span></code>) and backhook (<code><span class='Function'>H</span></code>), but it took some time to arrive at this point. The hook function in I comes from J's 2-train, also called hook (I had probably seen Roger Hui's <a href="https://code.jsoftware.com/wiki/Essays/Hook_Conjunction%3F">remarks</a> that he would prefer hook to be a conjunction, with 2-trains indicating composition instead, but I don't think Roger has proposed a reverse hook). But the model for Before and After was initially APL's Compose (<code><span class='Modifier2'>∘</span></code>) and the complement <a href="https://aplwiki.com/wiki/Reverse_Compose">Reverse Compose</a> that Adám created for Extended Dyalog APL. I noticed the similarity to Bind and decided to unify Binds and Composes at around the same time that I picked the symbols <code><span class='Modifier2'>⊸⟜</span></code>. However, I kept the idea that the one-argument case should be simple composition unless the bound operand had a subject role. Eventually I decided the violation of <a href="problems.html#syntactic-type-erasure">syntactic type erasure</a> was too inconsistent and settled on the current definition. Now I think these forms are better even ignoring constant functions, although I do occasionally run into cases where I'd like to use APL's Compose.</p>
-<h4 id="constant-modifier">Constant modifier</h4>
+<h4 id="constant-modifier"><a class="header" href="#constant-modifier">Constant modifier</a></h4>
<p>The idea of a constant function is nothing new; I named it <code><span class='Value'>k</span></code> in I, taking influence from the <a href="https://en.wikipedia.org/wiki/SKI_combinator_calculus">SKI</a> calculus. It was actually Adám who suggested adding it to Dyalog with the glyph <code><span class='Value'>⍨</span></code>, although I was the one who campaigned for it and introduced it to the public in version 18.0. It wasn't initially clear that a dedicated modifier was needed in BQN because the treatment of data types as constant functions seems to fill this role, but I eventually found that I needed a constant function returning a function too often to leave it out.</p>
diff --git a/docs/commentary/index.html b/docs/commentary/index.html
index c85c41fe..f5f3d2e0 100644
--- a/docs/commentary/index.html
+++ b/docs/commentary/index.html
@@ -4,7 +4,7 @@
<title>BQN commentary</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a></div>
-<h1 id="bqn-commentary">BQN commentary</h1>
+<h1 id="bqn-commentary"><a class="header" href="#bqn-commentary">BQN commentary</a></h1>
<p>Documents in this directory give context on how BQN was designed or remark on aspects of the language.</p>
<ul>
<li><a href="problems.html">Problems with BQN</a></li>
diff --git a/docs/commentary/orchard.html b/docs/commentary/orchard.html
index 12b5b9a9..0f2aaf42 100644
--- a/docs/commentary/orchard.html
+++ b/docs/commentary/orchard.html
@@ -4,7 +4,7 @@
<title>BQN: The APL Orchard</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">commentary</a></div>
-<h1 id="the-apl-orchard">The APL Orchard</h1>
+<h1 id="the-apl-orchard"><a class="header" href="#the-apl-orchard">The APL Orchard</a></h1>
<p>BQN users have largely moved to Matrix or Discord chat, and I no longer recommend using the APL Orchard (perhaps also known by the shortcut URL apl.chat). Chat options are discussed <a href="../index.html#where-can-i-find-bqn-users">in the README</a>; this page gives the reasons we switched forums.</p>
<p>StackExchange chat requires a StackExchange account with enough reputation, or moderator-granted permissions, to talk, and sets a reputation threshold for some minor features within the chat as well. Those who don't use StackExchange have to make an account and send an email to get permission. While this filtering probably leads to a more dedicated forum base, it does this at the expense of keeping out a lot of people, including many who have a lot to contribute. I think this isn't a good tradeoff, and this seems to be the community concensus as well.</p>
<p>StackExchange is not built for bots, and existing tooling for it is not very good. At the time of writing the bot that used to link the APL Orchard to IRC #apl is able to write but not read posts, so that the link only runs one way.</p>
diff --git a/docs/commentary/primitive.html b/docs/commentary/primitive.html
index fbbd4d5d..87ef3a21 100644
--- a/docs/commentary/primitive.html
+++ b/docs/commentary/primitive.html
@@ -4,9 +4,9 @@
<title>BQN: What is a primitive?</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">commentary</a></div>
-<h1 id="what-is-a-primitive">What is a primitive?</h1>
+<h1 id="what-is-a-primitive"><a class="header" href="#what-is-a-primitive">What is a primitive?</a></h1>
<p>People sometimes wonder how the set of primitives in BQN was chosen. Outsiders to array programming might assume that the &quot;big idea&quot; of APL is just to take the most common tasks and write them with symbols instead of names—even Dijkstra said something like this, calling APL a &quot;bag of tricks&quot;! I don't think this is quite right, so I'd like to explain my personal view on why it makes sense to call a few special operations &quot;primitives&quot; and give them dedicated symbols. While I think this overlaps some with the ideas of other array designers, I am speaking only for myself here.</p>
-<h2 id="names-versus-symbols">Names versus symbols</h2>
+<h2 id="names-versus-symbols"><a class="header" href="#names-versus-symbols">Names versus symbols</a></h2>
<p>Much of this text will be about why various functions <em>shouldn't</em> be considered primitives, so it makes sense to start with a discussion of the disadvantages of symbols and why we wouldn't want everything to use them.</p>
<ul>
<li>Words convey meaning more precisely</li>
@@ -16,11 +16,11 @@
</ul>
<p>A broad theme is that words—that is, language rather than notation—offer more possibilities and shades of meaning. If there are two related concepts, it's often possible to give them names that make both the relation and the difference clear (say, <code><span class='Function'>KeepBefore</span></code> and <code><span class='Function'>KeepUpTo</span></code>). With symbols this is more difficult: only a few broad relations like mirror reflection (which is error prone!) and juxtaposition are usable. But nuanced words can also be a liability. If there is really only one possibility, then a well-chosen symbol might indicate it better and be easier to remember.</p>
<p>In BQN, syntactic role is also a factor. Letter casing and underscores allow any word to be written with any role, while a primitive has a fixed role. If a value might be either called as a function or passed as an argument, this will be easier if it's named.</p>
-<h2 id="primitive-philosophy">Primitive philosophy</h2>
+<h2 id="primitive-philosophy"><a class="header" href="#primitive-philosophy">Primitive philosophy</a></h2>
<p>Is language design a process of discovery or invention? A bit of both, of course, but I think primitive design should be mostly discovery. That is, if a function feels invented—or worse, engineered—it's not a good fit for a BQN primitive. Discovery means that the thing in question is in some sense external to the person who describes it, so that if two different people discover something then it will be the exact same thing. An invented thing will always bear marks of its inventor, from the little decisions that could have been made differently.</p>
<p>It's not always so clear cut, and there's a little irony in that the <em>collection</em> of all the primitives in a language is definitely engineered. While I think it's a good idea to give symbols to things that are more primitive-like and words to things that are less primitive-like, this leaves room to use symbols relatively more as in APL, or words more as in Python, to focus on different functionality to provide, or to select different primitives when there are a few that provide similar functionality.</p>
<p>I do think some acts of engineering are okay, if the purpose is only to make the underlying primitive functionality more accessible. For example, Range (<code><span class='Function'>↕</span></code>) combines two primitive functions with disjoint domains, and Rank (<code><span class='Modifier2'>⎉</span></code>) sticks a few numbers into an arbitrarily-ordered list. I still view these as a little unfortunate, but acceptable for added convenience.</p>
-<h2 id="primitive-practice">Primitive practice</h2>
+<h2 id="primitive-practice"><a class="header" href="#primitive-practice">Primitive practice</a></h2>
<p>Are there primitives out there waiting to be discovered? I think so: fundamental concepts like addition, mapping, or joining one list to another would be reinvented by any society that could develop programming, and would have exactly the same meaning. But this is sort of a vague assertion, and I have no intention of getting into the question of whether anything &quot;actually&quot; exists. A more practical approach is to start with some properties that I associate with high-quality tools of thought:</p>
<ul>
<li>Simple mathematical description (or better, more than one)</li>
@@ -38,7 +38,7 @@
<li>Relationships between primitives can be used in proofs</li>
</ul>
<p>Again, some properties seem intuitively connected to the ones above but for others the connection isn't so obvious. They are broad patterns that I've observed over years of programming and designing.</p>
-<h2 id="arithmetic-primitives">Arithmetic primitives</h2>
+<h2 id="arithmetic-primitives"><a class="header" href="#arithmetic-primitives">Arithmetic primitives</a></h2>
<p>I can point out that there is already a class of functions that anyone would agree fit the description above, which are the arithmetic functions <code><span class='Function'>+-×÷</span></code>. They are indispensable tools, and it's interesting to note that they are also represented with symbols (not necessarily the same ones) in nearly every language.</p>
<p>Why is it that a function as broadly useful as addition should exist at all? It's one example of mathematics (and even if you don't consider programming to be mathematics, it can certainly be described by mathematics) being more structured than direct reasoning can explain. This happens because math imposes structure on itself, as facts about one mathematical object can constrain the behavior of another. The structure might manifest as theorems mathematicians can prove, theorems they can't, or the fuzzier ideas sometimes called &quot;folk theorems&quot;. A good illustration is <a href="https://en.wikipedia.org/wiki/Ulam%27s_spiral">Ulam's spiral</a>, the tendency of prime numbers to follow arithmetic patterns. There are a few proofs about specific patterns, and conjectures about others. The broader folk theorem that primes will show patterns in <em>any</em> simple arithmetic arrangement is too vague to even prove, but has lots of supporting evidence and is of practical use to mathematicians working in the field.</p>
<svg viewBox='-192.8 -64.8 688 208'>
@@ -71,7 +71,7 @@
<p>Folk theorems are a lot like design patterns in programming, in that they can guide or describe an implementation but don't appear in the code directly. A primitive, in contrast, is a precisely specified operation, so it can be used for both organization and in the actual code.</p>
<p>Primitives obey mathematical rules—for example that subtraction undoes addition. A sequence of primitives can be manipulated algebraically using these rules, changing it to a different sequence that does the same computation. Symbols are a good fit for algebraic manipulation because the lower overhead required to read them makes it easier to recognize groups of symbols and move them around. The programmer still has to choose what changes to make, but primitive symbols make it easier to perform them correctly.</p>
-<h2 id="programming-with-primitives">Programming with primitives</h2>
+<h2 id="programming-with-primitives"><a class="header" href="#programming-with-primitives">Programming with primitives</a></h2>
<p>APL adds a few arithmetic primitives that aren't common in other languages, but its main contribution is array primitives. Some later APL-family languages including BQN also add combinators—tacit primitives for working with functions (mathematics does have the composition <code><span class='Modifier2'>∘</span></code>; the difference is that APL's combinators are for functions of one or two arguments).</p>
<p>The main reason for the three domains of arithmetic, functions, and arrays is simply that these are the main types used for computations in BQN. It might be interesting to note that there are no namespace primitives. In BQN namespaces are used for code organization, not computation. Something similar happens with arrays in C: they aren't the object of computation, so while there are operators for working with pointers (addition, referencing and dereferencing), there aren't any for arrays. One step that makes BQN arrays more suitable to have primitives defined on them is that they are immutable.</p>
<p>These days many popular langauges have standard functions or methods for working with arrays, like concatenation, reversal, and mapping. But they're usually treated more as utilities than primitives, and in some cases have extra functionality tacked on that makes them more complicated and less composable (for example Javascript's mapping passes extra arguments to the operand).</p>
diff --git a/docs/commentary/problems.html b/docs/commentary/problems.html
index 8647bd09..c6da5787 100644
--- a/docs/commentary/problems.html
+++ b/docs/commentary/problems.html
@@ -4,35 +4,35 @@
<title>Problems with BQN</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">commentary</a></div>
-<h1 id="problems-with-bqn">Problems with BQN</h1>
+<h1 id="problems-with-bqn"><a class="header" href="#problems-with-bqn">Problems with BQN</a></h1>
<p>Every language has some issues that everyone can agree make programming harder. Sometimes there is a simple solution that has not yet been discovered; sometimes the problem is inherent to the language because it's caused by fundamental choices (or anywhere in between). Below are problems I have identified in BQN, ordered from what I consider the most severe to the least. This is independent of whether the issue can be solved—if it somehow went away, how much better would the language be?</p>
<p>I've omitted problems that are obviously addressed by speculated extensions. Of course adding A fixes the problem &quot;doesn't have A&quot;. Problems that only exist in reference to some existing convention (e.g. unfamiliarity to APLers) are also left out, unless the convention manifests technically (Unicode support).</p>
-<h3 id="empty-arrays-lose-type-information">Empty arrays lose type information</h3>
+<h3 id="empty-arrays-lose-type-information"><a class="header" href="#empty-arrays-lose-type-information">Empty arrays lose type information</a></h3>
<p>A pretty fundamental problem with dynamically-typed array languages. Prototypes are intended to solve it, but they don't really. It doesn't help that the notion of type is fluid: elements of an array in one moment can be axis lengths in the next; did the numeric value go from not being type information to being type information? Inferred type might help here, particularly the ability of one part of the program to ask another part for type information during compilation. But that needs to be specified if programmers are going to rely on it, which sounds difficult.</p>
-<h3 id="incoherent-monad-dyad-builtin-pairs">Incoherent monad-dyad builtin pairs</h3>
+<h3 id="incoherent-monad-dyad-builtin-pairs"><a class="header" href="#incoherent-monad-dyad-builtin-pairs">Incoherent monad-dyad builtin pairs</a></h3>
<p>BQN inherits the functions <code><span class='Function'>+×⌊⌈|</span></code>, and adds the functions <code><span class='Function'>∧∨&lt;&gt;≠≡≢↕⍷</span></code>, that are only paired for their glyphs and not for any other reason (that is, both function valences match the symbol but they don't match with each other). I find there are just not enough good glyphs to separate all of these out, but I'm sure the pairings could be improved.</p>
-<h3 id="glyphs-are-hard-to-type">Glyphs are hard to type</h3>
+<h3 id="glyphs-are-hard-to-type"><a class="header" href="#glyphs-are-hard-to-type">Glyphs are hard to type</a></h3>
<p>There's been a lot of work done on this. Still there, still a problem. On the other hand, glyphs are easy to read, and write by hand!</p>
-<h3 id="syntactic-type-erasure">Syntactic type erasure</h3>
+<h3 id="syntactic-type-erasure"><a class="header" href="#syntactic-type-erasure">Syntactic type erasure</a></h3>
<p>A programmer can call a modifier on either a syntactic function or subject, but there's no way to know within the modifier which syntax that operand had. Maybe this is a better design, but it doesn't feel quite right that <code><span class='Value'>f</span><span class='Modifier'>˜</span></code> is <code><span class='Value'>f</span></code>-Swap if <code><span class='Value'>f</span></code> has a function value. The subject syntax suggests it should be Constant. Instead the Constant modifier <code><span class='Modifier'>˙</span></code> has been added partially to mitigate this.</p>
-<h3 id="control-flow-substitutes-have-awkward-syntax">Control flow substitutes have awkward syntax</h3>
+<h3 id="control-flow-substitutes-have-awkward-syntax"><a class="header" href="#control-flow-substitutes-have-awkward-syntax">Control flow substitutes have awkward syntax</a></h3>
<p>At the moment BQN has no control structures, instead preferring modifiers, function recursion, and headers. When working with pure functions, these can be better than control structures. For more imperative programming they're a lot worse. For example, it's natural to have two arguments for small structures, but that becomes unreadable for larger ones. However, predefined functions acting on functions can cover a lot of ground for the imperative programmer; see <a href="../doc/control.html">Control flow in BQN</a>.</p>
<p>One particular sore point with Repeat (<code><span class='Modifier2'>⍟</span></code>) and Choose (<code><span class='Modifier2'>◶</span></code>) is that the condition and action(s) always apply to the same set of arguments. Often you'd like them to apply to completely different things: this seems like the sort of thing that split compose <code><span class='Function'>F</span><span class='Modifier2'>⊸</span><span class='Function'>G</span><span class='Modifier2'>⟜</span><span class='Function'>H</span></code> solved for trains, but here there's no such solution.</p>
-<h3 id="search-function-depth">Search function depth</h3>
+<h3 id="search-function-depth"><a class="header" href="#search-function-depth">Search function depth</a></h3>
<p>The simplest way to define a search function like Index Of is to require the left argument to be a list, and search for an element that matches the right argument. But this means you can only search for one element at a time, which is annoying and doesn't work for Progressive Index Of. So we instead treat the searched argument as a list of major cells. Then we decide to search for cells of the other argument that have the same rank as those cells, since only cells with the same rank can match. That's a little strange for Bins, where it still makes sense to compare cells of different ranks. Furthermore, the result of any search function is always an array. To search for a single element and get an plain number, you need something like <code><span class='Value'>list</span><span class='Modifier2'>⊸</span><span class='Function'>⊐</span><span class='Modifier2'>⌾</span><span class='Function'>&lt;</span><span class='Value'>elt</span></code>.</p>
-<h3 id="right-to-left-multi-line-functions-go-upwards">Right-to-left multi-line functions go upwards</h3>
+<h3 id="right-to-left-multi-line-functions-go-upwards"><a class="header" href="#right-to-left-multi-line-functions-go-upwards">Right-to-left multi-line functions go upwards</a></h3>
<p>If you include multiple multi-line functions in what would otherwise be a one-liner, the flow in each function goes top to bottom but the functions are executed bottom to top. I think the fix here is to just say give your functions names and don't do this.</p>
-<h3 id="tacit-and-one-line-functions-are-hard-to-debug">Tacit and one-line functions are hard to debug</h3>
+<h3 id="tacit-and-one-line-functions-are-hard-to-debug"><a class="header" href="#tacit-and-one-line-functions-are-hard-to-debug">Tacit and one-line functions are hard to debug</a></h3>
<p>This problem hasn't manifested yet as BQN has no debugger, but it's something to keep in mind. Traditional line-by-line debuggers don't work when the line is doing so much work. Something like J's dissect or some kind of hybrid would probably do better.</p>
-<h3 id="hard-to-search-part-of-an-array-or-in-a-different-order">Hard to search part of an array or in a different order</h3>
+<h3 id="hard-to-search-part-of-an-array-or-in-a-different-order"><a class="header" href="#hard-to-search-part-of-an-array-or-in-a-different-order">Hard to search part of an array or in a different order</a></h3>
<p>This includes index-of-last, and searching starting at a particular index, when the desired result indices are to the array to be seached <em>before</em> it is modified. Given indices <code><span class='Value'>i</span></code> into an array <code><span class='Value'>𝕨</span></code> (for example <code><span class='Function'>⌽↕≠</span><span class='Value'>𝕨</span></code> or <code><span class='Value'>a</span><span class='Function'>+↕</span><span class='Value'>b</span></code>), this section can be searched with <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='Modifier'>˜</span><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>. But this is clunky and difficult for the implementation to optimize.</p>
-<h3 id="subtraction-division-and-span-are-backwards">Subtraction, division, and span are backwards</h3>
+<h3 id="subtraction-division-and-span-are-backwards"><a class="header" href="#subtraction-division-and-span-are-backwards">Subtraction, division, and span are backwards</a></h3>
<p>The left argument feels much more like the primary one in these cases (indeed, this matches the typical left-to-right ordering of binary operators in mathematics). The commonly-paired <code><span class='Function'>⌊</span><span class='Modifier2'>∘</span><span class='Function'>÷</span></code> and <code><span class='Function'>|</span></code> have opposite orders for this reason. Not really fixable; too much precedent.</p>
-<h3 id="nothing--interacts-strangely-with-before-and-after">Nothing (<code><span class='Nothing'>·</span></code>) interacts strangely with Before and After</h3>
+<h3 id="nothing--interacts-strangely-with-before-and-after"><a class="header" href="#nothing--interacts-strangely-with-before-and-after">Nothing (<code><span class='Nothing'>·</span></code>) interacts strangely with Before and After</a></h3>
<p>Since <code><span class='Value'>𝕨</span><span class='Function'>F</span><span class='Modifier2'>⊸</span><span class='Function'>G</span><span class='Value'>𝕩</span></code> is <code><span class='Paren'>(</span><span class='Function'>F</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>G</span><span class='Value'>𝕩</span></code> and <code><span class='Value'>𝕨</span><span class='Function'>F</span><span class='Modifier2'>⟜</span><span class='Function'>G</span><span class='Value'>𝕩</span></code> is <code><span class='Value'>𝕨</span><span class='Function'>F</span> <span class='Function'>G</span><span class='Value'>𝕩</span></code> in the dyadic case, we might expect these to devolve to <code><span class='Function'>G</span><span class='Value'>𝕩</span></code> and <code><span class='Function'>F</span> <span class='Function'>G</span><span class='Value'>𝕩</span></code> when <code><span class='Value'>𝕨</span></code> is not present. Not so: instead <code><span class='Value'>𝕩</span></code> is substituted for the missing <code><span class='Value'>𝕨</span></code>. And Before and After are also the main places where a programmer might try to use <code><span class='Value'>𝕨</span></code> as an operand, which doesn't work either (the right way is the train <code><span class='Value'>𝕨</span><span class='Function'>F⊢</span></code>). It's also a little strange that <code><span class='Value'>v</span> <span class='Function'>F</span><span class='Modifier'>˜</span><span class='Nothing'>·</span></code> is <code><span class='Nothing'>·</span></code>, while <code><span class='Nothing'>·</span><span class='Function'>F</span> <span class='Value'>v</span></code> is <code><span class='Function'>F</span> <span class='Value'>v</span></code>.</p>
-<h3 id="cant-access-array-ordering-directly">Can't access array ordering directly</h3>
+<h3 id="cant-access-array-ordering-directly"><a class="header" href="#cant-access-array-ordering-directly">Can't access array ordering directly</a></h3>
<p>Only <code><span class='Function'>⍋⍒</span></code> use array ordering rather than just array equality or numeric ordering. Getting at the actual ordering to just compare two arrays is more difficult than it should be (but not <em>that</em> difficult: <code><span class='Function'>⥊</span><span class='Modifier2'>⊸</span><span class='Function'>⍋</span><span class='Modifier2'>⌾</span><span class='Function'>&lt;</span></code> is TAO <code><span class='Function'>≤</span></code>).</p>
-<h3 id="comparison-tolerance">Comparison tolerance</h3>
+<h3 id="comparison-tolerance"><a class="header" href="#comparison-tolerance">Comparison tolerance</a></h3>
<p>Kind of necessary for practical programming, but how should it be invoked or controlled? A system variable like <code><span class='Value'>⎕</span><span class='Function'>CT</span></code>? Per-primitive control? Both? Which primitives should use it?</p>
<table>
<thead>
@@ -50,112 +50,112 @@
</tr>
</tbody>
</table>
-<h3 id="no-access-to-fast-high-precision-sum">No access to fast high-precision sum</h3>
+<h3 id="no-access-to-fast-high-precision-sum"><a class="header" href="#no-access-to-fast-high-precision-sum">No access to fast high-precision sum</a></h3>
<p>Fold has a specific order of application, which must be used for <code><span class='Function'>+</span><span class='Modifier'>`</span></code>. But other orders can be both faster and more precise (in typical cases) by enabling greater parallelism. Generally ties into the question of providing precision control for a program: it could be fixed by a flag that enables BQN to optimize as long as the results will be at least as precise (relative to the same program in infinite precision) as the spec.</p>
-<h3 id="assert-has-no-way-to-compute-the-error-message">Assert has no way to compute the error message</h3>
+<h3 id="assert-has-no-way-to-compute-the-error-message"><a class="header" href="#assert-has-no-way-to-compute-the-error-message">Assert has no way to compute the error message</a></h3>
<p>In the compiler, error messages could require expensive diagnostics, and in some cases the message includes parts that can only be computed if there's an error (for example, the index of the first failure). However, Assert (<code><span class='Function'>!</span></code>) only takes a static error message, so you have to first check a condition, then compute the message, then call Assert with <code><span class='Number'>0</span></code> as its right argument. Very ugly. This is generally going to be an issue for high-quality tools built in BQN, where giving the user good errors is a priority.</p>
-<h3 id="high-rank-array-notation">High-rank array notation</h3>
+<h3 id="high-rank-array-notation"><a class="header" href="#high-rank-array-notation">High-rank array notation</a></h3>
<p>The proposed Dyalog array notation <code><span class='Value'>[]</span></code> for high-rank arrays: it's the same as BQN's lists <code><span class='Bracket'>⟨⟩</span></code> except it mixes at the end. This works visually because the bottom level—rows—is written with stranding. It also looks okay with BQN strands but clashes with BQN lists. At that point it becomes apparent that specifying whether something is a high-rank array at the top axes is kind of strange: shouldn't it be the lower axes saying to combine with higher ones?</p>
-<h3 id="list-splicing-is-fiddly">List splicing is fiddly</h3>
+<h3 id="list-splicing-is-fiddly"><a class="header" href="#list-splicing-is-fiddly">List splicing is fiddly</a></h3>
<p>It's common when manipulating text to want to replace a slice with a different slice with an unrelated length. Structural Under works well for this if the new slice has the same length but doesn't otherwise (an implementation could choose to support it, but <em>only</em> if the slice is extracted using two Drops, not Take). So in general the programmer has to cut off initial and final segments and join them to the new slice. If the new slice is computed from the old one it's much worse, as there will be duplication between the code to extract that slice and the other segments. The duplication can be avoided with Group using <code><span class='Function'>∾F</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>⊑</span><span class='Paren'>)(</span><span class='Value'>s</span><span class='Ligature'>‿</span><span class='Value'>e</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>, but this is a lot of work and will execute slowly without some special support. In fact, everything here is liable to run slowly, making too many copies of the unmodified part of the stream.</p>
<p>Dyalog's solution here (and dzaima/BQN's) is Regex, which is a nice feature but also an entire second language to learn.</p>
-<h3 id="cant-always-transfer-ambivalence-in-tacit-code">Can't always transfer ambivalence in tacit code</h3>
+<h3 id="cant-always-transfer-ambivalence-in-tacit-code"><a class="header" href="#cant-always-transfer-ambivalence-in-tacit-code">Can't always transfer ambivalence in tacit code</a></h3>
<p>For example, there's no tacit equivalent of the old APL (NARS) <code><span class='Modifier2'>∘</span></code>, which in explicit BQN is simply <code><span class='Brace'>{</span><span class='Value'>𝕨</span><span class='Function'>𝔽𝔾</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code>. Similarly, <code><span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>𝔽</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> is missing. The contrast with Atop and Over, which work very smoothly, can be jarring and make it harder to get an intuition for what the code is doing.</p>
-<h3 id="poor-font-support-">Poor font support</h3>
+<h3 id="poor-font-support-"><a class="header" href="#poor-font-support-">Poor font support</a></h3>
<p>Characters <code><span class='Function'>⥊∾</span><span class='Modifier2'>⟜⎉⚇</span><span class='Modifier'>˜</span></code> and double-struck letters are either missing from many fonts or drawn strangely.</p>
-<h3 id="choose-and-repeat-have-order-swapped">Choose and Repeat have order swapped</h3>
+<h3 id="choose-and-repeat-have-order-swapped"><a class="header" href="#choose-and-repeat-have-order-swapped">Choose and Repeat have order swapped</a></h3>
<p>In Choose, the selector goes on the left; in Repeat, the count goes on the right. Could be a strength in some contexts, since you can change Repeat-as-If to Choose if you don't like the ordering, but maybe a language that forces the programmer to make semantic decisions for syntactic reasons is not providing the greatest of services.</p>
-<h3 id="index-of-privileges-the-first-match">Index Of privileges the first match</h3>
+<h3 id="index-of-privileges-the-first-match"><a class="header" href="#index-of-privileges-the-first-match">Index Of privileges the first match</a></h3>
<p>It could be more sound to look at all matches, but using just the first one is too convenient. J has an index-of-last function; in BQN you have to reverse the left argument and then do arithmetic: <code><span class='Function'>≠</span><span class='Modifier2'>∘</span><span class='Function'>⊣-</span><span class='Number'>1</span><span class='Function'>+⌽</span><span class='Modifier2'>⊸</span><span class='Function'>⊐</span></code>.</p>
-<h3 id="glyphs-that-arent-great">Glyphs that aren't great</h3>
+<h3 id="glyphs-that-arent-great"><a class="header" href="#glyphs-that-arent-great">Glyphs that aren't great</a></h3>
<p>Blanket issue for glyphs that need work. Currently I find <code><span class='Function'>⥊⊏⊑⊐⊒⍷</span><span class='Modifier'>⁼</span><span class='Modifier2'>⎉⚇</span></code> to not be particularly good fits for what they describe.</p>
-<h3 id="cant-mix-define-and-modify-in-multiple-assignment">Can't mix define and modify in multiple assignment</h3>
+<h3 id="cant-mix-define-and-modify-in-multiple-assignment"><a class="header" href="#cant-mix-define-and-modify-in-multiple-assignment">Can't mix define and modify in multiple assignment</a></h3>
<p>Say <code><span class='Value'>a</span></code> is a pair and <code><span class='Value'>h</span></code> isn't defined yet; how would you set <code><span class='Value'>h</span></code> to the first element of <code><span class='Value'>a</span></code> and change <code><span class='Value'>a</span></code> to be just the second? <code><span class='Value'>h</span><span class='Ligature'>‿</span><span class='Value'>a</span><span class='Gets'>↩</span><span class='Value'>a</span></code> doesn't work because <code><span class='Value'>h</span></code> isn't defined, so the best I have is <code><span class='Value'>h</span><span class='Gets'>←</span><span class='String'>@</span><span class='Separator'>⋄</span><span class='Value'>h</span><span class='Ligature'>‿</span><span class='Value'>a</span><span class='Gets'>↩</span><span class='Value'>a</span></code>. A heavier assignment syntax wouldn't break down; BQN could allow <code><span class='Bracket'>⟨</span><span class='Value'>h</span><span class='Gets'>←</span><span class='Separator'>,</span><span class='Value'>a</span><span class='Bracket'>⟩</span><span class='Gets'>↩</span><span class='Value'>a</span></code> but I don't think this merits special syntax.</p>
-<h3 id="trains-dont-like-monads">Trains don't like monads</h3>
+<h3 id="trains-dont-like-monads"><a class="header" href="#trains-dont-like-monads">Trains don't like monads</a></h3>
<p>If you have the normal mix of monads and dyads you'll need a lot of parentheses and might end up abusing <code><span class='Modifier2'>⟜</span></code>. Largely solved with the &quot;nothing&quot; glyph <code><span class='Nothing'>·</span></code>, which acts like J's Cap (<code><span class='Value'>[:</span></code>) in a train, but still a minor frustration.</p>
-<h3 id="underbind-combination-is-awkward">Under/bind combination is awkward</h3>
+<h3 id="underbind-combination-is-awkward"><a class="header" href="#underbind-combination-is-awkward">Under/bind combination is awkward</a></h3>
<p>It's most common to use Under with dyadic structural functions in the form <code><span class='Value'>…</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Value'>i</span><span class='Modifier2'>⊸</span><span class='Function'>F</span><span class='Paren'>)</span></code>, for example where <code><span class='Function'>F</span></code> is one of <code><span class='Function'>/</span></code> or <code><span class='Function'>↑</span></code>. This is frustrating for two reasons: it requires parentheses, and it doesn't allow <code><span class='Value'>i</span></code> to be computed tacitly. If there's no left argument then the modifier <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='Value'>𝕩</span><span class='Brace'>}</span></code> can be more useful, but it doesn't cover some useful cases such as mask <code><span class='Value'>a</span> <span class='Function'>⊣</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Value'>u</span><span class='Modifier2'>⊸</span><span class='Function'>/</span><span class='Paren'>)</span> <span class='Value'>b</span></code>.</p>
-<h3 id="axis-ordering-is-big-endian">Axis ordering is big-endian</h3>
+<h3 id="axis-ordering-is-big-endian"><a class="header" href="#axis-ordering-is-big-endian">Axis ordering is big-endian</a></h3>
<p>The most natural ordering for polynomial coefficients and base representations is little-endian, because it aligns element <code><span class='Value'>i</span></code> of the list with power <code><span class='Value'>i</span></code> of the argument or base. It also allows a forward scan instead of a reverse one. Array axes go the other way. However, there are advantages to this ordering as well. For example, it's common to act only on the first few axes, so having them at the beginning of the array is good (<code><span class='Function'>≠</span><span class='Value'>a</span> <span class='Gets'>←→</span> <span class='Function'>⊑</span><span class='Modifier2'>∘</span><span class='Function'>≢</span><span class='Value'>a</span></code>).</p>
-<h3 id="inverse-is-not-fully-specified">Inverse is not fully specified</h3>
+<h3 id="inverse-is-not-fully-specified"><a class="header" href="#inverse-is-not-fully-specified">Inverse is not fully specified</a></h3>
<p>So it seems a bit strange to rely on it for core language features like <code><span class='Function'>/</span><span class='Modifier'>⁼</span></code>. On the other hand, this is a good fit for <code><span class='Function'>⋆</span><span class='Modifier'>⁼</span></code> since we are taking an arbitrary branch of a complex function that has many of them. I'm pretty sure it's impossible to solve the issue as stated but it might be possible to move to less hazardous constructs. Structural Under is a start.</p>
-<h3 id="group-doesnt-include-trailing-empty-groups">Group doesn't include trailing empty groups</h3>
+<h3 id="group-doesnt-include-trailing-empty-groups"><a class="header" href="#group-doesnt-include-trailing-empty-groups">Group doesn't include trailing empty groups</a></h3>
<p>A length can now be specified either in an extra element in any rank-1 component of <code><span class='Value'>𝕨</span></code>, or by overtaking, since the result's fill element is an empty group. However, it still seems like it would be pretty easy to end up with a length error when a program using Group encounters unexpected data. It's a fundamental safety-convenience tradeoff, though, because specifying a length has to take more code in the general case.</p>
-<h3 id="prefixessuffixes-add-depth-and-windows-doesnt">Prefixes/Suffixes add depth and Windows doesn't</h3>
+<h3 id="prefixessuffixes-add-depth-and-windows-doesnt"><a class="header" href="#prefixessuffixes-add-depth-and-windows-doesnt">Prefixes/Suffixes add depth and Windows doesn't</a></h3>
<p>It's an awkward inconsistency. Prefixes and Suffixes have to have a nested result, but Windows doesn't have to be flat; it's just that making it nested ignores the fact that it does have an array structure.</p>
-<h3 id="deshape-and-reshape-cant-ignore-trailing-axes">Deshape and Reshape can't ignore trailing axes</h3>
+<h3 id="deshape-and-reshape-cant-ignore-trailing-axes"><a class="header" href="#deshape-and-reshape-cant-ignore-trailing-axes">Deshape and Reshape can't ignore trailing axes</a></h3>
<p>If you want to repeat 3 major cells until there are 7 of them, or combine the first 4 axes of a rank-6 array, what's your best option? Nothing's too good: you could compute a full shape for Reshape, enclose cells and merge afterwards (for example <code><span class='Number'>7</span><span class='Modifier2'>⊸</span><span class='Function'>⥊</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Function'>&lt;</span><span class='Modifier'>˘</span><span class='Paren'>)</span></code>), use Select to reshape one axis to multiple, or use <code><span class='Function'>∾</span><span class='Modifier'>˝</span></code> to merge two axes (with possible empty-array issues). This is particularly dangerous with computed-length reshapes like <code><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Modifier2'>∘</span><span class='Function'>⥊</span><span class='Value'>…</span></code>, since the idea of splitting off a length-2 axis from an array's first axis is generally useful, but this version has an implicit Deshape first. J's Reshape analogue (<code><span class='Value'>$</span></code>) only ever applies to the first axis. This also seems to be giving up a lot.</p>
-<h3 id="at-which-scope-does-a-block-function-belong">At which scope does a block function belong?</h3>
+<h3 id="at-which-scope-does-a-block-function-belong"><a class="header" href="#at-which-scope-does-a-block-function-belong">At which scope does a block function belong?</a></h3>
<p>As a general principle, a programmer should make choices in one part of a program that constrain other parts of the program most tightly. This is a weak principle, but often it doesn't conflict with any other preferences and can be followed for free. For example it's usually best to define a variable in the smallest possible scope, so the reader knows it isn't used outside that scope. The same principle applies to blocks, but there is another conflicting principle: placing the block in a broader scope guarantees it won't access the variables in narrower ones. There's no position that will tell the reader, for example, that a function only uses variables local to itself and that it's only used within one particular scope.</p>
<p>This is an issue with any lexically-scoped language; it's unlikely BQN can solve it. On the other hand, I'm surprised I've never seen any discussion of such a universal issue.</p>
-<h3 id="negative-indices-dont-fail-by-default">Negative indices don't fail by default</h3>
+<h3 id="negative-indices-dont-fail-by-default"><a class="header" href="#negative-indices-dont-fail-by-default">Negative indices don't fail by default</a></h3>
<p>The typical case when selecting from an array is that a negative index doesn't make sense, and you'd prefer it to give an error. But negative indices are pretty useful in some contexts so BQN trades safety for convenience. Manually checking that indices are non-negative is easier than full range checking, but the issue is that you have to do it manually at all.</p>
-<h3 id="rankdepth-negative-zero">Rank/Depth negative zero</h3>
+<h3 id="rankdepth-negative-zero"><a class="header" href="#rankdepth-negative-zero">Rank/Depth negative zero</a></h3>
<p>A positive operand to Rank indicates the cell rank, so positive zero means to act on 0-cells. A negative operand indicates the frame length, so negative zero should act on the entire array. But it can't because it's equal to positive zero. Similar issue with Depth. Positive/negative is not really the right way to encode the frame/cell distinction, but it's convenient. Fortunately ∞ can be used in place of negative zero, but there can still be problems if the rank is computed.</p>
-<h3 id="tacit-code-cant-build-lists-easily">Tacit code can't build lists easily</h3>
+<h3 id="tacit-code-cant-build-lists-easily"><a class="header" href="#tacit-code-cant-build-lists-easily">Tacit code can't build lists easily</a></h3>
<p>It's unergonomic, and also quadratic in a naive runtime. The problem of course is that tacit code can only combine up to two values at a time, while in explicit code, list notation combines any number of them. In a language less beholden to syntax, <code><span class='Function'>List</span></code> would simply be a function with an arbitrary number of arguments and you'd be able to form trains with it—although this <em>does</em> require distinguishing when it's used as a train versus as a plain function.</p>
-<h3 id="must-read-the-body-to-find-headerless-blocks-type">Must read the body to find headerless block's type</h3>
+<h3 id="must-read-the-body-to-find-headerless-blocks-type"><a class="header" href="#must-read-the-body-to-find-headerless-blocks-type">Must read the body to find headerless block's type</a></h3>
<p>You have to scan for headers or double-struck names (and so does a compiler). A little inelegant, and difficult to describe in BNF. This can usually be fixed by adding a block header, except in the case of immediate modifiers: even an immediate modifier with a header can be made into a deferred modifier by adding a special name like <code><span class='Value'>𝕨</span></code>.</p>
-<h3 id="no-one-right-way-to-check-if-a-value-is-an-array">No one right way to check if a value is an array</h3>
+<h3 id="no-one-right-way-to-check-if-a-value-is-an-array"><a class="header" href="#no-one-right-way-to-check-if-a-value-is-an-array">No one right way to check if a value is an array</a></h3>
<p>The mathematical approach is <code><span class='Number'>0</span><span class='Function'>&lt;≡</span><span class='Value'>𝕩</span></code>, which can be slow without runtime support, while the efficient approach is <code><span class='Number'>0</span><span class='Function'>=•Type</span><span class='Value'>𝕩</span></code>, which is ugly and uses a system function for something that has nothing at all to do with the system. These are minor flaws, but programmers shouldn't have to hesitate about which one they want to use.</p>
-<h3 id="each-block-body-has-its-own-label">Each block body has its own label</h3>
+<h3 id="each-block-body-has-its-own-label"><a class="header" href="#each-block-body-has-its-own-label">Each block body has its own label</a></h3>
<p>In a block with multiple bodies, the label (the self-name part of the header) refers to the entire block. However, there's no way to give only one label to the entire block. If you want to consistently use the same internal name, then you may have to write it many times. It's also a weird mismatch, conceptually.</p>
-<h3 id="have-to-be-careful-about-intermediate-results-with-affine-characters">Have to be careful about intermediate results with affine characters</h3>
+<h3 id="have-to-be-careful-about-intermediate-results-with-affine-characters"><a class="header" href="#have-to-be-careful-about-intermediate-results-with-affine-characters">Have to be careful about intermediate results with affine characters</a></h3>
<p>A computation like <code><span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>+</span><span class='Value'>b</span><span class='Paren'>)</span><span class='Function'>÷</span><span class='Number'>2</span></code> (midpoint between characters <code><span class='Value'>a</span></code> and <code><span class='Value'>b</span></code>, of the distance between them is even) or <code><span class='Number'>5</span><span class='Function'>&gt;</span><span class='Value'>v</span><span class='Function'>-</span><span class='Value'>n</span></code> (equivalent to <code><span class='Value'>v</span><span class='Function'>&lt;</span><span class='Number'>5</span><span class='Function'>+</span><span class='Value'>n</span></code>) is conceptually okay, but the first will always fail because <code><span class='Value'>a</span><span class='Function'>+</span><span class='Value'>b</span></code> is invalid while the second will (even worse!) fail only if <code><span class='Value'>v</span></code> is a character with code point smaller than <code><span class='Value'>n</span></code>. Arithmetic manipulations that would be valid for numbers aren't for the number-character system.</p>
<p>Numbers and characters are subsets of a linear space with components &quot;characterness&quot; (0 for numbers and 1 for characters) and value (code point for characters). Numbers are a linear subspace, and characters a subset of an affine one. Their union isn't closed under addition and subtraction in either component. Usually this is good, as failing when the user creates a nonexistent character or double-character can catch a lot of errors. But not always.</p>
-<h3 id="monadic-argument-corresponds-to-left-for--and-">Monadic argument corresponds to left for <code><span class='Function'>/</span></code> and <code><span class='Function'>⊔</span></code></h3>
+<h3 id="monadic-argument-corresponds-to-left-for--and-"><a class="header" href="#monadic-argument-corresponds-to-left-for--and-">Monadic argument corresponds to left for <code><span class='Function'>/</span></code> and <code><span class='Function'>⊔</span></code></a></h3>
<p>Called dyadically, both functions shuffle cells of the right argument around, which is consistent with other selection-type functions. But the monadic case applies to what would be the left argument in the dyadic case.</p>
-<h3 id="hard-to-manipulate-the-result-of-a-modifier">Hard to manipulate the result of a modifier</h3>
+<h3 id="hard-to-manipulate-the-result-of-a-modifier"><a class="header" href="#hard-to-manipulate-the-result-of-a-modifier">Hard to manipulate the result of a modifier</a></h3>
<p>Trains and compositions make it easy to work with the results of functions, in some sense. The same can't be said for modifiers: for example, in a non-immediate block modifier, the derived function is <code><span class='Function'>𝕊</span></code>, but you can't apply <code><span class='Modifier'>˜</span></code> to it. This seems to call for modifer trains but people who worked with early J are confident they're not worth it. Or were they just not designed right?</p>
-<h3 id="monadic--versus-">Monadic <code><span class='Function'>⊑</span></code> versus <code><span class='Function'>&gt;</span></code></h3>
+<h3 id="monadic--versus-"><a class="header" href="#monadic--versus-">Monadic <code><span class='Function'>⊑</span></code> versus <code><span class='Function'>&gt;</span></code></a></h3>
<p>Both pull out elements and reduce the depth. But they face in opposite directions. However, neither should be thought of as the inverse to <code><span class='Function'>&lt;</span></code>: that's <code><span class='Function'>&lt;</span><span class='Modifier'>⁼</span></code>. And <code><span class='Function'>&gt;</span></code> can't reduce the depth to 0, so it's pretty different from <code><span class='Function'>⊑</span></code> or <code><span class='Function'>&lt;</span><span class='Modifier'>⁼</span></code>.</p>
<p>The directions of <code><span class='Function'>⊏⊐</span></code> and so on were mainly chosen to line up with <code><span class='Function'>∊</span></code>: the argument that indices apply to (that is, the one that is searched or selected from) corresponds to the open side of the function. I'd probably prefer new glyphs that don't have this sort of directionality, however.</p>
-<h3 id="cant-take-prefixes-or-suffixes-on-multiple-axes">Can't take Prefixes or Suffixes on multiple axes</h3>
+<h3 id="cant-take-prefixes-or-suffixes-on-multiple-axes"><a class="header" href="#cant-take-prefixes-or-suffixes-on-multiple-axes">Can't take Prefixes or Suffixes on multiple axes</a></h3>
<p>This is a natural array operation to do, and results in an array with a joinable structure, but as Prefixes and Suffixes are monadic there's no way to specify the number of axes to use.</p>
-<h3 id="modified-assignment-modifies-the-left-secondary-argument">Modified assignment modifies the left (secondary) argument</h3>
+<h3 id="modified-assignment-modifies-the-left-secondary-argument"><a class="header" href="#modified-assignment-modifies-the-left-secondary-argument">Modified assignment modifies the left (secondary) argument</a></h3>
<p>So you end up with <code><span class='Modifier'>˜</span><span class='Gets'>↩</span></code> a lot of the time. For ordinary assignment it's pretty reasonable to say the value is primary, but modified assignment flips this around.</p>
-<h3 id="andormaxmin-are-all-tangled-up">And/Or/Max/Min are all tangled up</h3>
+<h3 id="andormaxmin-are-all-tangled-up"><a class="header" href="#andormaxmin-are-all-tangled-up">And/Or/Max/Min are all tangled up</a></h3>
<p>Boolean And (<code><span class='Function'>∧</span></code>) and Or (<code><span class='Function'>∨</span></code>) are identical to Min (<code><span class='Function'>⌊</span></code>) and Max (<code><span class='Function'>⌈</span></code>) when restricted to Boolean arguments, and this would fit nicely with their monadic role as sorting functions: for example <code><span class='Value'>a</span><span class='Function'>∧</span><span class='Value'>b</span> <span class='Gets'>←→</span> <span class='Function'>⊑∧</span><span class='Value'>a</span><span class='Ligature'>‿</span><span class='Value'>b</span></code>. Furthermore the pairing of Min with Floor and Max with Ceiling is mnemonic only and not especially natural. The reason I have not used these glyphs for Min and Max, and have instead extended them to the somewhat superfluous <a href="../doc/logic.html">arithmetic logical functions</a> is that Min and Max have different <a href="https://aplwiki.com/wiki/Identity_element">identity elements</a> of <code><span class='Number'>∞</span></code> and <code><span class='Number'>¯∞</span></code> rather than <code><span class='Number'>1</span></code> and <code><span class='Number'>0</span></code>. Having to code around empty arrays when using <code><span class='Function'>∧</span><span class='Modifier'>´</span></code> would be a fairly big issue.</p>
<p>The other drawback of Min (<code><span class='Function'>∧</span></code>) and Max (<code><span class='Function'>∨</span></code>) is that the symbols are counterintuitive, but I have found a way to remember them: consider the graph of variables <code><span class='Value'>a</span><span class='Gets'>←</span><span class='Value'>x</span></code> and <code><span class='Value'>b</span><span class='Gets'>←</span><span class='Function'>¬</span><span class='Value'>x</span></code> for x from 0 to 1: two crossed lines. Now the graph of <code><span class='Value'>a</span><span class='Function'>∧</span><span class='Value'>b</span></code> is a caret shape and <code><span class='Value'>a</span><span class='Function'>∨</span><span class='Value'>b</span></code> is a vee.</p>
-<h3 id="acting-on-windows-can-be-awkward">Acting on windows can be awkward</h3>
+<h3 id="acting-on-windows-can-be-awkward"><a class="header" href="#acting-on-windows-can-be-awkward">Acting on windows can be awkward</a></h3>
<p>When taking Windows along more than one axis, acting on the resulting array requires the Rank modifier, duplicating either the right argument rank or (negated) left argument length. A nested Windows would only require Each.</p>
-<h3 id="inputs-to-modifiers-are-called-operands">Inputs to modifiers are called operands?</h3>
+<h3 id="inputs-to-modifiers-are-called-operands"><a class="header" href="#inputs-to-modifiers-are-called-operands">Inputs to modifiers are called operands?</a></h3>
<p>&quot;Operand&quot; is derived from &quot;operator&quot;. &quot;Modificand&quot; would be better if it weren't both made up and hideous.</p>
-<h3 id="converting-a-function-expression-to-a-subject-is-tricky">Converting a function expression to a subject is tricky</h3>
+<h3 id="converting-a-function-expression-to-a-subject-is-tricky"><a class="header" href="#converting-a-function-expression-to-a-subject-is-tricky">Converting a function expression to a subject is tricky</a></h3>
<p>You can name it, you can write <code><span class='Function'>⊑</span><span class='Bracket'>⟨</span><span class='Function'>Expr</span><span class='Bracket'>⟩</span></code> or <code><span class='Paren'>(</span><span class='Function'>Expr</span><span class='Paren'>)</span><span class='Modifier'>˙</span><span class='Number'>0</span></code>, and if it doesn't use special names you can write <code><span class='Brace'>{</span><span class='Function'>Expr</span><span class='Brace'>}</span></code>. All of these are at least a little awkward in reasonable cases. Should there be a dedicated syntax? Note that going the other way, from subject to function, isn't too bad: the modifier <code><span class='Brace'>{</span><span class='Function'>𝔽</span><span class='Brace'>}</span></code> does it, as does <code><span class='Modifier2'>○</span><span class='Function'>⊢</span></code>.</p>
-<h3 id="scan-ordering-is-weird">Scan ordering is weird</h3>
+<h3 id="scan-ordering-is-weird"><a class="header" href="#scan-ordering-is-weird">Scan ordering is weird</a></h3>
<p>Scan moves along the array so that it uses results as left arguments, which is opposite to the usual right-to-left order of evaluation. But I think this is still better than scanning the array in reverse. You can always use Swap on the operand, or recover the APL scan ordering by doing a Reduce-Each on Prefixes.</p>
-<h3 id="only-errors-in-functions-can-be-caught">Only errors in functions can be caught</h3>
+<h3 id="only-errors-in-functions-can-be-caught"><a class="header" href="#only-errors-in-functions-can-be-caught">Only errors in functions can be caught</a></h3>
<p>The modifier <code><span class='Modifier2'>⎊</span></code> allows errors in a function to be caught, but a more natural unit for this is the block (scope, really). However, catching errors shouldn't be common in typical code, in the sense that an application should have only a few instances of <code><span class='Modifier2'>⎊</span></code>. Ordinary testing and control flow should be preferred instead.</p>
-<h3 id="special-names-other-than--cant-be-written-as-modifiers">Special names other than 𝕣 can't be written as modifiers</h3>
+<h3 id="special-names-other-than--cant-be-written-as-modifiers"><a class="header" href="#special-names-other-than--cant-be-written-as-modifiers">Special names other than 𝕣 can't be written as modifiers</a></h3>
<p>I decided that it was better to allow <code><span class='Value'>𝕨</span><span class='Modifier2'>_m_</span><span class='Value'>𝕩</span></code> to work with no spaces than to allow <code><span class='Modifier2'>_</span><span class='Value'>𝕩</span></code> to be a modifier, and this rule also helps keep tokenization simple. But to apply <code><span class='Value'>𝕩</span></code> as a modifier you have to give it a different name.</p>
-<h3 id="bins-is-inconsistent-with-index-of">Bins is inconsistent with Index of</h3>
+<h3 id="bins-is-inconsistent-with-index-of"><a class="header" href="#bins-is-inconsistent-with-index-of">Bins is inconsistent with Index of</a></h3>
<p>In Dyalog APL, Interval Index is identical to Index Of if the left argument has no duplicate cells and every right argument cell intolerantly matches a left argument cell. In BQN they're off by one—Bins is one larger. But all the caveats for the Dyalog relation indicate this might not be so fundamental.</p>
-<h3 id="changing-boundary-behavior-can-require-very-different-code">Changing boundary behavior can require very different code</h3>
+<h3 id="changing-boundary-behavior-can-require-very-different-code"><a class="header" href="#changing-boundary-behavior-can-require-very-different-code">Changing boundary behavior can require very different code</a></h3>
<p>This mainly applies to pairwise operations; for bigger stencils you'd use Windows, and probably handle boundaries with multidimensional selection. For pairwise operations there are four different paths you might use: decrease size using <code><span class='Function'>↓</span></code>; periodic conditions with <code><span class='Function'>⌽</span></code>; fixed or computed boundaries with <code><span class='Function'>«</span></code> and <code><span class='Function'>»</span></code>; and increased size with <code><span class='Function'>∾</span></code>. Having all this flexibility is great, and it's hard to imagine a parametrized system that offers the same without being difficult to remember. However, some of these functions take lengths and some take values, the latter class only works on one dimension at a time, and for <code><span class='Function'>∾</span></code> the argument can go on either side. This is frustrating if you have a reason to switch between the conditions.</p>
-<h3 id="exact-result-of-power-is-unspecified">Exact result of Power is unspecified</h3>
+<h3 id="exact-result-of-power-is-unspecified"><a class="header" href="#exact-result-of-power-is-unspecified">Exact result of Power is unspecified</a></h3>
<p>The other arithmetic functions round to nearest, and compound functions such as <code><span class='Value'>⊥</span></code> have been removed. But Power makes no guarantees, and the result could change over time based on different special code. Dyadic logarithm is similar, but expected because of its inverse status.</p>
-<h3 id="empty-left-argument-to-select">Empty left argument to Select</h3>
+<h3 id="empty-left-argument-to-select"><a class="header" href="#empty-left-argument-to-select">Empty left argument to Select</a></h3>
<p>Select chooses whether the left argument maps to right argument axes or selects from the first axis only based on its depth. Without prototypes an empty array has depth 1, so it selects no major cells. However, it could also select from no axes (a no-op) and in some contexts the other behavior would be surprising.</p>
-<h3 id="unclear-primitive-names">Unclear primitive names</h3>
+<h3 id="unclear-primitive-names"><a class="header" href="#unclear-primitive-names">Unclear primitive names</a></h3>
<p>Blanket issue for names that I don't find informative: &quot;Solo&quot;, &quot;Bins&quot;, &quot;Find&quot;, and &quot;Group&quot;.</p>
-<h3 id="modifiers-look-looser-than-trains-without-spaces">Modifiers look looser than trains without spaces</h3>
+<h3 id="modifiers-look-looser-than-trains-without-spaces"><a class="header" href="#modifiers-look-looser-than-trains-without-spaces">Modifiers look looser than trains without spaces</a></h3>
<p>Consider <code><span class='Function'>⋆</span><span class='Modifier2'>∘</span><span class='Function'>-×</span><span class='Modifier'>˜</span></code>. It's just a sequence of three functions so the use of <code><span class='Modifier2'>∘</span></code> rather than <code><span class='Nothing'>·</span></code> is to highlight structure: <code><span class='Function'>⋆</span><span class='Modifier2'>∘</span><span class='Function'>-</span></code> is more tightly bound so the suggestion is to consider this composition as a single entity. But in fact <code><span class='Function'>-</span></code> is closer to <code><span class='Function'>×</span><span class='Modifier'>˜</span></code> than to <code><span class='Function'>⋆</span></code>, intuitively suggesting the opposite. Adding a space fixes it: <code><span class='Function'>⋆</span><span class='Modifier2'>∘</span><span class='Function'>-</span> <span class='Function'>×</span><span class='Modifier'>˜</span></code> visually connects <code><span class='Function'>⋆</span><span class='Modifier2'>∘</span><span class='Function'>-</span></code>. It's unfortunate that this is something the writer must do rather than something the notation encourages.</p>
-<h3 id="tacit-exports-can-leak-data">Tacit exports can leak data</h3>
+<h3 id="tacit-exports-can-leak-data"><a class="header" href="#tacit-exports-can-leak-data">Tacit exports can leak data</a></h3>
<p>One of the nice facets of BQN's module system is that it provides perfect encapsulation: if you have variables <code><span class='Value'>a</span></code> and <code><span class='Value'>b</span></code> in a namespace (or closure) initialized so that <code><span class='Value'>a</span><span class='Function'>≤</span><span class='Value'>b</span></code>, and all exported operations maintain the property that <code><span class='Value'>a</span><span class='Function'>≤</span><span class='Value'>b</span></code>, then that property will always be true. Well, not quite: if you define, say <code><span class='Function'>Inc</span> <span class='Gets'>⇐</span> <span class='Function'>IncA</span> <span class='Function'>⊣</span> <span class='Function'>IncB</span></code> to increase the values of both <code><span class='Value'>a</span></code> and <code><span class='Value'>b</span></code> by <code><span class='Value'>𝕩</span></code>, then <code><span class='Function'>Inc</span></code> maintains <code><span class='Value'>a</span><span class='Function'>≤</span><span class='Value'>b</span></code>, but <code><span class='Function'>IncA</span></code> doesn't—and it can be extracted with <code><span class='Function'>•Decompose</span></code>. This isn't too serious because it sounds impossible to do accidentally, and it's easy to protect against.</p>
-<h3 id="strands-go-left-to-right">Strands go left to right</h3>
+<h3 id="strands-go-left-to-right"><a class="header" href="#strands-go-left-to-right">Strands go left to right</a></h3>
<p>This is the best ordering, since it's consistent with <code><span class='Bracket'>⟨</span><span class='Separator'>⋄</span><span class='Bracket'>⟩</span></code> lists. And code in a strand probably shouldn't have side effects anyway. Still, it's an odd little tack-on to say separators <em>and strands</em> go left to right, and it complicates the implementation a little.</p>
-<h3 id="primitive-name-capitalization">Primitive name capitalization</h3>
+<h3 id="primitive-name-capitalization"><a class="header" href="#primitive-name-capitalization">Primitive name capitalization</a></h3>
<p>I went with &quot;Index of&quot; and &quot;Less Than or Equal to&quot; but the last word blends into surrounding text. Should they be fully capitalized or hyphenated?</p>
-<h2 id="solved-problems">Solved problems</h2>
+<h2 id="solved-problems"><a class="header" href="#solved-problems">Solved problems</a></h2>
<p>Problems that existed in mainstream APL or a transitional BQN that have in my opinion been put to rest (while in some cases introducing new problems). Listed in reverse chronological order by time solved, by my recollection.</p>
-<h3 id="trigonometry">Trigonometry</h3>
+<h3 id="trigonometry"><a class="header" href="#trigonometry">Trigonometry</a></h3>
<p>Solved with namespaces. dzaima/BQN uses <code><span class='Value'>•math</span></code> to expose math functions, but it could also be provided in a system library (still deciding). It's up to the implementation how the functions are implemented.</p>
<p>There are a lot of standard functions and I don't want to use separate primitives or a menu-style primitive like APL Circle for them. You can define all the functions eventually if you use complex exponential and take real and imaginary parts and inverses, but this doesn't sound well-suited for implementation. And there should be a math library that gives you the standard functions with normal names, but how will it be implemented?</p>
-<h3 id="should-have-a-rounding-function">Should have a rounding function</h3>
+<h3 id="should-have-a-rounding-function"><a class="header" href="#should-have-a-rounding-function">Should have a rounding function</a></h3>
<p>Also placed in the math namespace.</p>
<p>There is a standard way to round floats—to nearest integer, ties to even—but it's fairly hard to implement and would have to be specially recognized for performance. It would be nice to have a better way to access this.</p>
-<h3 id="array-reductions-are-annoying">Array reductions are annoying</h3>
+<h3 id="array-reductions-are-annoying"><a class="header" href="#array-reductions-are-annoying">Array reductions are annoying</a></h3>
<p>There are really three kinds of reduction a BQN programmer might want to use.</p>
<ul>
<li><code><span class='Function'>𝔽</span><span class='Modifier'>´</span></code> Apply the function between elements of a list (Lisp).</li>
@@ -163,28 +163,28 @@
<li><code><span class='Function'>𝔽</span><span class='Modifier'>¨˝</span></code> Apply it between elements of an array, enclosing results to get a new array (NARS).</li>
</ul>
<p>BQN bounced between these some at first; eventually I decided it really needed two, with <code><span class='Function'>𝔽</span><span class='Modifier'>˝</span></code> equivalent to <code><span class='Function'>𝔽</span><span class='Modifier'>´</span><span class='Function'>&lt;</span><span class='Modifier'>˘</span></code>. The last requires two symbols, but they can always be used together as a unit, so I think this is no longer annoying.</p>
-<h3 id="modifier-and-composition-terminology">&quot;Modifier&quot; and &quot;composition&quot; terminology</h3>
+<h3 id="modifier-and-composition-terminology"><a class="header" href="#modifier-and-composition-terminology">&quot;Modifier&quot; and &quot;composition&quot; terminology</a></h3>
<p>1-modifiers and 2-modifiers used to be called &quot;modifiers&quot; and &quot;compositions&quot;, respectively, and sometimes &quot;operators&quot; collectively. The new names are much better, although they do leave a disconnect between the names for modifiers, and those for their inputs—&quot;operands&quot;.</p>
-<h3 id="cant-return-from-inner-functions">Can't return from inner functions</h3>
+<h3 id="cant-return-from-inner-functions"><a class="header" href="#cant-return-from-inner-functions">Can't return from inner functions</a></h3>
<p>Fixed by adding block returns such as <code><span class='Value'>label</span><span class='Gets'>←</span></code> to jump out of a block with header name <code><span class='Value'>label</span></code>. Hopefully these don't cause too many new problems.</p>
<p>This was an issue with using functions as control flow. For example, when looping through an array with Each, you can't decide to exit early. In a curly-brace language you would just use a for loop and a return. In BQN, we need… longjmp? Maybe not as crazy as it sounds, and potentially worth it in exchange for replacing control structures.</p>
-<h3 id="ambivalent-explicit-functions">Ambivalent explicit functions</h3>
+<h3 id="ambivalent-explicit-functions"><a class="header" href="#ambivalent-explicit-functions">Ambivalent explicit functions</a></h3>
<p>Fixed with multiple bodies: if there are two bodies with no headers such as <code><span class='Brace'>{</span><span class='Number'>2</span><span class='Function'>×</span><span class='Value'>𝕩;𝕨</span><span class='Function'>-</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code>, they are the monadic and dyadic case.</p>
-<h3 id="how-to-choose-a-partitioning-function">How to choose a partitioning function?</h3>
+<h3 id="how-to-choose-a-partitioning-function"><a class="header" href="#how-to-choose-a-partitioning-function">How to choose a partitioning function?</a></h3>
<p>Fixed with <a href="../doc/group.html">Group</a>, which I found May 2020. Group serves as a much improved <a href="https://aplwiki.com/wiki/Partition">Partition</a>. Later extended to multiple axes as well to get all the functionality.</p>
-<h3 id="key-doesnt-do-what-you-want">Key doesn't do what you want</h3>
+<h3 id="key-doesnt-do-what-you-want"><a class="header" href="#key-doesnt-do-what-you-want">Key doesn't do what you want</a></h3>
<p>Fixed with <a href="../doc/group.html">Group</a> to my satisfaction, except for the trailing-empty-group problem. There were various issues with Key operators in J and Dyalog, such as the fact that the ordering and presence of groups depends on where and whether the keys appear. Also, Dyalog's Key can return keys and values, but they are in a different format than the input: an array of pairs instead of two arrays. Monadic Group returns indices, which can be used how the programmer wants.</p>
-<h3 id="greek-letter-issues">Greek letter issues</h3>
+<h3 id="greek-letter-issues"><a class="header" href="#greek-letter-issues">Greek letter issues</a></h3>
<p>Fixed by not using Greek letters. In particular, the idea of using fancy Latin letters as fixed names for function arguments was suggested in proto-BQN sessions, possibly by Nathan Rogers.</p>
-<h3 id="stranding-gotchas">Stranding gotchas</h3>
+<h3 id="stranding-gotchas"><a class="header" href="#stranding-gotchas">Stranding gotchas</a></h3>
<p>Fixed with list notation, which descends from the array notation developed by Phil Last and later Adám Brudzewsky. The problem that array notation has much more cluttered syntax than stranding has pretty much been fixed by the ligature character <code><span class='Ligature'>‿</span></code>, which I discovered during proto-BQN discussions.</p>
-<h3 id="functions-are-not-first-class">Functions are not first class</h3>
+<h3 id="functions-are-not-first-class"><a class="header" href="#functions-are-not-first-class">Functions are not first class</a></h3>
<p>Fixed by allowing a variable to be written with a different syntactic role than it was created with, suggested by Adám in proto-BQN discussions.</p>
-<h3 id="apl-is-not-context-free">APL is not context-free</h3>
+<h3 id="apl-is-not-context-free"><a class="header" href="#apl-is-not-context-free">APL is not context-free</a></h3>
<p>Fixed with the casing conventions for variable names, which I think I first saw in <a href="https://aplwiki.com/wiki/APL%5Civ">APL\iv</a>, although the cases are swapped relative to BQN.</p>
-<h3 id="selective-assignment-requires-a-named-variable">Selective assignment requires a named variable</h3>
+<h3 id="selective-assignment-requires-a-named-variable"><a class="header" href="#selective-assignment-requires-a-named-variable">Selective assignment requires a named variable</a></h3>
<p>Fixed with structural Under, which I developed in 2017 and 2018.</p>
-<h3 id="its-hard-use-an-array-as-a-major-cell">It's hard use an array as a major cell</h3>
+<h3 id="its-hard-use-an-array-as-a-major-cell"><a class="header" href="#its-hard-use-an-array-as-a-major-cell">It's hard use an array as a major cell</a></h3>
<p>Fixed with <code><span class='Function'>≍</span></code>: dyadic form from A+ and monadic/dyadic pair from J.</p>
-<h3 id="scan-and-windowed-reduce-shouldnt-always-reduce">Scan and Windowed Reduce shouldn't always reduce</h3>
+<h3 id="scan-and-windowed-reduce-shouldnt-always-reduce"><a class="header" href="#scan-and-windowed-reduce-shouldnt-always-reduce">Scan and Windowed Reduce shouldn't always reduce</a></h3>
<p>Fixed with Prefix, Suffix, and Infix operators in J. Changed to functions in BQN.</p>
diff --git a/docs/doc/arithmetic.html b/docs/doc/arithmetic.html
index 0be70506..22dc233b 100644
--- a/docs/doc/arithmetic.html
+++ b/docs/doc/arithmetic.html
@@ -4,7 +4,7 @@
<title>BQN: Arithmetic functions</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="arithmetic-functions">Arithmetic functions</h1>
+<h1 id="arithmetic-functions"><a class="header" href="#arithmetic-functions">Arithmetic functions</a></h1>
<p>BQN's arithmetic functions use mostly the same symbols as APL, and the functionality is actually defined by the language implementation's number system and not the specification, so there's not too much to say about them.</p>
<p>Summary of differences for APLers:</p>
<ul>
@@ -13,7 +13,7 @@
<li>Not uses a different symbol <code><span class='Function'>¬</span></code>, and binary logical functions <code><span class='Function'>∧∨</span></code> (described on <a href="logic.html">their own page</a>) are extended linearly in all arguments instead of using GCD or LCM.</li>
<li>Dyadic arithmetic functions use <a href="leading.html#leading-axis-agreement">leading axis agreement</a> like J.</li>
</ul>
-<h2 id="basic-arithmetic">Basic arithmetic</h2>
+<h2 id="basic-arithmetic"><a class="header" href="#basic-arithmetic">Basic arithmetic</a></h2>
<p><em>These functions are also introduced in the <a href="../tutorial/expression.html">first BQN tutorial</a>.</em></p>
<p>BQN of course supports the elementary functions taught in schools everywhere:</p>
<table>
@@ -104,7 +104,7 @@
<span class='Function'>×</span> <span class='Number'>∞</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'>0</span><span class='Ligature'>‿</span><span class='Number'>4</span>
⟨ 1 ¯1 0 0 1 ⟩
</pre>
-<h3 id="character-arithmetic">Character arithmetic</h3>
+<h3 id="character-arithmetic"><a class="header" href="#character-arithmetic">Character arithmetic</a></h3>
<p>The Add and Subtract functions can be applied to <a href="types.html#characters">characters</a> as well as numbers. While any two numbers (finite ones, at least) can be added or subtracted, character arithmetic has more restrictions.</p>
<svg viewBox='-204.8 -42.2 640 132'>
<rect class='code' stroke-width='1' rx='6' x='0' y='0' width='256' height='68'/>
@@ -149,7 +149,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=J2EnIC0gQA==">↗️</a><pre> <span class='String'>'a'</span> <span class='Function'>-</span> <span class='String'>@</span>
97
</pre>
-<h2 id="additional-arithmetic">Additional arithmetic</h2>
+<h2 id="additional-arithmetic"><a class="header" href="#additional-arithmetic">Additional arithmetic</a></h2>
<table>
<thead>
<tr>
@@ -202,7 +202,7 @@
1
</pre>
<p>Unlike in APL, a left argument of 0 fails or returns a not-a-number result. Set <code><span class='Value'>𝕨</span></code> to <code><span class='Number'>∞</span></code> to keep <code><span class='Value'>𝕩</span></code> intact, but do note that if <code><span class='Value'>𝕩</span><span class='Function'>&lt;</span><span class='Number'>0</span></code> this will return <code><span class='Number'>∞</span></code>.</p>
-<h2 id="comparisons">Comparisons</h2>
+<h2 id="comparisons"><a class="header" href="#comparisons">Comparisons</a></h2>
<p>BQN uses the six standard comparison functions of mathematics. For each pair of atoms the result is 1 if the comparison is true and 0 if it's false. These functions do the obvious thing with numeric arguments, but are extended to other types as well.</p>
<table>
<thead>
@@ -283,7 +283,7 @@
<span class='String'>'b'</span> <span class='Function'>≠</span> <span class='String'>&quot;abacba&quot;</span>
⟨ 1 0 1 1 0 1 ⟩
</pre>
-<h2 id="pervasion">Pervasion</h2>
+<h2 id="pervasion"><a class="header" href="#pervasion">Pervasion</a></h2>
<p>Arithmetic primitives act as though they are given <a href="depth.html#the-depth-modifier">depth</a> 0, so that with array arguments they treat each atom independently. While the examples above use only numbers or lists of them, arithmetic applies to nested and high-rank arrays just as easily.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=w5cg4omNy5jin6jCrzgswq854p+p4oC/4p+o4p+oMiww4p+pLDQsNeKfqQ==">↗️</a><pre> <span class='Function'>×</span> <span class='Function'>≍</span><span class='Modifier'>˘</span><span class='Bracket'>⟨</span><span class='Number'>¯8</span><span class='Separator'>,</span><span class='Number'>¯9</span><span class='Bracket'>⟩</span><span class='Ligature'>‿</span><span class='Bracket'>⟨⟨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Bracket'>⟩</span><span class='Separator'>,</span><span class='Number'>4</span><span class='Separator'>,</span><span class='Number'>5</span><span class='Bracket'>⟩</span>
┌─
diff --git a/docs/doc/array.html b/docs/doc/array.html
index 001a9f70..1eeb5ee6 100644
--- a/docs/doc/array.html
+++ b/docs/doc/array.html
@@ -4,7 +4,7 @@
<title>BQN: The array</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="the-array">The array</h1>
+<h1 id="the-array"><a class="header" href="#the-array">The array</a></h1>
<p>As BQN is an array language, it's often helpful to understand what an array is when writing BQN programs. Fully describing the concept is sometimes <a href="https://www.jsoftware.com/papers/array.htm">held to be tricky</a>; here we'll see definitions, examples, and metaphors.</p>
<p>In BQN, as in APL, arrays are multidimensional, instead of strictly linear. Languages like Python, Javascript, or Haskell offer only one-dimensional arrays with <code><span class='Value'>[]</span></code> syntax, and typically represent multidimensional data with nested arrays. Multidimensional arrays have fundamental differences relative to this model.</p>
<p>BQN's arrays are immutable, meaning that an array is entirely defined by its attributes, and there is no way to modify an existing array, only to produce another array that has changes relative to it. As a result, an array can never contain itself, and arrays form an inductive type. BQN's <a href="lexical.html#mutation">mutable</a> types are operations and namespaces.</p>
@@ -85,7 +85,7 @@
</g>
</svg>
-<h2 id="rectangles">Rectangles</h2>
+<h2 id="rectangles"><a class="header" href="#rectangles">Rectangles</a></h2>
<p>A BQN <strong>array</strong> is a multidimensional arrangement of data. The word &quot;array&quot; descends from words meaning &quot;order&quot;, and the data in an array is ordered indeed. Below are examples of arrays with zero, one, and two dimensions.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=PDUKCuKfqDMsJ3gnLDHin6kKCjLigL8z4oC/NCDDl+KMnCAx4oC/NeKAvzjigL8xMQ==">↗️</a><pre> <span class='Function'>&lt;</span><span class='Number'>5</span>
┌·
@@ -105,23 +105,23 @@
<p>Each dimension, or <strong>axis</strong>, has some finite number of positions, with an <strong>element</strong> at every <em>combination</em> of positions. For example, if a group of friends shop at several different stores, the amount they spend in a week could be placed in a two-dimensional array, with people along one axis and stores along another. An element of the array would indicate how much one person spent at one store, so that summing across stores gives each person's expenditures and summing across people gives each store's income.</p>
<p>The axes of an array must be independent, that is, the positions present in one axis are fixed for the entire array and don't depend on other axes. This is a difference relative to a nested list model. When storing data in nested lists, the outer axis comes first and later axes are subordinate to it. The length of the second axis depends completely on the position in the first. A programmer might choose the lengths so it doesn't in a particular case, but in a BQN array differing lengths simply aren't representable.</p>
<p>The array also needs to be complete. Every element—every combination of positions—must have a value. This value could be a placeholder like <code><span class='String'>@</span></code>, but it has to be <em>something</em> (in the spending example, everyone spends some amount at each store, even if it's zero). And of course, there are no extra elements that don't fit into the positioning system—the <a href="fill.html">fill</a> isn't really part of the array, but extra information about it.</p>
-<h2 id="ordering-and-indices">Ordering and indices</h2>
+<h2 id="ordering-and-indices"><a class="header" href="#ordering-and-indices">Ordering and indices</a></h2>
<p>To finish this definition of an array we also need to nail down the idea of a position. The positions along one dimension can't be labelled in any way, but they have a linear ordering (mathematically speaking, a <a href="https://en.wikipedia.org/wiki/Total_order">total order</a>: out of any two different positions one comes earlier and the other later). BQN keeps track of this order: for example, when we <a href="join.html">join</a> two arrays it places positions in <code><span class='Value'>𝕨</span></code> before those of <code><span class='Value'>𝕩</span></code> and otherwise maintains the original ordering.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ImJlZm9yZSIg4oi+ICJhZnRlciI=">↗️</a><pre> <span class='String'>&quot;before&quot;</span> <span class='Function'>∾</span> <span class='String'>&quot;after&quot;</span>
"beforeafter"
</pre>
<p>It's only the ordering that allows positions to be distinguished. BQN labels them with natural numbers called <strong>indices</strong> that can be derived from the order: the earliest position is called <code><span class='Number'>0</span></code>, the next <code><span class='Number'>1</span></code>, and so on. The axes of an array are also ordered, and they're indexed starting at <code><span class='Number'>0</span></code> as well.</p>
<p>These kinds of index are one-dimensional, but there's also a multidimensional kind of array <a href="indices.html">index</a>, that identifies an element. An element index consists of one index along each axis. Because the axis are ordered, it can be represented as a list <code><span class='Value'>l</span></code> of numbers, where <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>l</span></code> is the index along axis <code><span class='Value'>i</span></code>. It's important to distinguish an element from its value: for example, there's only one value (<code><span class='Number'>3</span></code>) contained in the array <code><span class='Bracket'>⟨</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Bracket'>⟩</span></code>, but it still has three elements, identified by indices <code><span class='Bracket'>⟨</span><span class='Number'>0</span><span class='Bracket'>⟩</span></code>, <code><span class='Bracket'>⟨</span><span class='Number'>1</span><span class='Bracket'>⟩</span></code>, and <code><span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Bracket'>⟩</span></code>.</p>
-<h2 id="dimensions">Dimensions</h2>
+<h2 id="dimensions"><a class="header" href="#dimensions">Dimensions</a></h2>
<p>The number of axes in an array is called its <strong>rank</strong>. The number of positions along an axis is called its <strong>length</strong>, and the length of an array means its length along the first axis, or <code><span class='Number'>1</span></code> if there are no axes. The list of the length along each axis is the array's <strong>shape</strong>, and describes the possible element locations completely. In BQN they're exposed as the <a href="shape.html">functions</a> Rank (<code><span class='Function'>=</span></code>), Length (<code><span class='Function'>≠</span></code>), and Shape (<code><span class='Function'>≢</span></code>).</p>
<p>The total number of elements in an array is its <strong>bound</strong>, and can be found using <a href="reshape.html">Deshape</a> with <code><span class='Function'>≠</span><span class='Modifier2'>∘</span><span class='Function'>⥊</span></code>, is then the product of all the lengths in the shape. An array of rank 0, which always contains exactly one element, is called a <a href="enclose.html#whats-a-unit"><strong>unit</strong></a>, while an array of rank 1 is called a <strong>list</strong> and an array of rank 2 is called a <strong>table</strong>.</p>
-<h2 id="elements">Elements</h2>
+<h2 id="elements"><a class="header" href="#elements">Elements</a></h2>
<p>Any BQN value can be used as an array element, including another array (BQN, as a dynamically-typed language, doesn't restrict the types that can be used in one context without a good reason). However, BQN arrays are restricted relative to another array model. Frameworks like NumPy or Julia have mutable arrays, so that the value of an element can be changed after the array is created. This allows an array to be its own element, by creating an array and then inserting it into itself. This would be unnatural in BQN, where an array can only be formed from elements that already exist. In BQN only operations and namespaces are <a href="lexical.html#mutation">mutable</a>.</p>
-<h2 id="properties">Properties</h2>
+<h2 id="properties"><a class="header" href="#properties">Properties</a></h2>
<p>Summarizing, the values needed to define an array are its rank (the number of axes), its shape (the number of positions along each axis), and the value of each element (that is, at each combination of positions). Two arrays <a href="match.html">match</a> when all these values match.</p>
<p>If the rank is considered to be part of the shape, as it is when the shape is a BQN list, then the array is defined by its shape and element list—from <a href="reshape.html">deshape</a>.</p>
<p>Here's a somewhat informal mathematical take. Given a set of possible element values <code><span class='Function'>T</span></code>, a <em>list</em> of <code><span class='Function'>T</span></code> of length <code><span class='Value'>l</span></code> is a map from natural numbers less than <code><span class='Value'>l</span></code> to <code><span class='Function'>T</span></code>. An array is a rank <code><span class='Value'>r</span></code>, along with a list <code><span class='Value'>s</span></code> of natural numbers of length <code><span class='Value'>r</span></code>, and a map from lists of natural numbers <code><span class='Value'>i</span></code> that satisfy <code><span class='Value'>i</span><span class='Paren'>(</span><span class='Value'>j</span><span class='Paren'>)</span> <span class='Function'>&lt;</span> <span class='Value'>s</span><span class='Paren'>(</span><span class='Value'>j</span><span class='Paren'>)</span></code> for all natural numbers <code><span class='Value'>j</span><span class='Function'>&lt;</span><span class='Value'>r</span></code> to BQN values. Arrays are an inductive type, so that an array can only be defined using elements that already exist. As a result an array's elements are always values of lesser complexity and selecting one element of an array, then an element of that element, and so on, must eventually reach a non-array.</p>
-<h2 id="why-arrays">Why arrays?</h2>
+<h2 id="why-arrays"><a class="header" href="#why-arrays">Why arrays?</a></h2>
<p>The multidimensional array is a fairly simple structure, but there are simpler ones like pairs, lists, sets, and dictionaries. Why does BQN choose the array for its central type? I don't think arrays are always the best data structure (or that BQN is always the best language), but I do think they're one of several good choices and have unique advantages.</p>
<p>Arrays offer a lot of flexibility since they generalize lists. This also means that they can be used to represent pairs or sets. Two lists, or an array with a length-2 axis, can represent a map, although it could be hard to use with good performance.</p>
<p>But arrays are less flexible than <em>nested</em> lists (which in turn are less flexible than nested arrays). This is also in some sense a strength. The axes of an array are inherently independent. Lots of things in real life are independent! Regardless of which main you choose in your Cook Out tray you have the same options for sides. A term in a multivariate polynomial can have any power of <code><span class='Value'>x</span></code> and any power of <code><span class='Value'>y</span></code>. An array language lets you encode this independence in your data, and use operations that take advantage of it.</p>
diff --git a/docs/doc/arrayrepr.html b/docs/doc/arrayrepr.html
index 55598a6a..7c27fa07 100644
--- a/docs/doc/arrayrepr.html
+++ b/docs/doc/arrayrepr.html
@@ -4,10 +4,10 @@
<title>BQN: Array notation and display</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="array-notation-and-display">Array notation and display</h1>
+<h1 id="array-notation-and-display"><a class="header" href="#array-notation-and-display">Array notation and display</a></h1>
<p>This page documents ways arrays are represented in BQN: the notation you can use to write them and the way the REPL displays them.</p>
<p>Array display is a feature of a BQN environment such as a REPL. You can also access it with <code><span class='Function'>•Fmt</span></code>, which takes a value and returns a string indicating how it would be formatted. Array notation is of course part of BQN source code, but you can also go from an array to one possible source code for it using the similar system function <code><span class='Function'>•Repr</span></code>.</p>
-<h2 id="array-display">Array display</h2>
+<h2 id="array-display"><a class="header" href="#array-display">Array display</a></h2>
<p>Although it's really part of the language environment and not BQN itself, let's look at display first so it's clear what arrays we're talking about later on. The BQN REPL prints arrays in a way that's meant to unambiguously show the structure and data, but doesn't correspond to BQN source code. A few examples are given below; of course, displays like this appear all over the documentation.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oaVIDPigL80ICAgICAgICAgICAgICMgQXJyYXkgb2YgbGlzdHMKCjxAICAgICAgICAgICAgICAgICMgRW5jbG9zZWQgbnVsbAoK4p+o4oaVMywgInh5Iiwg4oaVMuKAvzDin6kgICMgQSBsaXN0IG9mIHRocmVlIGFycmF5cw==">↗️</a><pre> <span class='Function'>↕</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>4</span> <span class='Comment'># Array of lists
</span>┌─
@@ -31,7 +31,7 @@
</pre>
<p>There are several different ways to show arrays: as a string <code><span class='String'>&quot;&quot;</span></code>, with brackets <code><span class='Bracket'>⟨⟩</span></code>, or with corners <code><span class='Value'>┌</span></code> and <code><span class='Value'>┘</span></code>. We'll start with the most general, the corners. These show arrays of any rank while the other two ways are special cases for lists.</p>
<p>Array displays show only the array shape and elements. The <a href="fill.html">fill</a> is an inferred property and the display never indicates or depends on it.</p>
-<h3 id="corners">Corners</h3>
+<h3 id="corners"><a class="header" href="#corners">Corners</a></h3>
<p>Those top-left and bottom-right corners are a distinctive part of BQN's display, as other systems almost always completely enclose the contents. BQN could add the other two corners, naturally; it just doesn't. Within the corners, elements are separated by whitespace only, and generally aligned to the top left.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oMiwieHki4p+p4omN4p+oMuKAvzLipYoiYWJjZCIsNOKfqSAgIyBOZXN0ZWQgMsOXMiBhcnJheQ==">↗️</a><pre> <span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='String'>&quot;xy&quot;</span><span class='Bracket'>⟩</span><span class='Function'>≍</span><span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Function'>⥊</span><span class='String'>&quot;abcd&quot;</span><span class='Separator'>,</span><span class='Number'>4</span><span class='Bracket'>⟩</span> <span class='Comment'># Nested 2×2 array
</span>┌─
@@ -43,7 +43,7 @@
</pre>
<p>The lack of extra separation is to make it clear that the corners enclose the array rather than any of its elements (elements are still distinguishable becase an individual element won't contain whitespace except maybe between quotes). Now every set of corners indicates one array. This is a good fit for the <a href="based.html">based array model</a>, where data doesn't have to be in an array.</p>
-<h4 id="rank-indicator">Rank indicator</h4>
+<h4 id="rank-indicator"><a class="header" href="#rank-indicator">Rank indicator</a></h4>
<p>The top left corner indicates the rank of an array. Here's a neat way using <a href="fold.html">Fold</a> (<code><span class='Modifier'>´</span></code>) and <a href="prefixes.html">Prefixes</a> (<code><span class='Function'>↑</span></code>) to nest ranks 0 through 6 together:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MCDipYrin5w8wrQg4oaRNuKlijE=">↗️</a><pre> <span class='Number'>0</span> <span class='Function'>⥊</span><span class='Modifier2'>⟜</span><span class='Function'>&lt;</span><span class='Modifier'>´</span> <span class='Function'>↑</span><span class='Number'>6</span><span class='Function'>⥊</span><span class='Number'>1</span>
┌·
@@ -67,7 +67,7 @@
<span class='Value'>┌</span><span class='Nothing'>·</span> <span class='Value'>┌─</span> <span class='Value'>┌─</span> <span class='Value'>┌─</span> <span class='Value'>┌─</span> <span class='Value'>┌─</span> <span class='Value'>┌</span><span class='Number'>6</span> <span class='Value'>┌</span><span class='Number'>7</span> <span class='Value'>…</span>
<span class='Nothing'>·</span> <span class='Nothing'>·</span> <span class='Value'>╵</span> <span class='Value'>╎</span> <span class='Value'>┆</span> <span class='Value'>┊</span> <span class='Value'>┊</span> <span class='Value'>┊</span> <span class='Value'>…</span>
</pre>
-<h4 id="high-rank-layout">High-rank layout</h4>
+<h4 id="high-rank-layout"><a class="header" href="#high-rank-layout">High-rank layout</a></h4>
<p>We've seen already that elements of a list are placed side by side, while the rows of a table (rank-2 array) are stacked on top of each other.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=PMKoIOKGlTUgICAgICAgICMgQSBsaXN0IG9mIHVuaXRzCgoy4oC/M+KAvzTiiY0x4oC/MOKAvzUgICMgQSB0YWJsZQ==">↗️</a><pre> <span class='Function'>&lt;</span><span class='Modifier'>¨</span> <span class='Function'>↕</span><span class='Number'>5</span> <span class='Comment'># A list of units
</span>┌─
@@ -120,7 +120,7 @@
·lmnopqrst"
</pre>
-<h4 id="empty-arrays">Empty arrays</h4>
+<h4 id="empty-arrays"><a class="header" href="#empty-arrays">Empty arrays</a></h4>
<p>The top-left corner can show the rank of an array but not its shape; the shape must be seen from the data. An empty array has no data, and it's hard to tell shape from a bunch of blank space. In general, an empty array is printed as <code><span class='Function'>↕</span><span class='Value'>shape</span></code>. An empty list is shown using brackets <code><span class='Bracket'>⟨⟩</span></code>, which are discussed in the next section.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oaVwqgg4p+oMOKAvzQsIDPigL8w4oC/MSwgMuKAvzDigL8wLCAw4p+p">↗️</a><pre> <span class='Function'>↕</span><span class='Modifier'>¨</span> <span class='Bracket'>⟨</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Separator'>,</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Separator'>,</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Separator'>,</span> <span class='Number'>0</span><span class='Bracket'>⟩</span>
⟨ ↕0‿4 ↕3‿0‿1 ↕2‿0‿0 ⟨⟩ ⟩
@@ -135,7 +135,7 @@
</pre>
-<h3 id="simple-lists">Simple lists</h3>
+<h3 id="simple-lists"><a class="header" href="#simple-lists">Simple lists</a></h3>
<p>In two cases BQN might use a different format to display a list on one line. The first is for a string (that is, a list of just characters), which is displayed using the exact source code that would generate it. This is different from the array display, which doesn't escape quotes, and substitutes control characters to make sure things stay horizontal.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=InRhYigJKStxdW90ZSgiIikiCgriiY0idGFiKAkpK3F1b3RlKCIiKSI=">↗️</a><pre> <span class='String'>&quot;tab( )+quote(&quot;&quot;)&quot;</span>
"tab( )+quote("")"
@@ -158,10 +158,10 @@
⟨⟩
</pre>
<p>This case also covers empty lists, which are shown as <code><span class='Bracket'>⟨⟩</span></code>. This includes an empty string, as the only difference between an empty string and any other empty list is its fill element and array displays don't depend on the fill.</p>
-<h2 id="list-literals">List literals</h2>
+<h2 id="list-literals"><a class="header" href="#list-literals">List literals</a></h2>
<p><em>The tutorial section <a href="../tutorial/list.html#list-notation">here</a> also covers this topic.</em></p>
<p>There are three kinds literal notation for lists: strings, list notation, and stranding. Strings indicate character lists (with space for the <a href="fill.html">fill</a>) and the other two can combine any sequence of elements.</p>
-<h3 id="strings">Strings</h3>
+<h3 id="strings"><a class="header" href="#strings">Strings</a></h3>
<p>A <strong>string</strong> consists of a sequence of characters surrounded by double quotes <code><span class='String'>&quot;&quot;</span></code>. The only rule for the characters inside is that any double quote must be escaped by repeating it twice; otherwise the string ends at that point.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Ii0nw5clIiIqIgoKIi0nw5clIioiICAjIEVzY2FwaW5nIGZhaWx1cmU=">↗️</a><pre> <span class='String'>&quot;-'×%&quot;&quot;*&quot;</span>
"-'×%""*"
@@ -170,7 +170,7 @@
</span>ERROR
</pre>
<p>Even special characters like a newline can appear in a string literal, so that string literals are automatically multi-line.</p>
-<h3 id="brackets">Brackets</h3>
+<h3 id="brackets"><a class="header" href="#brackets">Brackets</a></h3>
<p><strong>List notation</strong> uses angle brackets <code><span class='Bracket'>⟨⟩</span></code>. The contents are structurally identical to those of a <a href="block.html">block</a>, that is, a list of expressions <a href="syntax.html#separators">separated</a> by <code><span class='Separator'>,</span></code> or <code><span class='Separator'>⋄</span></code> or newlines. Unlike a block, a list doesn't need to have any expressions: <code><span class='Bracket'>⟨⟩</span></code> or <code><span class='Bracket'>⟨</span><span class='Separator'>⋄</span><span class='Bracket'>⟩</span></code> or <code><span class='Bracket'>⟨</span><span class='Separator'>,,⋄,</span><span class='Bracket'>⟩</span></code> will create an empty list. Other differences are that a list doesn't introduce a new <a href="lexical.html">scope</a> and all of the expressions have to result in a value, not Nothing (<code><span class='Nothing'>·</span></code>).</p>
<p>Entries in a list are evaluated in source order, and the value will be the list of those results. The list has a subject role, even if it contains expressions with other roles. Any value can be an element.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oQCwg4o2Jy5gsIOKJjSJhYmMi4p+p">↗️</a><pre> <span class='Bracket'>⟨</span><span class='String'>@</span><span class='Separator'>,</span> <span class='Function'>⍉</span><span class='Modifier'>˘</span><span class='Separator'>,</span> <span class='Function'>≍</span><span class='String'>&quot;abc&quot;</span><span class='Bracket'>⟩</span>
@@ -192,7 +192,7 @@
<span class='String'>&quot;e6&quot;</span>
<span class='Bracket'>⟩</span>
</pre>
-<h3 id="strands">Strands</h3>
+<h3 id="strands"><a class="header" href="#strands">Strands</a></h3>
<p><strong>Strand notation</strong> is another way to write lists of length two or more. The elements are connected with the ligature character <code><span class='Ligature'>‿</span></code>. It has a precedence lower than the <a href="namespace.html">namespace</a> dot but higher than anything else other than paired brackets <code><span class='Paren'>()</span></code>, <code><span class='Brace'>{}</span></code>, and <code><span class='Bracket'>⟨⟩</span></code>, so compound elements generally need to be placed in parentheses. Expressions joined by ligatures behave exactly the same as those in list notation: they are evaluated in order and placed in a list.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=K+KAv8K04oC/4oiY4oC/w5cKCivigL/CtOKAv+KImOKAv8OXICDiiaEgIOKfqCsswrQs4oiYLMOX4p+p">↗️</a><pre> <span class='Function'>+</span><span class='Ligature'>‿</span><span class='Modifier'>´</span><span class='Ligature'>‿</span><span class='Modifier2'>∘</span><span class='Ligature'>‿</span><span class='Function'>×</span>
⟨ + ´ ∘ × ⟩
@@ -201,7 +201,7 @@
1
</pre>
<p>Strand notation is mainly useful for simple elements that don't require parentheses. A strand with one set of parentheses is no shorter than using list notation (but could look nicer), and one with more parentheses will be longer.</p>
-<h4 id="why-not-whitespace">Why not whitespace?</h4>
+<h4 id="why-not-whitespace"><a class="header" href="#why-not-whitespace">Why not whitespace?</a></h4>
<p>In APL two or more arrays that are next to each other in the code are combined into a list, a convention known as <a href="https://aplwiki.com/wiki/Strand_notation">stranding</a>. So <code><span class='Number'>2</span> <span class='Number'>3</span> <span class='Number'>5</span> <span class='Function'>+</span> <span class='Number'>1</span></code> adds a list to a number. This looks substantially cleaner than a BQN list, so it's reasonable to ask: why give it up? I admit I've been jealous of that clean look at times. But I'm also finding I view it with a certain unease: what's hiding in that space?</p>
<p>This feeling comes because the language is doing something I didn't ask it to, and it's justified. Consider the BQN expression <code><span class='Value'>a</span> <span class='Function'>+</span><span class='Modifier'>˝</span><span class='Modifier2'>∘</span><span class='Function'>×</span><span class='Modifier2'>⎉</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>∞</span> <span class='Value'>b</span></code> for a matrix product. If we remove the space then we have <code><span class='Value'>…</span><span class='Modifier2'>⎉</span><span class='Number'>1</span> <span class='Number'>∞</span> <span class='Value'>b</span></code>. There's no good rule to say which of the three subjects <code><span class='Number'>1</span></code>, <code><span class='Number'>∞</span></code>, and <code><span class='Value'>b</span></code> to strand together. For modifiers like Rank and <a href="depth.html#the-depth-modifier">Depth</a> we'd like stranding to bind more tightly than modifier application, but in order to actually use arguments for these modifiers the modifier application should take precedence. Similar but simpler cases show up more often when binding an argument to a function. The difference between the following two statements is obvious in BQN, but with space-for-stranding one of them would require a complicating parenthesis.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyAx4oq4K+KKuMOXIDUKCjPigL8x4oq4K+KKuMOXIDU=">↗️</a><pre> <span class='Number'>3</span> <span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Modifier2'>⊸</span><span class='Function'>×</span> <span class='Number'>5</span>
@@ -213,7 +213,7 @@
<p>Explicit stranding is also more general, because it applies equally to elements of any role. <code><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Function'>+</span><span class='Ligature'>‿</span><span class='Number'>3</span></code> is a perfectly fine list in BQN—maybe it's part of an AST—while <code><span class='Number'>2</span> <span class='Function'>+</span> <span class='Number'>3</span></code> is clearly not a list. J and K restrict their stranding even further, to numbers only. It does mean that issues with stranding show up in fewer cases, but it also means that changing one element of a list from a constant to a variable requires rewriting the whole list.</p>
<p>Why can't the more explicit list notation <code><span class='Bracket'>⟨</span><span class='Value'>a</span><span class='Separator'>,</span><span class='Value'>b</span><span class='Separator'>,</span><span class='Value'>c</span><span class='Bracket'>⟩</span></code> drop the separators? This is also largely for reasons of generality, which is even more important given that <code><span class='Bracket'>⟨⟩</span></code> is the more general-purpose list notation. Writing <code><span class='Bracket'>⟨</span><span class='Function'>÷</span><span class='Separator'>,</span><span class='Function'>-</span><span class='Separator'>,</span><span class='Number'>4</span><span class='Bracket'>⟩</span></code> without the <code><span class='Separator'>,</span></code> won't go well. For something like <code><span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Function'>×</span><span class='Value'>c</span><span class='Separator'>,</span><span class='Value'>b</span><span class='Function'>-</span><span class='Number'>1</span><span class='Bracket'>⟩</span></code>, maybe the interpreter could sort it out but it would be pretty confusing. Pretty soon you're going through the list character by character trying to figure out which space is actually a separator. And cursing, probably.</p>
<p>Fortunately, I find that after a reasonable period of adjustment typing ligatures instead of spaces doesn't feel strange, and reading code is improved overall by the more explicit notation. A minor note is that lists of literal numbers, where APL-style stranding is best, tend to show up more in the snippets that beginners write to test out the language than in programs even in the tens of lines. So this issue sticks out in first experiences with BQN, but will probably come up less later on.</p>
-<h3 id="array-notation">Array notation?</h3>
+<h3 id="array-notation"><a class="header" href="#array-notation">Array notation?</a></h3>
<p>BQN has literal notation for lists only right now. To get an array with rank other than 1, either <a href="reshape.html">reshape</a> a list, or <a href="couple.html#merge-and-array-theory">merge</a> a list of arrays:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oiY4oC/MiDipYog4p+oMiwzLCA0LDEsIDAsNeKfqQoKPiDin6gy4oC/MywgNOKAvzEsIDDigL814p+p">↗️</a><pre> <span class='Modifier2'>∘</span><span class='Ligature'>‿</span><span class='Number'>2</span> <span class='Function'>⥊</span> <span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Separator'>,</span> <span class='Number'>4</span><span class='Separator'>,</span><span class='Number'>1</span><span class='Separator'>,</span> <span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>5</span><span class='Bracket'>⟩</span>
┌─
diff --git a/docs/doc/assert.html b/docs/doc/assert.html
index 7630f925..2e112283 100644
--- a/docs/doc/assert.html
+++ b/docs/doc/assert.html
@@ -4,7 +4,7 @@
<title>BQN: Assert</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="assert">Assert</h1>
+<h1 id="assert"><a class="header" href="#assert">Assert</a></h1>
<p>BQN takes the position that errors exist to indicate exceptional conditions that the developer of a given program didn't expect. However, the types of errors that BQN naturally checks for, such as mismatched shapes in Couple (<code><span class='Function'>≍</span></code>), aren't always enough to detect exceptional conditions. Issues like numeric values that don't make physical sense will slip right through. BQN makes it easy for a programmer to check for these sorts of problems by building in the primitive Assert, written <code><span class='Function'>!</span></code>. This function checks whether <code><span class='Value'>𝕩</span></code> matches <code><span class='Number'>1</span></code>: if it does, then it does nothing and returns <code><span class='Value'>𝕩</span></code>, and otherwise it gives an error.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ISAyPTIgICMgUGFzc2VkCiEgMj0zICAjIEZhaWxlZA==">↗️</a><pre> <span class='Function'>!</span> <span class='Number'>2</span><span class='Function'>=</span><span class='Number'>2</span> <span class='Comment'># Passed
</span>1
@@ -23,7 +23,7 @@ ERROR
<span class='Bracket'>⟨</span><span class='Modifier2'>∘</span><span class='Separator'>,</span><span class='String'>&quot;abc&quot;</span><span class='Separator'>,</span><span class='Modifier'>˜</span><span class='Bracket'>⟩</span> <span class='Function'>!</span> <span class='String'>'0'</span> <span class='Comment'># Okay this is not a very helpful printout
</span>ERROR
</pre>
-<h3 id="computing-the-error-message-on-demand">Computing the error message on demand</h3>
+<h3 id="computing-the-error-message-on-demand"><a class="header" href="#computing-the-error-message-on-demand">Computing the error message on demand</a></h3>
<p>Because the left argument to a function is always computed before the function is called, Assert <a href="../commentary/problems.html#assert-has-no-way-to-compute-the-error-message">doesn't let you</a> compute the error message only if there's an error. This might be a problem if the error message computation is slow or has side effects. There are a few ways to work around the issue:</p>
<ul>
<li>Handle errors with ordinary if-then logic (perhaps using <a href="control.html">control structures</a>). This is probably the best path for user-facing applications where displaying an error goes through the user interface.</li>
diff --git a/docs/doc/based.html b/docs/doc/based.html
index 6fce0526..7974f1d5 100644
--- a/docs/doc/based.html
+++ b/docs/doc/based.html
@@ -4,12 +4,12 @@
<title>BQN: Based array theory</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="based-array-theory">Based array theory</h1>
+<h1 id="based-array-theory"><a class="header" href="#based-array-theory">Based array theory</a></h1>
<style>code span.Comment { color: inherit; }</style>
<p><em>&quot;Like a normal programming language&quot;</em></p>
<p>This page explains how BQN's array model (christened &quot;based&quot; <a href="https://dl.acm.org/doi/abs/10.1145/586656.586663">in 1981</a>) differs from the models used by existing APL dialects, and why the choice was made to discard APL's &quot;everything is an array&quot; dictum. If you're not wondering what the difference is, and don't think everything should be an array, then you can probably just read about BQN's <a href="types.html">type system</a> instead.</p>
<p>If you're an array programmer then I have bad news for you. My thesis here is that APL took a wrong turn around 1981 when it extrapolated the excellent, but limited, flat array model of APL\360 to the ill-founded nested array model and the rigorous but clumsy boxed array model. Make that two wrong turns, I guess. Simultaneously. Anyway, if you've been brought up in either of these array models, then the best thing to do when starting BQN is to throw out your existing ideas about array depth and nesting (but don't worry too much: the fundamental concept of an array as a rectangular collection of data still holds!). If you'd like to ponder the relationship of BQN to APL later, that's great, but trying to initially understand BQN in terms of APL or J will just cause confusion.</p>
-<h2 id="starting-from-atoms">Starting from atoms</h2>
+<h2 id="starting-from-atoms"><a class="header" href="#starting-from-atoms">Starting from atoms</a></h2>
<p>APL tends to define its data by starting with the array and then looking downwards in depth at what it contains. The based array model, as the name suggests, starts at the foundations, which in BQN are called &quot;atoms&quot;. There are six <a href="types.html">types</a> of atom, which together with the array type give the seven types a value can have in BQN. Based means being yourself, and an atom's <em>not</em> an array.</p>
<p>An atom has <a href="depth.html">depth</a> 0, and doesn't inherently have a shape. However, primitives that expect an array promote atoms by <a href="enclose.html">enclosing</a> them to get a rank-0, or <em>unit</em>, array that contains the atom (any value can be enclosed in this way, giving a unit array with higher depth, but it only happens automatically for atoms). <a href="shape.html">Rank and shape</a> both do this, so an atom can be considered to have the same dimensions as a unit array: rank 0 and shape <code><span class='Bracket'>⟨⟩</span></code>. An atom is also considered a kind of unit, but it's not a unit array.</p>
<p>Atoms are displayed as plain values, while enclosed atoms, that is, depth-1 unit arrays, are shown with an array display.</p>
@@ -39,14 +39,14 @@
· 3
</pre>
-<h2 id="building-arrays">Building arrays</h2>
+<h2 id="building-arrays"><a class="header" href="#building-arrays">Building arrays</a></h2>
<p>Arrays in BQN, like nearly all data structures in modern programming languages, are an <a href="https://en.wikipedia.org/wiki/Inductive_type">inductive type</a>. That means that an array can be constructed from existing values, but can't contain itself (including recursively: an array always has finite depth). To construct the type of all BQN values inductively, we would say that atoms form the base case, and arrays are an inductive case: an array is a shaped collection of existing BQN values. For an array programmer, this is of course the easy part.</p>
-<h2 id="versus-the-nested-array-model">Versus the nested array model</h2>
+<h2 id="versus-the-nested-array-model"><a class="header" href="#versus-the-nested-array-model">Versus the nested array model</a></h2>
<p>The <a href="https://aplwiki.com/wiki/Array_model#Nested_array_theory">nested array model</a> of NARS, APL2, Dyalog, and GNU APL can be constructed from the based model by adding a rule: a unit (or &quot;scalar&quot; in APL) array containing an atom is equivalent to that atom. The equivalents of atoms in nested array theory are thus called &quot;simple scalars&quot;, and they are considered arrays but share the characteristics of BQN atoms. Nested arrays don't form an inductive type, because simple scalars contain themselves.</p>
<p>Nested array theory can seem simpler to use, because the programmer never has to worry about simple scalars being enclosed the wrong number of times: all these encloses have been identified with each other. For example, <code><span class='String'>'</span><span class='Value'>abcd</span><span class='String'>'</span><span class='Value'>[</span><span class='Number'>2</span><span class='Value'>]</span></code> returns a character while BQN's <code><span class='Number'>2</span><span class='Function'>⊏</span><span class='String'>&quot;abcd&quot;</span></code> returns an array containing a character. However, these issues usually still appear with more complex arrays: <code><span class='String'>'</span><span class='Value'>ab</span><span class='String'>'</span> <span class='Number'>1</span> <span class='String'>'</span><span class='Value'>ef</span><span class='String'>'</span><span class='Value'>[</span><span class='Number'>2</span><span class='Value'>]</span></code> (here spaces are used for stranding) is not a string but an enclosed string!</p>
<p>A property that might warn about dangerous issues like this is that nested array theory tends to create <em>inversions</em> where the depth of a particular array depends on its rank (reversing the normal hierarchy of depth→rank→shape). A 1-character string has depth 1, but when its rank is reduced to 0, its depth is reduced as well.</p>
<p>In some cases nested array theory can remove a depth issue entirely, and not just partially. Most notable is the <a href="../commentary/problems.html#search-function-depth">search function result depth</a> issue, in which it's impossible for a search function in BQN to return an atomic number because it always returns an array. Nested array theory doesn't have this issue since a scalar number is &quot;just a number&quot;, and more complicated arrays can't cause problems because a search function's result is always a numeric array. The other half of the problem, about the non-principal argument depth, is only partly hidden, and causes problems for example when searching for a single string out of a list of strings.</p>
-<h2 id="versus-the-boxed-array-model">Versus the boxed array model</h2>
+<h2 id="versus-the-boxed-array-model"><a class="header" href="#versus-the-boxed-array-model">Versus the boxed array model</a></h2>
<p>The <a href="https://aplwiki.com/wiki/Array_model#Boxes">boxed array model</a> of SHARP APL, A+, and J is an inductive system like BQN's. But this model uses arrays as the base case: numeric and character arrays are the simplest kind of data allowed, and &quot;a number&quot; means a rank-0 numeric array. The inductive step is the array of boxes; as with numbers &quot;a box&quot; is simply a rank-0 array of boxes.</p>
<p>Numeric and character arrays in this system have depth 0. In general these correspond to arrays of depth 1 in BQN, but because there's no lower depth they are also used where BQN atoms would appear. For example, both Shape (<code><span class='Value'>$</span></code>) and Length (<code><span class='Comment'>#</span></code>) return depth-0 results in J. For an array <code><span class='Value'>a</span></code> with rank at least 1, the length <code><span class='Comment'>#a</span></code> is exactly <code><span class='Value'>[</span><span class='Function'>/</span> <span class='Value'>$</span> <span class='Value'>a</span></code>, while the identical BQN code <code><span class='Function'>⊣</span><span class='Modifier'>˝</span> <span class='Function'>≢</span> <span class='Value'>a</span></code> returns not <code><span class='Function'>≠</span> <span class='Value'>a</span></code> but <code><span class='Function'>&lt;</span> <span class='Function'>≠</span> <span class='Value'>a</span></code>. Like the nested model, the boxed model can hide depth issues that occur at lower depths but generally reveals them at higher depths.</p>
<p>The boundary at depth 0 will tend to cause inconsistencies and confusion in any array language, and boxed array languages push this boundary up a level. This leads to the programmer spending more effort managing boxes: for example, to reverse each list in a list of lists, the programmer can use reverse under open, <code><span class='Function'>|</span><span class='Value'>.</span> <span class='Value'>&amp;.</span> <span class='Function'>&gt;</span></code>. But to find the lengths of each of these lists, <code><span class='Comment'># &amp;. &gt;</span></code> would yield a boxed list, which is usually not wanted, so <code><span class='Comment'># @ &gt;</span></code> is needed instead. BQN shows that a system that doesn't require these distinctions is possible, as a BQN programmer would use <code><span class='Function'>⌽</span><span class='Modifier'>¨</span></code> and <code><span class='Function'>≠</span><span class='Modifier'>¨</span></code>.</p>
diff --git a/docs/doc/block.html b/docs/doc/block.html
index 82547a15..a3fa4397 100644
--- a/docs/doc/block.html
+++ b/docs/doc/block.html
@@ -4,7 +4,7 @@
<title>BQN: Blocks</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="blocks">Blocks</h1>
+<h1 id="blocks"><a class="header" href="#blocks">Blocks</a></h1>
<p>In BQN, a <em>block</em> is any piece of code surrounded with curly braces <code><span class='Brace'>{}</span></code>. Blocks can be used simply to group statements, or can define functions or modifiers. They are the sole large-scale structure used to organize programs.</p>
<p>Blocks are most commonly used to define functions by including one of the special names for arguments, <code><span class='Value'>𝕨</span></code> or <code><span class='Value'>𝕩</span></code>. With the operands <code><span class='Function'>𝔽</span></code> or <code><span class='Function'>𝔾</span></code>, they can also define 1-modifiers or 2-modifiers.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=e/CdlakrMX0gMwrDl3vwnZWp8J2UvfCdlal9IDQ=">↗️</a><pre> <span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Function'>+</span><span class='Number'>1</span><span class='Brace'>}</span> <span class='Number'>3</span>
@@ -17,7 +17,7 @@
<span class='Brace'>{</span> <span class='Value'>a</span><span class='Gets'>←</span><span class='String'>&quot;inner&quot;</span> <span class='Separator'>⋄</span> <span class='Value'>a</span><span class='Ligature'>‿</span><span class='Value'>b</span> <span class='Brace'>}</span>
⟨ "inner" "outer" ⟩
</pre>
-<h2 id="headerless-blocks">Headerless blocks</h2>
+<h2 id="headerless-blocks"><a class="header" href="#headerless-blocks">Headerless blocks</a></h2>
<p>In the simplest case a block is just a list of statements, which are executed to <em>evaluate</em> the block. A block with no special names like <code><span class='Value'>𝕨</span></code> or <code><span class='Value'>𝕩</span></code> is called an <em>immediate block</em>, and is evaluated as soon as it is reached. The only think such a block does is group some statements, and create a scope for them so that definitions made there are discarded when the block finishes. Even this small amount of functionality could be useful; as an example the following program can build up an array from named components without polluting the rest of the program with those names.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=dXBkb3duIOKGkCB7IHVw4oaQ4oaVNSDii4QgZG93buKGkOKMvXVwIOKLhCB1cOKIvmRvd24gfQp1cGRvd24=">↗️</a><pre> <span class='Value'>updown</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Value'>up</span><span class='Gets'>←</span><span class='Function'>↕</span><span class='Number'>5</span> <span class='Separator'>⋄</span> <span class='Value'>down</span><span class='Gets'>←</span><span class='Function'>⌽</span><span class='Value'>up</span> <span class='Separator'>⋄</span> <span class='Value'>up</span><span class='Function'>∾</span><span class='Value'>down</span> <span class='Brace'>}</span>
<span class='Value'>updown</span>
@@ -66,7 +66,7 @@
</tbody>
</table>
<p>Of these, <code><span class='Value'>𝕣</span></code> is sort of a &quot;more special&quot; character, as we'll discuss below. Except for <code><span class='Value'>𝕣</span></code>, every special name is a single character and can't have underscores added to spell it as a modifier, allowing a modifier to be applied to a special name with no spacing as in <code><span class='Value'>𝕗</span><span class='Modifier'>_m</span></code>, something that can't be done with ordinary names.</p>
-<h3 id="arguments">Arguments</h3>
+<h3 id="arguments"><a class="header" href="#arguments">Arguments</a></h3>
<p>The names <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code>, and their uppercase spellings, represent function arguments. As the argument to a function is typically data, it's more common to use the lowercase forms for these. Either of these names will turn an immediate block into a function (or an immediate modifier into a deferred one; see the next section). Instead of being evaluated as soon as it appears in the source, a function is evaluated when it's called, with the special names set to appropriate values. Unlike in Dyalog APL's dfns, their values can be changed like ordinary variables.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eydjJz3wnZWpfSAiYWJjZCIKeyDwnZWpK+KGqTIg4ouEIDDiiY3wnZWpIH0gMwo0IHsg4p+o8J2VqeKLhC3wnZWo4p+pIH0gNQ==">↗️</a><pre> <span class='Brace'>{</span><span class='String'>'c'</span><span class='Function'>=</span><span class='Value'>𝕩</span><span class='Brace'>}</span> <span class='String'>&quot;abcd&quot;</span>
⟨ 0 0 1 0 ⟩
@@ -97,7 +97,7 @@
143.4131591025766
</pre>
<p>Called dyadically, this function will expand to <code><span class='Paren'>(</span><span class='Function'>⋆</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>-</span><span class='Value'>𝕩</span></code>, so we might expect the monadic result to be <code><span class='Function'>-</span><span class='Value'>𝕩</span></code>. This sort of expansion isn't right with <code><span class='Nothing'>·</span></code> on the left. <code><span class='Function'>⋆</span><span class='Modifier2'>⊸</span><span class='Function'>-</span></code> taken as a whole is a function, so <code><span class='Nothing'>·</span> <span class='Function'>⋆</span><span class='Modifier2'>⊸</span><span class='Function'>-</span> <span class='Value'>𝕩</span></code> is just <code><span class='Function'>⋆</span><span class='Modifier2'>⊸</span><span class='Function'>-</span> <span class='Value'>𝕩</span></code>, or <code><span class='Paren'>(</span><span class='Function'>⋆</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Function'>-</span><span class='Value'>𝕩</span></code>, giving the large result seen above.</p>
-<h3 id="operands">Operands</h3>
+<h3 id="operands"><a class="header" href="#operands">Operands</a></h3>
<p>The special names <code><span class='Function'>𝔽</span></code> and <code><span class='Function'>𝔾</span></code>, and their lowercase forms, represent operands. Since operands are more often functions, they're typically shown with the uppercase spelling. If <code><span class='Function'>𝔽</span></code> is present in a block then it defines a 1-modifier or 2-modifier depending on whether <code><span class='Function'>𝔾</span></code> is present; if <code><span class='Function'>𝔾</span></code> is there it's always a 2-modifier.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=NCB7w5fLnPCdlZd9CjIge/CdlZcr8J2VmH0gMw==">↗️</a><pre> <span class='Number'>4</span> <span class='Brace'>{</span><span class='Function'>×</span><span class='Modifier'>˜</span><span class='Value'>𝕗</span><span class='Brace'>}</span>
16
@@ -116,7 +116,7 @@
⟨ ⟨ 2 ⟩ ¯5 ⟩
</pre>
<p>The distinction between an immediate and deferred modifier only matters inside the braces. Once defined, the object is simply a modifier that can be called on operands to return a result. For a deferred modifier this result will always be a function; for an immediate modifier it could be anything.</p>
-<h3 id="self-reference">Self-reference</h3>
+<h3 id="self-reference"><a class="header" href="#self-reference">Self-reference</a></h3>
<p>If a block is assigned a name after it is created, this name can be used for recursion:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=RmFjdCDihpAgeyDwnZWpIMOXICgw4oq4PCnil7Yx4oC/RmFjdCDwnZWpLTEgfQpGYWN0IDcKKMOXwrQxK+KGlSkgNyAgIyBUaGVyZSdzIG9mdGVuIGEgc2ltcGxlciBzb2x1dGlvbiB0aGFuIHJlY3Vyc2lvbg==">↗️</a><pre> <span class='Function'>Fact</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Value'>𝕩</span> <span class='Function'>×</span> <span class='Paren'>(</span><span class='Number'>0</span><span class='Modifier2'>⊸</span><span class='Function'>&lt;</span><span class='Paren'>)</span><span class='Modifier2'>◶</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Function'>Fact</span> <span class='Value'>𝕩</span><span class='Function'>-</span><span class='Number'>1</span> <span class='Brace'>}</span>
<span class='Function'>Fact</span> <span class='Number'>7</span>
@@ -134,7 +134,7 @@
5040
</pre>
<p>Because <code><span class='Value'>𝕣</span></code> only ever refers to a 1-modifier or 2-modifer, it can never make sense to refer to it as a function, and the uppercase letter <code><span class='Value'>ℝ</span></code> is not recognized by BQN. In order to allow <code><span class='Value'>𝕣</span></code> to be spelled as a 1-modifier <code><span class='Modifier'>_𝕣</span></code> or 2-modifier <code><span class='Modifier2'>_𝕣_</span></code>, it is treated as an ordinary identifier character, so it must be separated from letters or numbers by spaces.</p>
-<h2 id="block-headers">Block headers</h2>
+<h2 id="block-headers"><a class="header" href="#block-headers">Block headers</a></h2>
<p>As a program becomes larger, it often becomes necessary to name inputs to blocks rather than just using special names. It can also become difficult to identify what kind of block is being defined, as it requires scanning through the block for special names. A <em>block header</em>, which is separated from the body of a block by a colon <code><span class='Value'>:</span></code>, specifies the kind of block and can declare names for the block and its inputs. Its syntax mirrors an application of the block. As suggested by the positioning, the names given in a header apply only inside the block.</p>
<pre><span class='Comment'># A dyadic function called Func
</span><span class='Brace'>{</span> <span class='Value'>l</span> <span class='Function'>Func</span> <span class='Value'>r:</span>
@@ -160,16 +160,16 @@
<span class='Value'>…</span>
</pre>
<p>Unlike these assignments, the header also constrains what inputs the block can take: a monadic 1-modifier like the one above can't take a right operand or left argument, and consequently its body can't contain <code><span class='Function'>𝔾</span></code> or <code><span class='Value'>𝕨</span></code>. Calling it with a left argument, or a right argument that isn't a two-element list, will result in an error.</p>
-<h3 id="destructuring">Destructuring</h3>
+<h3 id="destructuring"><a class="header" href="#destructuring">Destructuring</a></h3>
<p>Arguments, but not operands, allow destructuring like assignment does. While assignment only tolerates lists of variables, header destructuring also allows constants. The argument must match the given structure, including the constants where they appear, or an error results.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=RGVzdHJ1Y3Qg4oaQIHsg8J2ViiBh4oC/MeKAv+KfqGIsMuKfqTogYeKJjWIgfQpEZXN0cnVjdCAgICAgICA14oC/MeKAv+KfqDcsMuKfqQ==">↗️</a><pre> <span class='Function'>Destruct</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Function'>𝕊</span> <span class='Value'>a</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Bracket'>⟨</span><span class='Value'>b</span><span class='Separator'>,</span><span class='Number'>2</span><span class='Bracket'>⟩</span><span class='Value'>:</span> <span class='Value'>a</span><span class='Function'>≍</span><span class='Value'>b</span> <span class='Brace'>}</span>
<span class='Function'>Destruct</span> <span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Bracket'>⟨</span><span class='Number'>7</span><span class='Separator'>,</span><span class='Number'>2</span><span class='Bracket'>⟩</span>
⟨ 5 7 ⟩
</pre>
-<h3 id="special-names-in-headers">Special names in headers</h3>
+<h3 id="special-names-in-headers"><a class="header" href="#special-names-in-headers">Special names in headers</a></h3>
<p>Any element of a function or modifier header can be left nameless by using the corresponding special name in that position, instead of an identifier. For example, the header <code><span class='Value'>𝕨</span> <span class='Function'>𝔽</span><span class='Modifier2'>_𝕣_</span><span class='Function'>𝔾</span> <span class='Value'>𝕩:</span></code> incorporates as much vagueness as possible. It indicates a deferred 2-modifier, but provides no other information.</p>
<p>The name <code><span class='Value'>𝕨</span></code> in this context can refer to either a left argument or no left argument, allowing a header with arguments to be used even for an ambiguous function. Recall that <code><span class='Value'>𝕨</span></code> is the only token other than <code><span class='Nothing'>·</span></code> that can have no value. If an identifier or list is given as the left argument, then the function must be called with a left argument.</p>
-<h3 id="short-headers">Short headers</h3>
+<h3 id="short-headers"><a class="header" href="#short-headers">Short headers</a></h3>
<p>A header does not need to include all inputs, as shown by the <code><span class='Function'>F</span> <span class='Modifier2'>_op_</span> <span class='Value'>val:</span></code> header above. The simplest case, when no inputs are given, is called a <em>label</em>. While it doesn't restrict the inputs, a label specifies the type of the block and gives an internal name that can be used to refer to it.</p>
<pre><span class='Brace'>{</span> <span class='Value'>b:</span> <span class='Comment'># Block
</span><span class='Brace'>{</span> <span class='Function'>𝕊</span><span class='Value'>:</span> <span class='Comment'># Function
@@ -177,7 +177,7 @@
</span><span class='Brace'>{</span> <span class='Modifier2'>_𝕣_</span><span class='Value'>:</span> <span class='Comment'># 2-Modifier
</span></pre>
<p>For immediate blocks, this is the only type of header possible, and it must use an identifier as there is no applicable special name. However, this name can't be used, except for <a href="#returns">returns</a>: it doesn't make sense to refer to a value while it is still being computed!</p>
-<h2 id="multiple-bodies">Multiple bodies</h2>
+<h2 id="multiple-bodies"><a class="header" href="#multiple-bodies">Multiple bodies</a></h2>
<p>Blocks that define functions and deferred modifiers can include more than one body, separated by semicolons <code><span class='Value'>;</span></code>. The body used for a particular evaluation is chosen based on the arguments the the block. One special case applies when there are exactly two bodies either without headers or with labels only: in this case, the first applies when there is one argument and the second when there are two.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=QW1iaXYg4oaQIHsg4p+oMSzwnZWp4p+pIDsg4p+oMizwnZWoLPCdlanin6kgfQpBbWJpdiAnYScKJ2EnIEFtYml2ICdiJw==">↗️</a><pre> <span class='Function'>Ambiv</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Bracket'>⟨</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span> <span class='Value'>;</span> <span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Value'>𝕨</span><span class='Separator'>,</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span> <span class='Brace'>}</span>
<span class='Function'>Ambiv</span> <span class='String'>'a'</span>
@@ -198,7 +198,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyBDYXNlQWRkIDM=">↗️</a><pre> <span class='Number'>3</span> <span class='Function'>CaseAdd</span> <span class='Number'>3</span>
ERROR
</pre>
-<h3 id="case-headers">Case headers</h3>
+<h3 id="case-headers"><a class="header" href="#case-headers">Case headers</a></h3>
<p>A special rule allows for convenient case-matching syntax for one-argument functions. In any function header with one argument, the function name can be omitted as long as the argument is <em>not</em> a plain identifier—it must be <code><span class='Value'>𝕩</span></code> or a compound value like a list to distinguish it from an immediate block label.</p>
<pre><span class='Function'>Test</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='String'>&quot;abc&quot;</span><span class='Value'>:</span> <span class='String'>&quot;string&quot;</span>
@@ -208,6 +208,6 @@ ERROR
<span class='Brace'>}</span>
</pre>
<p>These case-style headers function exactly the same as if they were preceded by <code><span class='Function'>𝕊</span></code>, and can be mixed with other kinds of headers.</p>
-<h2 id="returns">Returns</h2>
+<h2 id="returns"><a class="header" href="#returns">Returns</a></h2>
<p><em>This feature is not yet included in any BQN implementation.</em></p>
<p>The glyph <code><span class='Gets'>→</span></code> indicates an early return from a block. It must be preceded either by one of the self-reference special names <code><span class='Function'>𝕊</span></code> or <code><span class='Value'>𝕣</span></code> or by an internal name for a containing block. The combination of name and return token—like <code><span class='Function'>F</span><span class='Gets'>→</span></code>, let's say—is a function that returns from the current instance of the indicated block. If that instance has already returned, then it instead results in an error.</p>
diff --git a/docs/doc/context.html b/docs/doc/context.html
index 35705a7e..b907956f 100644
--- a/docs/doc/context.html
+++ b/docs/doc/context.html
@@ -4,7 +4,7 @@
<title>BQN's context-free grammar</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="bqns-context-free-grammar">BQN's context-free grammar</h1>
+<h1 id="bqns-context-free-grammar"><a class="header" href="#bqns-context-free-grammar">BQN's context-free grammar</a></h1>
<p>APL has a problem. To illustrate, let's look at an APL expression:</p>
<pre><span class='Value'>a</span> <span class='Value'>b</span> <span class='Value'>c</span> <span class='Value'>d</span> <span class='Value'>e</span>
</pre>
@@ -16,12 +16,12 @@
<pre><span class='Value'>a</span> <span class='Function'>B</span> <span class='Function'>C</span> <span class='Modifier'>_d</span> <span class='Value'>e</span>
</pre>
<p>Here, the lowercase spelling indicates that <code><span class='Value'>a</span></code> and <code><span class='Value'>e</span></code> are to be treated as subjects (&quot;arrays&quot; in APL) while the uppercase spelling of variables <code><span class='Function'>B</span></code> and <code><span class='Function'>C</span></code> are used as functions and <code><span class='Modifier'>_d</span></code> is a 1-modifier (&quot;monadic operator&quot;). Like parentheses for function application, the spelling is not inherent to the variable values used, but instead indicates their grammatical role in this particular expression. A variable has no inherent spelling and can be used in any role, so the names <code><span class='Value'>a</span></code>, <code><span class='Function'>A</span></code>, <code><span class='Modifier'>_a</span></code>, and <code><span class='Modifier2'>_a_</span></code> all refer to exact same variable, but in different roles; typically we use the lowercase name to refer to the variable in isolation—all values are nouns when speaking about them in English. While we still don't know anything about what values <code><span class='Value'>a</span></code>, <code><span class='Value'>b</span></code>, <code><span class='Value'>c</span></code>, and so on have, we know how they interact in the line of code above.</p>
-<h2 id="is-grammatical-context-really-a-problem">Is grammatical context really a problem?</h2>
+<h2 id="is-grammatical-context-really-a-problem"><a class="header" href="#is-grammatical-context-really-a-problem">Is grammatical context really a problem?</a></h2>
<p>Yes, in the sense of <a href="../commentary/problems.html">problems with BQN</a>. A grammar that uses context is harder for humans to read and machines to execute. A particular difficulty is that parts of an expression you don't yet understand can interfere with parts you do, making it difficult to work through an unknown codebase.</p>
<p>One difficulty beginners to APL will encounter is that code in APL at first appears like a string of undifferentiated symbols. For example, a tacit Unique Mask implementation <code><span class='Value'>⍳⍨</span><span class='Function'>=</span><span class='Value'>⍳</span><span class='Modifier2'>∘</span><span class='Function'>≢</span></code> consists of six largely unfamiliar characters with little to distinguish them (in fact, the one obvious bit of structure, the repeated <code><span class='Value'>⍳</span></code>, is misleading as it means different things in each case!). Simply placing parentheses into the expression, like <code><span class='Paren'>(</span><span class='Value'>⍳⍨</span><span class='Paren'>)</span><span class='Function'>=</span><span class='Paren'>(</span><span class='Value'>⍳</span><span class='Modifier2'>∘</span><span class='Function'>≢</span><span class='Paren'>)</span></code>, can be a great help to a beginner, and part of learning APL is to naturally see where the parentheses should go. The equivalent BQN expression, <code><span class='Function'>⊐</span><span class='Modifier'>˜</span><span class='Function'>=↕</span><span class='Modifier2'>∘</span><span class='Function'>≠</span></code>, will likely appear equally intimidating at first, but the path to learning which things apply to which is much shorter: rather than learning the entire list of APL primitives, a beginner just needs to know that superscript characters like <code><span class='Modifier'>˜</span></code> are 1-modifiers and characters like <code><span class='Modifier2'>∘</span></code> with unbroken circles are 2-modifiers before beginning to learn the BQN grammar that will explain how to tie the various parts together.</p>
<p>This sounds like a distant concern to a master of APL or a computer that has no difficulty memorizing a few dozen glyphs. Quite the opposite: the same concern applies to variables whenever you begin work with an unfamiliar codebase! Many APL programmers even enforce variable name conventions to ensure they know the class of a variable. By having such a system built in, BQN keeps you from having to rely on programmers following a style guide, and also allows greater flexibility, including <a href="functional.html">functional programming</a>, as we'll see later.</p>
<p>Shouldn't a codebase define all the variables it uses, so we can see their class from the definition? Not always: consider that in a language with libraries, code might be imported from dependencies. Many APLs also have some dynamic features that can allow a variable to have more than one class, such as the <code><span class='Value'>⍺</span><span class='Gets'>←</span><span class='Function'>⊢</span></code> pattern in a dfn that makes <code><span class='Value'>⍺</span></code> an array in the dyadic case but a function in the monadic case. Regardless, searching for a definition somewhere in the code is certainly a lot more work than knowing the class just from looking! One final difficulty is that even one unknown can delay understanding of an entire expression. Suppose in <code><span class='Function'>A</span> <span class='Function'>B</span> <span class='Value'>c</span></code>, <code><span class='Function'>B</span></code> is a function and <code><span class='Value'>c</span></code> is an array, and both values are known to be constant. If <code><span class='Function'>A</span></code> is known to be a function (even if its value is not yet known), its right argument <code><span class='Function'>B</span> <span class='Value'>c</span></code> can be evaluated ahead of time. But if <code><span class='Function'>A</span></code>'s type isn't known, it's impossible to know if this optimization is worth it, because if it is an array, <code><span class='Function'>B</span></code> will instead be called dyadically.</p>
-<h2 id="bqns-spelling-system">BQN's spelling system</h2>
+<h2 id="bqns-spelling-system"><a class="header" href="#bqns-spelling-system">BQN's spelling system</a></h2>
<p>BQN's expression grammar is a simplified version of the typical APL, removing some oddities like niladic functions and the two-glyph Outer Product operator. Every value can be used in any of four syntactic roles:</p>
<table>
<thead>
@@ -58,7 +58,7 @@
<p>BQN's variables use another system, where the spelling indicates how the variable's value is used. A variable spelled with a lowercase first letter, like <code><span class='Value'>var</span></code>, is a subject. Spelled with an uppercase first letter, like <code><span class='Function'>Var</span></code>, it is a function. Underscores are placed where operands apply to indicate a 1-modifier <code><span class='Modifier'>_var</span></code> or 2-modifier <code><span class='Modifier2'>_var_</span></code>. Other than the first letter or underscore, variables are case-insensitive.</p>
<p>The associations between spelling and syntactic role are considered part of BQN's <a href="../spec/token.html">token formation rules</a>.</p>
<p>One rule for typing is also best considered to be a pre-parsing rule like the spelling system: the role of a brace construct <code><span class='Brace'>{}</span></code> with no header is determined by which special arguments it uses: it's a subject if there are none, but a <code><span class='Value'>𝕨</span></code> or <code><span class='Value'>𝕩</span></code> makes it at least a function, an <code><span class='Function'>𝔽</span></code> makes it a 1- or 2-modifier, and a <code><span class='Function'>𝔾</span></code> always makes it a 2-modifier.</p>
-<h2 id="bqns-grammar">BQN's grammar</h2>
+<h2 id="bqns-grammar"><a class="header" href="#bqns-grammar">BQN's grammar</a></h2>
<p>A formal treatment is included in <a href="../spec/grammar.html">the spec</a>. BQN's grammar—the ways syntactic roles interact—follows the original APL model (plus trains) closely, with allowances for new features like <a href="arrayrepr.html#list-literals">list notation</a>. In order to keep BQN's syntax context-free, the syntactic role of any expression must be known from its contents, just like tokens.</p>
<p>Here is a table of the APL-derived modifier and function application rules:</p>
<table>
@@ -133,7 +133,7 @@
<p>A function with an asterisk indicates that a subject can also be used: in these positions there is no difference between function and subject spellings. Modifier applications bind more tightly than functions, and associate left-to-right while functions associate right-to-left.</p>
<p>BQN lists can be written with angle brackets <code><span class='Bracket'>⟨</span><span class='Value'>elt0</span><span class='Separator'>,</span><span class='Value'>elt1</span><span class='Separator'>,</span><span class='Value'>…</span><span class='Bracket'>⟩</span></code> or ligatures <code><span class='Value'>elt0</span><span class='Ligature'>‿</span><span class='Value'>elt1</span><span class='Ligature'>‿</span><span class='Value'>…</span></code>. In either case the elements can have any type, and the result is a subject.</p>
<p>The statements in a block can also be any role, including the return value at the end. These roles have no effect: outside of braces, an immediate block is a subject, a function always returns a subject, and a modifier always returns a function, regardless of how these objects were defined.</p>
-<h2 id="mixing-roles">Mixing roles</h2>
+<h2 id="mixing-roles"><a class="header" href="#mixing-roles">Mixing roles</a></h2>
<p>BQN's value types align closely with its syntactic roles: functions, 1-modifiers, and 2-modifiers are all types (<em>operation</em> types) as well as roles, while the other types (<em>data</em> types) are split into numbers, characters, and arrays. This is no accident, and usually values will be used in roles that correspond to their underlying type. However, the ability to use a role that doesn't match the type is also useful.</p>
<p>Any type can be passed as an argument to a function, or as an operand, by treating it as a subject. This means that BQN fully supports Lisp-style <a href="functional.html">functional programming</a>, where functions can be used as first-class entities.</p>
<p>It can also be useful to treat a value of a data type as a function, in which case it applies as a constant function. This rule is useful with most built-in modifiers. For example, <code><span class='Function'>F</span><span class='Modifier2'>⎉</span><span class='Number'>1</span></code> uses a constant for the rank even though in general a function can be given, and if <code><span class='Value'>a</span></code> is an array then <code><span class='Value'>a</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Value'>b</span><span class='Modifier2'>⊸</span><span class='Function'>/</span><span class='Paren'>)</span></code> inserts the values in <code><span class='Value'>a</span></code> into the positions selected by <code><span class='Value'>b</span></code>, ignoring the old values rather than applying a function to them.</p>
diff --git a/docs/doc/control.html b/docs/doc/control.html
index ce33ddb6..10a9fc7a 100644
--- a/docs/doc/control.html
+++ b/docs/doc/control.html
@@ -4,7 +4,7 @@
<title>Control flow in BQN</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="control-flow-in-bqn">Control flow in BQN</h1>
+<h1 id="control-flow-in-bqn"><a class="header" href="#control-flow-in-bqn">Control flow in BQN</a></h1>
<p>BQN does not have ALGOL-style control structures. Instead, functional techniques can be used to control when code is evaluated. This page describes how BQN functionality can be used to emulate something more familiar to an imperative programmer.</p>
<p>Control structures here are always functions that act on lists of functions, although alternatives might be presented. This is because stranded functions can be formatted in a very similar way to blocks in curly-brace languages. However, there are many ways to write control flow, including simple operators and a mix of operators and more control-structure-like code. Implementing a control structure rarely takes much code with any method, so there are usually several simple ways to implement a given flow or a variation of it.</p>
<p>The surfeit of ways to write control structures could be a bit of an issue for reading BQN. My hope is that the community can eventually settle on a smaller set of standard forms to recommend so that you won't have to recognize all the variants given here. On the other hand, the cost of using specialized control structures is lower in a large project without too many contributors. In this case BQN's flexibility allows developers to adapt to the project's particular demands (for example, some programs use switch/case statements heavily but most do not).</p>
@@ -21,7 +21,7 @@
<span class='Function'>Switch</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>c</span><span class='Gets'>←</span><span class='Function'>⊑</span><span class='Value'>𝕩</span> <span class='Separator'>⋄</span> <span class='Value'>m</span><span class='Ligature'>‿</span><span class='Value'>a</span><span class='Gets'>←</span><span class='Function'>&lt;</span><span class='Modifier'>˘</span><span class='Function'>⍉</span><span class='Modifier2'>∘</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Function'>⥊</span><span class='Number'>1</span><span class='Function'>↓</span><span class='Value'>𝕩</span> <span class='Separator'>⋄</span> <span class='Paren'>(</span><span class='Function'>⊑</span><span class='Value'>a</span><span class='Function'>⊐C</span><span class='Paren'>)</span><span class='Modifier2'>◶</span><span class='Value'>m</span><span class='String'>@</span><span class='Brace'>}</span>
<span class='Function'>Test</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>fn</span><span class='Gets'>←</span><span class='Brace'>{</span><span class='Function'>C</span><span class='Ligature'>‿</span><span class='Function'>A𝕊</span><span class='Value'>e:</span><span class='Function'>C</span><span class='Modifier2'>◶</span><span class='Function'>A</span><span class='Ligature'>‿</span><span class='Function'>E</span><span class='Brace'>}</span><span class='Modifier'>´</span><span class='Value'>𝕩</span><span class='Separator'>⋄</span><span class='Function'>Fn</span><span class='String'>@</span><span class='Brace'>}</span>
</pre>
-<h2 id="blocks-and-functions">Blocks and functions</h2>
+<h2 id="blocks-and-functions"><a class="header" href="#blocks-and-functions">Blocks and functions</a></h2>
<p>Control structures are generally defined to work with blocks of code, which they might skip, or execute one or more times. This might sound like a BQN immediate block, which also consists of a sequence of code to execute, but immediate blocks are always executed as soon as they are encountered and can't be manipulated the way that blocks in imperative languages can. They're intended to be used with <a href="lexical.html">lexical scoping</a> as a tool for encapsulation. Instead, the main tool we will use to get control structures is the block function.</p>
<p>Using functions as blocks is a little outside their intended purpose, and the fact that they have to be passed an argument and are expected to use it will be a minor annoyance. The following conventions signal a function that ignores its argument and is called purely for the side effects:</p>
<ul>
@@ -33,7 +33,7 @@
<span class='Function'>Fn</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>𝕤</span><span class='Separator'>⋄</span> <span class='Value'>m</span><span class='Function'>+</span><span class='Gets'>↩</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Value'>n</span><span class='Function'>×</span><span class='Gets'>↩</span><span class='Number'>2</span><span class='Brace'>}</span><span class='Separator'>,</span> <span class='Function'>Fn</span> <span class='String'>@</span>
</pre>
<p>Control structures are called &quot;statements&quot; below to match common usage, but they are actually expressions, and return a value that might be used later.</p>
-<h2 id="if">If</h2>
+<h2 id="if"><a class="header" href="#if">If</a></h2>
<p>The if statement conditionally performs some action. It is similar to the Repeat (<code><span class='Modifier2'>⍟</span></code>) modifier with a right operand returning a boolean: <code><span class='Function'>Fn</span><span class='Modifier2'>⍟</span><span class='Function'>Cond</span> <span class='Value'>𝕩</span></code> gives <code><span class='Function'>Fn</span> <span class='Value'>𝕩</span></code> if <code><span class='Function'>Cond</span> <span class='Value'>𝕩</span></code> is <code><span class='Number'>1</span></code>, and returns <code><span class='Value'>𝕩</span></code> without calling <code><span class='Function'>Fn</span></code> if <code><span class='Function'>Cond</span> <span class='Value'>𝕩</span></code> is <code><span class='Number'>0</span></code>. Here is how we might make it behave like a control structure.</p>
<pre><span class='Brace'>{</span><span class='Value'>𝕤</span><span class='Separator'>⋄</span><span class='Value'>a</span><span class='Function'>+</span><span class='Gets'>↩</span><span class='Number'>10</span><span class='Brace'>}</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>&lt;</span><span class='Number'>10</span><span class='Paren'>)</span> <span class='String'>@</span>
</pre>
@@ -54,10 +54,10 @@
<span class='Brace'>}</span>
</pre>
<p>In all cases, the result of an if statement is the result of the action if it's performed, and otherwise it's whatever argument was passed to the statement, which is <code><span class='String'>@</span></code> in most examples above.</p>
-<h2 id="repeat">Repeat</h2>
+<h2 id="repeat"><a class="header" href="#repeat">Repeat</a></h2>
<p>There's no reason the condition in an if statement from the previous section has to be boolean: it could be any natural number, causing the action to be repeated that many times. If the action is never performed, the result is the statement's argument, and otherwise it's the result of the last time the action was performed.</p>
<p>Another option is to use a <a href="#for">for-each</a> statement with an argument of <code><span class='Function'>↕</span><span class='Value'>n</span></code>: in this case the result is the list of each action's result.</p>
-<h2 id="if-else">If-Else</h2>
+<h2 id="if-else"><a class="header" href="#if-else">If-Else</a></h2>
<p>Despite the name, an if-else statement is most closely related to a <a href="#switch-case">switch-case</a> statement: in fact, it's just a special case where the two cases are true (<code><span class='Number'>1</span></code>) and false (<code><span class='Number'>0</span></code>). As a result, we can implement it either with Choose (<code><span class='Modifier2'>◶</span></code>) or with <a href="block.html#case-headers">case headers</a> of <code><span class='Number'>1</span></code> and <code><span class='Number'>0</span></code>.</p>
<p>When using Choose, note that the natural ordering places the false case before the true one to match list index ordering. To get the typical if-else order, the condition should be negated or the statements reversed. Here's a function to get an if-else statement by swapping the conditions, and two ways its application might be written.</p>
<pre><span class='Function'>IfElse</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>cond</span><span class='Ligature'>‿</span><span class='Function'>True</span><span class='Ligature'>‿</span><span class='Function'>False</span><span class='Value'>:</span> <span class='Value'>cond</span><span class='Modifier2'>◶</span><span class='Function'>False</span><span class='Ligature'>‿</span><span class='Function'>True</span> <span class='String'>@</span><span class='Brace'>}</span>
@@ -81,7 +81,7 @@
<span class='Brace'>}</span>
</pre>
<p>The result of an if-else statement is just the result of whichever branch was used; chained if-else and switch-case statements will work the same way.</p>
-<h3 id="chained-if-else">Chained If-Else</h3>
+<h3 id="chained-if-else"><a class="header" href="#chained-if-else">Chained If-Else</a></h3>
<p>One pattern in imperative languages is to check one condition and apply an action if it succeeds, but check a different condition if it fails, in sequence until some condition succeeds or every one has been checked. Languages might make this pattern easier by making if-else right associative, so that the programmer can write an <code><span class='Value'>if</span></code> statement followed by a sequence of <code><span class='Value'>else</span> <span class='Value'>if</span></code> &quot;statements&quot;, or might just provide a unified <code><span class='Value'>elif</span></code> keyword that works similarly (while this <em>is</em> a common pattern, I suspect it's used more often than it's really wanted because of this syntactic support).</p>
<p>In BQN it's possible to nest <code><span class='Function'>IfElse</span></code> expressions, but it's also possible to write a control structure that chains them all at one level. For this statement the input will be a sequence of <code><span class='Bracket'>⟨</span><span class='Function'>Test</span><span class='Separator'>,</span><span class='Function'>Action</span><span class='Bracket'>⟩</span></code> pairs, followed by a final action to perform if no test succeeds. The first test is always performed; other tests should be wrapped in blocks because otherwise they'll be executed even if an earlier test succeeded.</p>
<pre><span class='Function'>Test</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>fn</span><span class='Gets'>←</span><span class='Brace'>{</span><span class='Function'>Cond</span><span class='Ligature'>‿</span><span class='Function'>Act</span> <span class='Function'>𝕊</span> <span class='Value'>else:</span> <span class='Function'>Cond</span><span class='Modifier2'>◶</span><span class='Function'>Else</span><span class='Ligature'>‿</span><span class='Function'>Act</span><span class='Brace'>}</span><span class='Modifier'>´</span><span class='Value'>𝕩</span> <span class='Separator'>⋄</span> <span class='Function'>Fn</span><span class='String'>@</span><span class='Brace'>}</span>
@@ -92,7 +92,7 @@
<span class='Brace'>{</span><span class='Value'>𝕤</span><span class='Separator'>⋄</span><span class='Value'>a</span><span class='Function'>-</span><span class='Gets'>↩</span><span class='Number'>2</span><span class='Brace'>}</span>
<span class='Bracket'>⟩</span>
</pre>
-<h2 id="switch-case">Switch-Case</h2>
+<h2 id="switch-case"><a class="header" href="#switch-case">Switch-Case</a></h2>
<p>The simplest way to write a switch-case statement is with <a href="block.html#case-headers">case headers</a> in a monadic function. A function with case headers tests its input against the headers in order until one matches, then executes the code there. To make it into a control structure, we just want to call the function on a given value.</p>
<pre><span class='Function'>Match</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Function'>𝕏</span><span class='Value'>𝕨</span><span class='Brace'>}</span><span class='Modifier'>´</span>
@@ -126,7 +126,7 @@
<span class='Bracket'>⟩</span>
</pre>
<p>Finally, the most general form of a switch statement is a <a href="#chained-if-else">chained if-else</a>!</p>
-<h2 id="loop-forever">Loop forever</h2>
+<h2 id="loop-forever"><a class="header" href="#loop-forever">Loop forever</a></h2>
<p>It's not a particularly common pattern, but this is a good simple case to warm up for the while loop. BQN primitives usually take a predictable amount of time, and none of them will run forever! Recursion is the tool to use here. If there's a particular function that we'd like to run infinity times, we can just add <code><span class='Value'>𝕨</span><span class='Function'>𝕊</span><span class='Value'>𝕩</span></code> to the end:</p>
<pre><span class='Brace'>{</span>
<span class='Comment'># Stuff to do forever
@@ -148,7 +148,7 @@
<span class='Comment'># Stuff to do forever
</span><span class='Brace'>}</span>
</pre>
-<h2 id="while">While</h2>
+<h2 id="while"><a class="header" href="#while">While</a></h2>
<p>The same modifier technique used in <code><span class='Function'>Forever</span></code> works for a while loop as well. Because there are now two components—the condition and action—we'll use a 2-modifier instead of a 1-modifier.</p>
<pre><span class='Function'>While</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>𝕨</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='Value'>𝕩</span><span class='Brace'>}</span><span class='Value'>𝕩</span><span class='String'>@</span><span class='Brace'>}</span><span class='Modifier'>´</span>
@@ -160,12 +160,12 @@
<pre><span class='Function'>DoWhile</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>𝕨</span><span class='Brace'>{</span><span class='Function'>𝕊</span><span class='Modifier2'>⍟</span><span class='Function'>𝔽𝔾</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Value'>𝕩</span><span class='String'>@</span><span class='Brace'>}</span><span class='Modifier'>´</span>
</pre>
<p>Because the condition is run repeatedly, it has to be a function, and can't be a plain expression as in an if conditional.</p>
-<h3 id="low-stack-version">Low-stack version</h3>
+<h3 id="low-stack-version"><a class="header" href="#low-stack-version">Low-stack version</a></h3>
<p>The above version of <code><span class='Function'>While</span></code> will fail in a fairly small number of iterations, because it consumes a new stack frame with each iteration. While tail call optimization could solve this, detecting the tail call in a compound function like <code><span class='Function'>𝕊</span><span class='Modifier2'>∘</span><span class='Function'>𝔾</span><span class='Modifier2'>⍟</span><span class='Function'>𝔽</span></code> is technically difficult and would introduce overhead into a BQN interpreter. However, there is a method to make the number of required stack frames logarithmic in the number of iterations instead of linear:</p>
<pre><span class='Function'>While</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>𝕩</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><span class='Value'>𝕨</span><span class='String'>@</span><span class='Brace'>}</span><span class='Modifier'>´</span>
</pre>
<p>The innovation is to use <code><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> instead of the equivalent <code><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='Value'>𝕩</span><span class='Brace'>}</span></code> or <code><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='Value'>𝕩</span><span class='Brace'>}</span></code> (these are the same, as <code><span class='Function'>𝕊</span></code> in a modifier is defined as <code><span class='Function'>𝔽</span><span class='Modifier2'>_𝕣_</span><span class='Function'>𝔾</span></code>). Here <code><span class='Function'>𝔽</span></code> performs one iteration and <code><span class='Function'>𝔾</span></code> tests whether to continue. The simplest approach is to perform one iteration and recurse with the same two functions. The modified approach replaces <code><span class='Function'>𝔽</span></code> with <code><span class='Function'>𝔽</span><span class='Modifier2'>⍟</span><span class='Function'>𝔾</span><span class='Modifier2'>∘</span><span class='Function'>𝔽</span></code>, that is, it doubles it while making sure the condition is still checked each iteration. The doublings compound so that recursion level <code><span class='Value'>n</span></code> performs <code><span class='Function'>𝔽</span></code> up to <code><span class='Number'>2</span><span class='Function'>⋆</span><span class='Value'>n</span></code> times while using on the order of <code><span class='Value'>n</span></code> additional stack frames. Only a hundred or two stack frames are needed to give a practically unlimited number of iterations.</p>
-<h2 id="for">For</h2>
+<h2 id="for"><a class="header" href="#for">For</a></h2>
<p>To begin with, are you sure you don't want a for-each loop instead? In BQN that's just a function with Each (<code><span class='Modifier'>¨</span></code>), and it covers most common uses of a for loop.</p>
<pre><span class='Function'>Fn</span><span class='Modifier'>¨</span> <span class='Value'>v</span> <span class='Comment'># for (𝕩 in v)
</span><span class='Function'>Fn</span><span class='Modifier'>¨</span> <span class='Function'>↕</span><span class='Value'>n</span> <span class='Comment'># for (𝕩=0; 𝕩&lt;n; 𝕩++)
@@ -195,7 +195,7 @@
<span class='Brace'>}</span>
<span class='Brace'>}</span><span class='Bracket'>⟩</span>
</pre>
-<h3 id="break-and-continue">Break and continue</h3>
+<h3 id="break-and-continue"><a class="header" href="#break-and-continue">Break and continue</a></h3>
<p>In a <code><span class='Function'>While</span></code> or <code><span class='Function'>For</span></code> loop, <a href="block.html#returns">returns</a> can be used for either the break or the continue statement (or, for that matter, a multiline break) if available. Returning from the main body, either with <code><span class='Function'>𝕊</span><span class='Gets'>→</span></code> or a labelled return, is a functional version of a continue statement. To escape from the loop as a whole, it should be wrapped in a labelled immediate block. Returning from that block using its label breaks the loop. For example, the following loop</p>
<pre><span class='Brace'>{</span><span class='Value'>brk:</span>
<span class='Value'>sum</span> <span class='Gets'>←</span> <span class='Number'>0</span> <span class='Separator'>⋄</span> <span class='Value'>even</span> <span class='Gets'>←</span> <span class='Bracket'>⟨⟩</span>
diff --git a/docs/doc/couple.html b/docs/doc/couple.html
index 8bc54ef5..03b0bf07 100644
--- a/docs/doc/couple.html
+++ b/docs/doc/couple.html
@@ -4,7 +4,7 @@
<title>BQN: Couple and Merge</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="couple-and-merge">Couple and Merge</h1>
+<h1 id="couple-and-merge"><a class="header" href="#couple-and-merge">Couple and Merge</a></h1>
<p>Solo/Couple (<code><span class='Function'>≍</span></code>) and Merge (<code><span class='Function'>&gt;</span></code>) are functions that create a higher-rank array from lower-rank components. Each takes some number of inner arrays organized in an outer structure, and creates a single array combining all elements of those inner arrays. For example, let's couple two arrays of shape <code><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span></code>:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIHAg4oaQIDPigL81w5fijJzihpUzCuKKoiBxIOKGkCAy4oC/M+KliiJhYmNkZWYiCnAg4omNIHEgICAjIHAgY291cGxlZCB0byBxCuKJoiBwIOKJjSBx">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>p</span> <span class='Gets'>←</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>5</span><span class='Function'>×</span><span class='Modifier'>⌜</span><span class='Function'>↕</span><span class='Number'>3</span>
┌─
@@ -56,7 +56,7 @@
⟨ 2 3 5 ⟩
</pre>
<p>Merge is effectively a generalization of Solo and Couple, since Solo is <code><span class='Brace'>{</span><span class='Function'>&gt;</span><span class='Bracket'>⟨</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span><span class='Brace'>}</span></code> and Couple is <code><span class='Brace'>{</span><span class='Function'>&gt;</span><span class='Bracket'>⟨</span><span class='Value'>𝕨</span><span class='Separator'>,</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span><span class='Brace'>}</span></code>. Since <code><span class='Function'>≍</span></code> works on the &quot;list&quot; of arguments, it can only add one dimension, but <code><span class='Function'>&gt;</span></code> can take any number of dimensions as its input.</p>
-<h2 id="merge-and-array-theory">Merge and array theory</h2>
+<h2 id="merge-and-array-theory"><a class="header" href="#merge-and-array-theory">Merge and array theory</a></h2>
<p>In all cases what these functions do is more like reinterpreting existing data than creating new information. In fact, if we ignore the shape and look at the ravels of the arrays involved in a call to Merge, we find that it just <a href="join.html">joins</a> them together. Essentially, Merge is a request to ensure that the inner arrays (which, being independent elements, could be any sort of &quot;ragged&quot; array) can fit together in an array, and then to consider them to be such an array. For this reason, Merge (or a virtual analogue) is used to combine the result cells when calling a function with Rank into a single array.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4qWKID4gYQripYog4qWKwqggYQriiL4g4qWKIOKlisKoIGE=">↗️</a><pre> <span class='Function'>⥊</span> <span class='Function'>&gt;</span> <span class='Value'>a</span>
"ABrstABuvwABxyzCDrstCDuvwCDxyz"
@@ -74,7 +74,7 @@
⟨ 3 0 ⟩
</pre>
<p>Above we start with a list of three empty arrays. After merging once we get a shape <code><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>0</span></code> array, sure, but what happens next? The shape added by another merge is the shared shape of that array's elements—and there aren't any! If the nested list kept some type information around then we might know, but extra type information is essentially how lists pretend to be arrays. True dynamic lists simply can't represent multidimensional arrays with a <code><span class='Number'>0</span></code> in the middle of the shape. In this sense, arrays are a richer model than nested lists.</p>
-<h2 id="coupling-units">Coupling units</h2>
+<h2 id="coupling-units"><a class="header" href="#coupling-units">Coupling units</a></h2>
<p>A note on the topic of Solo and Couple applied to units. As always, one axis will be added, so that the result is a list (strangely, J's <a href="https://code.jsoftware.com/wiki/Vocabulary/commaco#dyadic">laminate</a> differs from Couple in this one case, as it will add an axis to get a shape <code><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span></code> result). For Solo, this is interchangeable with <a href="reshape.html">Deshape</a> (<code><span class='Function'>⥊</span></code>), and either primitive might be chosen for stylistic reasons. For Couple, it is equivalent to <a href="join.html">Join-to</a> (<code><span class='Function'>∾</span></code>), but this is an irregular form of Join-to because it is the only case where Join-to adds an axis to both arguments instead of just one. Couple should be preferred in this case.</p>
<p>The pair function, which creates a list from its arguments, can be written <code><span class='Function'>Pair</span> <span class='Gets'>←</span> <span class='Function'>≍</span><span class='Modifier2'>○</span><span class='Function'>&lt;</span></code>, while <code><span class='Function'>≍</span></code> in either valence is <code><span class='Function'>&gt;</span><span class='Modifier2'>∘</span><span class='Function'>Pair</span></code>. As an interesting consequence, <code><span class='Function'>≍</span> <span class='Gets'>←→</span> <span class='Function'>&gt;</span><span class='Modifier2'>∘</span><span class='Function'>≍</span><span class='Modifier2'>○</span><span class='Function'>&lt;</span></code>, and the same relationship holds for <code><span class='Function'>Pair</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oMiwz4p+pIOKJjeKXizwgImFiYyIgICMgUGFpciB0d28gdmFsdWVzCuKJjeKXizwgImFiYyIgICAgICAgICMgUGFpciBvbmUoPykgdmFsdWU=">↗️</a><pre> <span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Bracket'>⟩</span> <span class='Function'>≍</span><span class='Modifier2'>○</span><span class='Function'>&lt;</span> <span class='String'>&quot;abc&quot;</span> <span class='Comment'># Pair two values
@@ -82,6 +82,6 @@
<span class='Function'>≍</span><span class='Modifier2'>○</span><span class='Function'>&lt;</span> <span class='String'>&quot;abc&quot;</span> <span class='Comment'># Pair one(?) value
</span>⟨ "abc" ⟩
</pre>
-<h2 id="definitions">Definitions</h2>
+<h2 id="definitions"><a class="header" href="#definitions">Definitions</a></h2>
<p>As discussed above, <code><span class='Function'>≍</span></code> is equivalent to <code><span class='Function'>&gt;</span><span class='Brace'>{</span><span class='Bracket'>⟨</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span><span class='Value'>;</span><span class='Bracket'>⟨</span><span class='Value'>𝕨</span><span class='Separator'>,</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span><span class='Brace'>}</span></code>. To complete the picture we should describe Merge fully. Merge is defined on an array argument <code><span class='Value'>𝕩</span></code> such that there's some shape <code><span class='Value'>s</span></code> satisfying <code><span class='Function'>∧</span><span class='Modifier'>´</span><span class='Function'>⥊</span><span class='Paren'>(</span><span class='Value'>s</span><span class='Function'>≡≢</span><span class='Paren'>)</span><span class='Modifier'>¨</span><span class='Value'>𝕩</span></code>. If <code><span class='Value'>𝕩</span></code> is empty then any shape satisfies this expression; <code><span class='Value'>s</span></code> should be chosen based on known type information for <code><span class='Value'>𝕩</span></code> or otherwise assumed to be <code><span class='Bracket'>⟨⟩</span></code>. If <code><span class='Value'>s</span></code> is empty then <code><span class='Value'>𝕩</span></code> is allowed to contain atoms as well as unit arrays, and these will be implicitly promoted to arrays by the <code><span class='Function'>⊑</span></code> indexing used later. We construct the result by combining the outer and inner axes of the argument with Table; since the outer axes come first they must correspond to the left argument and the inner axes must correspond to the right argument. <code><span class='Value'>𝕩</span></code> is a natural choice of left argument, and because no concrete array can be used, the right argument will be <code><span class='Function'>↕</span><span class='Value'>s</span></code>, the array of indices into any element of <code><span class='Value'>𝕩</span></code>. To get the appropriate element corresponding to a particular choice of index and element of <code><span class='Value'>𝕩</span></code> we should select using that index. The result of Merge is <code><span class='Value'>𝕩</span><span class='Function'>⊑</span><span class='Modifier'>˜⌜</span><span class='Function'>↕</span><span class='Value'>s</span></code>.</p>
<p>Given this definition we can also describe Rank (<code><span class='Modifier2'>⎉</span></code>) in terms of Each (<code><span class='Modifier'>¨</span></code>) and the simpler monadic function Enclose-Rank <code><span class='Function'>&lt;</span><span class='Modifier2'>⎉</span><span class='Value'>k</span></code>. We assume effective ranks <code><span class='Value'>j</span></code> for <code><span class='Value'>𝕨</span></code> (if present) and <code><span class='Value'>k</span></code> for <code><span class='Value'>𝕩</span></code> have been computed. Then the correspondence is <code><span class='Value'>𝕨</span><span class='Function'>F</span><span class='Modifier2'>⎉</span><span class='Value'>k𝕩</span> <span class='Gets'>←→</span> <span class='Function'>&gt;</span><span class='Paren'>(</span><span class='Function'>&lt;</span><span class='Modifier2'>⎉</span><span class='Value'>j𝕨</span><span class='Paren'>)</span><span class='Function'>F</span><span class='Modifier'>¨</span><span class='Paren'>(</span><span class='Function'>&lt;</span><span class='Modifier2'>⎉</span><span class='Value'>k𝕩</span><span class='Paren'>)</span></code>.</p>
diff --git a/docs/doc/depth.html b/docs/doc/depth.html
index c2501726..6d043d8d 100644
--- a/docs/doc/depth.html
+++ b/docs/doc/depth.html
@@ -4,7 +4,7 @@
<title>BQN: Depth</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="depth">Depth</h1>
+<h1 id="depth"><a class="header" href="#depth">Depth</a></h1>
<svg viewBox='-278.4 -45.6 556.8 193.8'>
<g font-family='BQN,monospace' font-size='16px' text-anchor='middle' fill='currentColor' stroke-width='0' stroke='currentColor' stroke-linecap='round'>
<rect class='code' stroke-width='1.5' rx='12' x='-196.8' y='-30.4' width='393.6' height='163.4'/>
@@ -65,7 +65,7 @@
</svg>
<p>The depth of an array is the greatest level of array nesting it attains, or, put another way, the greatest number of times you can pick an element starting from the original array before reaching an atom. The monadic function Depth (<code><span class='Function'>≡</span></code>) returns the depth of its argument, while the 2-modifier Depth (<code><span class='Modifier2'>⚇</span></code>) can control the way its left operand is applied based on the depth of its arguments. Several primitive functions also use the depth of the left argument to decide whether it applies to a single axis of the right argument or to several axes.</p>
-<h2 id="the-depth-function">The Depth function</h2>
+<h2 id="the-depth-function"><a class="header" href="#the-depth-function">The Depth function</a></h2>
<p>To find the depth of an array, use Depth (<code><span class='Function'>≡</span></code>). For example, the depth of a list of numbers or characters is 1:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4omhIDLigL8z4oC/NAriiaEgImEgc3RyaW5nIGlzIGEgbGlzdCBvZiBjaGFyYWN0ZXJzIg==">↗️</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'>4</span>
1
@@ -105,7 +105,7 @@
<span class='Function'>≡</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Function'>⥊</span><span class='Number'>0</span>
1
</pre>
-<h2 id="testing-depth-for-multiple-axis-primitives">Testing depth for multiple-axis primitives</h2>
+<h2 id="testing-depth-for-multiple-axis-primitives"><a class="header" href="#testing-depth-for-multiple-axis-primitives">Testing depth for multiple-axis primitives</a></h2>
<p>Several primitive functions use the left argument to manipulate the right argument along one or more axes, using <a href="leading.html#multiple-axes">the leading axis convention</a>.</p>
<table>
<thead>
@@ -151,7 +151,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MuKAvzHigL80IDzCqOKKuOKKjyDihpUz4oC/NOKAvzXigL8y">↗️</a><pre> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>4</span> <span class='Function'>&lt;</span><span class='Modifier'>¨</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span> <span class='Function'>↕</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>2</span>
⟨ ⟨ 2 1 4 0 ⟩ ⟨ 2 1 4 1 ⟩ ⟩
</pre>
-<h2 id="the-depth-modifier">The Depth modifier</h2>
+<h2 id="the-depth-modifier"><a class="header" href="#the-depth-modifier">The Depth modifier</a></h2>
<p>The Depth 2-modifier (<code><span class='Modifier2'>⚇</span></code>) is a generalization of <a href="map.html">Each</a> that allows diving deeper into an array. To illustrate it we'll use a shape <code><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span></code> array of lists of lists.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIG4g4oaQIDzijokx4o2fMiA04oC/M+KAvzLigL8y4qWK4oaVNDgK4omhIG4=">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>n</span> <span class='Gets'>←</span> <span class='Function'>&lt;</span><span class='Modifier2'>⎉</span><span class='Number'>1</span><span class='Modifier2'>⍟</span><span class='Number'>2</span> <span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Function'>⥊↕</span><span class='Number'>48</span>
┌─
diff --git a/docs/doc/embed.html b/docs/doc/embed.html
index e0f48dc2..bdd03679 100644
--- a/docs/doc/embed.html
+++ b/docs/doc/embed.html
@@ -4,10 +4,10 @@
<title>Using embedded BQN</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="using-embedded-bqn">Using embedded BQN</h1>
+<h1 id="using-embedded-bqn"><a class="header" href="#using-embedded-bqn">Using embedded BQN</a></h1>
<p>The Javascript implementation of BQN, <a href="https://github.com/mlochbaum/BQN/blob/master/doc/../docs/bqn.js">docs/bqn.js</a>, can be <a href="https://mlochbaum.github.io/BQN/try.html">used</a> as a standalone interpreter, but it can also be called from JS, which in combination with BQN's first-class functions allows the two language to interoperate well. Similar functionality will most likely be brought to other host languages in the future. Languages that (like JS) allow functions and arrays to be tagged with extra properties can host a full BQN implementation with good interoperability. Other languages would either require functions and arrays to be stored in specialized data structures, making interoperability a little harder, or would miss out on some inferred properties like function inverses and array fills.</p>
<p>There is only one mechanism to interface between the host language and BQN: the function <code><span class='Value'>bqn</span></code> evaluates a string containing a BQN program and returns the result. Doesn't sound like much, especially considering these programs can't share any state such as global variables (BQN doesn't have those). But taking first-class functions and closures into account, it's all you could ever need!</p>
-<h2 id="passing-closures">Passing closures</h2>
+<h2 id="passing-closures"><a class="header" href="#passing-closures">Passing closures</a></h2>
<p>Probably you can figure out the easy things like calling <code><span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>&quot;×´1+↕6&quot;</span><span class='Paren'>)</span></code> to compute six factorial. But how do you get JS and BQN to <em>talk</em> to each other, for example to compute the factorial of a number <code><span class='Value'>n</span></code>? Constructing a source string with <code><span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>&quot;×´1+↕&quot;</span><span class='Function'>+</span><span class='Value'>n</span><span class='Paren'>)</span></code> isn't the best way—in fact I would recommend you never use this strategy.</p>
<p>Instead, return a function from BQN and call it: <code><span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>&quot;{×´1+↕𝕩}&quot;</span><span class='Paren'>)(</span><span class='Value'>n</span><span class='Paren'>)</span></code>. This strategy also has the advantage that you can store the function, so that it will only be compiled once. Define <code><span class='Value'>let</span> <span class='Value'>fact</span> <span class='Function'>=</span> <span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>&quot;{×´1+↕𝕩}&quot;</span><span class='Paren'>)</span><span class='Value'>;</span></code> at the top of your program and use it as a function elsewhere.</p>
<p>BQN can also call JS functions, to use functionality that isn't native to BQN or interact with a program written in JS. For example, <code><span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>&quot;{𝕏'a'+↕26}&quot;</span><span class='Paren'>)(</span><span class='Value'>alert</span><span class='Paren'>)</span></code> calls the argument <code><span class='Value'>alert</span></code> from within BQN. The displayed output isn't quite right here, because a BQN string is stored as a JS array, not a string. See the next section for more information.</p>
@@ -32,12 +32,12 @@
</pre>
<p>When defining closures for their side effects like this, make sure they are actually functions! For example, since <code><span class='Value'>flip</span></code> ignores its argument (you can call it with <code><span class='Value'>flip</span><span class='Paren'>()</span></code>, because a right argument of <code><span class='Value'>undefined</span></code> isn't valid but will just be ignored), it needs an extra <code><span class='Value'>𝕤</span></code> in the definition to be a function instead of an immediate block.</p>
<p>You can also use an array to pass multiple functions or other values from JS into BQN all at once. However, a JS array can't be used directly in BQN because its shape isn't known. The function <code><span class='Value'>list</span><span class='Paren'>()</span></code> converts a JS array into a BQN list by using its length for the shape; the next section has a few more details.</p>
-<h2 id="js-encodings">JS encodings</h2>
+<h2 id="js-encodings"><a class="header" href="#js-encodings">JS encodings</a></h2>
<p>In the programs above we've used numbers and functions of one argument, which mean the same thing in BQN and JS. This isn't the case for all types: although every BQN value is stored as some JS value, the way it's represented may not be obvious and there are many JS values that don't represent any BQN value and could cause errors. BQN operations don't verify that their inputs are valid BQN values (this would have a large performance cost), so it's up to the JS programmer to make sure that values passed in are valid. To do this, you need to know the encodings for each of the seven BQN <a href="types.html">types</a> you're going to use.</p>
<p>The two atomic data values are simple: numbers are just JS numbers, and characters are strings containing a single code point. Arrays <em>are</em> JS arrays, but with some extra information. Since JS arrays are 1-dimensional, a BQN array <code><span class='Value'>a</span></code> is stored as the element list <code><span class='Function'>⥊</span><span class='Value'>a</span></code>. Its shape <code><span class='Function'>≢</span><span class='Value'>a</span></code>, a list of numbers, is <code><span class='Value'>a.sh</span></code> in JS (the shape isn't necessarily a BQN array so it doesn't have to have a <code><span class='Value'>sh</span></code> property). Optionally, its <a href="fill.html">fill element</a> is <code><span class='Value'>a.fill</span></code>. Note that a BQN string is not a JS string, but instead an array of BQN characters, or JS strings. To convert it to a JS string you can use <code><span class='Value'>str.join</span><span class='Paren'>(</span><span class='String'>&quot;&quot;</span><span class='Paren'>)</span></code>.</p>
<p>There are two utilities for converting from JS to BQN data: <code><span class='Value'>list</span><span class='Paren'>(</span><span class='Value'>[…]</span><span class='Paren'>)</span></code> converts a JS array to a BQN list, and <code><span class='Value'>str</span><span class='Paren'>(</span><span class='String'>&quot;JS string&quot;</span><span class='Paren'>)</span></code> converts a string.</p>
<p>Operations are all stored as JS functions, with one or two arguments for the inputs. The type is determined by the <code><span class='Value'>.m</span></code> property, which is <code><span class='Number'>1</span></code> for a 1-modifier and <code><span class='Number'>2</span></code> for a 2-modifier, and undefined or falsy for a function. Functions might be called with one or two arguments. In either case, <code><span class='Value'>𝕩</span></code> is the first argument; <code><span class='Value'>𝕨</span></code>, if present, is the second. Note that <code><span class='Function'>F</span><span class='Paren'>(</span><span class='Value'>x</span><span class='Separator'>,</span><span class='Value'>w</span><span class='Paren'>)</span></code> in JS corresponds to <code><span class='Value'>w</span> <span class='Function'>F</span> <span class='Value'>x</span></code> in BQN, reversing the visual ordering of the arguments! For modifiers there's no such reversal, as <code><span class='Value'>𝕗</span></code> is always the first argument, and for 2-modifiers <code><span class='Value'>𝕘</span></code> is the second argument. As in BQN, a modifier may or may not return a function.</p>
<p>Operations may have some extra properties set that aren't terribly important for the JS programmer: for each primitive <code><span class='Value'>p</span></code>, <code><span class='Value'>p.glyph</span></code> gives its glyph, and for a compound operation <code><span class='Value'>o</span></code> such as a train, or a modifier with bound operands, <code><span class='Value'>o.repr</span><span class='Paren'>()</span></code> decomposes it into its parts. It wouldn't make sense to define either of these properties for a function created in JS.</p>
-<h2 id="other-functionality">Other functionality</h2>
+<h2 id="other-functionality"><a class="header" href="#other-functionality">Other functionality</a></h2>
<p>The BQN script also contains the function <code><span class='Value'>fmt</span></code>, which takes a BQN value for its argument and returns a string displaying it.</p>
<p>The expression diagram builder used for the REPL's &quot;Explain&quot; button isn't included in the main BQN script: it's kept in <a href="https://github.com/mlochbaum/BQN/blob/master/doc/../docs/repl.js">docs/repl.js</a> instead. It's a little tricky to use as it takes both the source string and the bytecode obtained from compiling the source: see the surrounding Javascript code for an example. The result is the source code for an svg, as a BQN string.</p>
diff --git a/docs/doc/enclose.html b/docs/doc/enclose.html
index 2be9bddb..aac48d68 100644
--- a/docs/doc/enclose.html
+++ b/docs/doc/enclose.html
@@ -4,7 +4,7 @@
<title>BQN: Enclose</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="enclose">Enclose</h1>
+<h1 id="enclose"><a class="header" href="#enclose">Enclose</a></h1>
<p>The function enclose creates a unit array whose only element is <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=PCAieHl6Ig==">↗️</a><pre> <span class='Function'>&lt;</span> <span class='String'>&quot;xyz&quot;</span>
┌·
@@ -13,7 +13,7 @@
</pre>
<p>If you understand the concept of a unit array, then that definition almost certainly made sense to you. Therefore the remainder of this document will explain what a unit array is, what it isn't, and why you would use it.</p>
<p>If you're familiar with the Enclose or Box function from APL or J (but particularly APL), then it's possible you understand the concept of a unit array wrongly, or at least, not in the same way BQN uses it. A difference from APL is that <code><span class='Function'>&lt;</span><span class='Value'>𝕩</span></code> is never the same as <code><span class='Value'>𝕩</span></code>. I recommend reading about <a href="based.html">based array theory</a> if you haven't already.</p>
-<h2 id="whats-a-unit">What's a unit?</h2>
+<h2 id="whats-a-unit"><a class="header" href="#whats-a-unit">What's a unit?</a></h2>
<p>A <strong>unit array</strong> is an array with no axes: that is, it has rank 0 and its shape is the empty list. The array itself isn't empty though. The number of elements is the product of the shape, which is 1.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ICAg4omiIDwiYW55dGhpbmciICAgIyBlbXB0eSBzaGFwZQrDl8K0IOKJoiA8ImFueXRoaW5nIiAgICMgYW5kIG9uZSBlbGVtZW50">↗️</a><pre> <span class='Function'>≢</span> <span class='Function'>&lt;</span><span class='String'>&quot;anything&quot;</span> <span class='Comment'># empty shape
</span>⟨⟩
@@ -45,9 +45,9 @@ ERROR
</pre>
<p>The function <code><span class='Function'>+</span><span class='Modifier'>´˘</span></code> tries to mix together the result elements into one big array, causing an error because they have different lengths, but <code><span class='Function'>+</span><span class='Modifier'>˝˘</span></code> keeps them as elements.</p>
<p>One strained example probably isn't all that compelling. And it doesn't explain why you'd use Enclose, which doesn't remove an axis from an existing array but creates a whole new unit array. So…</p>
-<h2 id="why-create-a-unit">Why create a unit?</h2>
+<h2 id="why-create-a-unit"><a class="header" href="#why-create-a-unit">Why create a unit?</a></h2>
<p>Why indeed?</p>
-<h3 id="table-of-combinations">Table of combinations</h3>
+<h3 id="table-of-combinations"><a class="header" href="#table-of-combinations">Table of combinations</a></h3>
<p>Let's take a look at the following program, which uses <a href="map.html#table">Table</a> (<code><span class='Modifier'>⌜</span></code>) to create an array of combinations—every possibility from three sets of choices. It uses Enclose not once but twice.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KDzin6jin6kpIDziirjiiL7ijJzCtCDin6giIuKAvyJhbnRpIiwgInJlZCLigL8iYmx1ZSLigL8iZ3JlZW4iLCAidXAi4oC/ImRvd24i4p+p">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>&lt;</span><span class='Bracket'>⟨⟩</span><span class='Paren'>)</span> <span class='Function'>&lt;</span><span class='Modifier2'>⊸</span><span class='Function'>∾</span><span class='Modifier'>⌜´</span> <span class='Bracket'>⟨</span><span class='String'>&quot;&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;anti&quot;</span><span class='Separator'>,</span> <span class='String'>&quot;red&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;blue&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;green&quot;</span><span class='Separator'>,</span> <span class='String'>&quot;up&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;down&quot;</span><span class='Bracket'>⟩</span>
┌─
@@ -112,7 +112,7 @@ ERROR
⟨ "green" "down" "quark" ⟩ ⟨ "green" "strange" "quark" ⟩ ⟨ "green" "bottom" "quark" ⟩
</pre>
-<h3 id="broadcasting">Broadcasting</h3>
+<h3 id="broadcasting"><a class="header" href="#broadcasting">Broadcasting</a></h3>
<p>Table isn't the only mapping function that gets along well with units. Here's an example with Each (<code><span class='Modifier'>¨</span></code>).</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=PeKAv+KJoOKAv+KJoeKAv+KJoiB78J2VjvCdlal9wqggPCAz4oC/MuKliiJhYmNkZWYi">↗️</a><pre> <span class='Function'>=</span><span class='Ligature'>‿</span><span class='Function'>≠</span><span class='Ligature'>‿</span><span class='Function'>≡</span><span class='Ligature'>‿</span><span class='Function'>≢</span> <span class='Brace'>{</span><span class='Function'>𝕎</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier'>¨</span> <span class='Function'>&lt;</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Function'>⥊</span><span class='String'>&quot;abcdef&quot;</span>
⟨ 2 3 1 ⟨ 3 2 ⟩ ⟩
@@ -125,7 +125,7 @@ ERROR
⟨ 14 ¯9 ⟩ ⟨ 15 ¯6 ⟩
</pre>
-<h2 id="coda">Coda</h2>
+<h2 id="coda"><a class="header" href="#coda">Coda</a></h2>
<p>Perhaps you feel bludgeoned rather than convinced at this point. Unit arrays are useful, sure, but aren't they ugly? Aren't they a hack?</p>
<p>The practical answer is that I think you should use them anyway. You'll probably come to appreciate the use of Enclose and how it can help you produce working, reliable code, making you a more effective BQN programmer.</p>
<p>On the theoretical side, it's important to realize that units are just a consequence of having multidimensional arrays. Array languages come with units be default, so that &quot;adding&quot; them is not really a complication, it's a simplification. It's natural to not feel quite right around these sorts of non-things, because zero is a pretty special number—being among other things the only number of paddles you can have and still not be able to go anywhere in your canoe. In my opinion the right response is to understand why they are special but also why they fit in as part of the system, so you can be in control instead of worrying.</p>
diff --git a/docs/doc/expression.html b/docs/doc/expression.html
index 20eb896e..614052fa 100644
--- a/docs/doc/expression.html
+++ b/docs/doc/expression.html
@@ -4,10 +4,10 @@
<title>BQN: Expression syntax</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="expression-syntax">Expression syntax</h1>
+<h1 id="expression-syntax"><a class="header" href="#expression-syntax">Expression syntax</a></h1>
<p>BQN expressions are the part of <a href="syntax.html">syntax</a> that describes computations to perform. Programs are mainly made up of expressions with a little organizing material like <a href="block.html">blocks</a> and <a href="namespace.html">namespaces</a> around them. This page explains how functions, modifiers, and assignment combine with their inputs. It doesn't describe <a href="syntax.html#constant">constant</a> and <a href="arrayrepr.html#list-literals">array</a> literals, which each form a single subject for grammatical purposes.</p>
<p>The <a href="../tutorial/expression.html">first tutorial</a> also covers how to build and read BQN expressions.</p>
-<h2 id="overview">Overview</h2>
+<h2 id="overview"><a class="header" href="#overview">Overview</a></h2>
<p>BQN expressions consist of subjects, functions, and modifiers arranged in sequence, with parentheses to group parts into subexpressions. Assignment arrows <code><span class='Gets'>←</span></code> and <code><span class='Gets'>↩</span></code> can also be present and mostly behave similar to functions. Functions can be applied to subjects or grouped into trains, while modifiers can be applied to subjects or functions. The most important kinds of application are:</p>
<table>
<thead>
@@ -57,11 +57,11 @@
</table>
<p>The four roles (subject, function, two kinds of modifier) describe expressions, not values. When an expression is evaluated, the value's <a href="types.html">type</a> doesn't have to correspond to its role, and can even change from one evaluation to another. An expression's role is determined entirely by its source code, so it's fixed.</p>
<p>If you're comfortable reading <a href="https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form">BNF</a> and want to understand things in more detail than described below, you might check the <a href="../spec/grammar.html">grammar specification</a> as well.</p>
-<h2 id="syntactic-role">Syntactic role</h2>
+<h2 id="syntactic-role"><a class="header" href="#syntactic-role">Syntactic role</a></h2>
<p><em>This issue is approached from a different angle in <a href="context.html">Context free grammar</a>.</em></p>
<p>In APL, the way one part of an expression interacts with others is determined by its value. That means that to parse an expression, in general you would have to evaluate that part, get a value, check its type, and then figure out how it fits in with the rest of the expression. This is a lot of work. BQN changes things so that you can determine how to parse an expression just by looking at its source code. But because it still needs to support expressions that can evaluate to more than one possible <a href="types.html">type</a>, BQN has to introduce a new and independent concept, called <strong>syntactic role</strong>, in order to support APL-like expressions.</p>
<p>Syntactic role is a property of an expression, not its value. To describe it in terms of English grammar, you might say &quot;I like BQN&quot;, using &quot;BQN&quot; as an object, or &quot;BQN scares me&quot;, using it as a subject. BQN itself isn't a subject or object, it's a programming language. Similarly you might write <code><span class='Function'>F</span> <span class='Value'>g</span></code>, placing <code><span class='Value'>f</span></code> in a function role to apply it to <code><span class='Value'>g</span></code>, or <code><span class='Function'>G</span> <span class='Value'>f</span></code> to use <code><span class='Value'>f</span></code> as an argument. Maybe even in the same program, although it's unlikely.</p>
-<h3 id="role-spellings">Role spellings</h3>
+<h3 id="role-spellings"><a class="header" href="#role-spellings">Role spellings</a></h3>
<p>The four roles are <strong>subject</strong>, <strong>function</strong>, <strong>1-modifier</strong>, and <strong>2-modifier</strong>, as shown in the table below. Each type has an associated role (with non-operation types all corresponding to subjects), and the value of an expression will often have a matching type, but it doesn't have to.</p>
<table>
<thead>
@@ -98,7 +98,7 @@
<p>Variable names can be written in any case and with underscores added, and these changes don't affect what <a href="lexical.html">identifier</a> the name refers to. <code><span class='Value'>ab</span></code>, <code><span class='Value'>aB</span></code>, <code><span class='Function'>AB</span></code>, and <code><span class='Modifier2'>_a_B_</span></code> are all the same variable. However, the spelling—specifically the first and last characters—determine the variable's role. A lowercase first letter indicates a subject, and an uppercase first letter makes it a function. A leading underscore (regardless of the following character) indicates a 1-modifier, and both leading and trailing underscores makes a 2-modifier.</p>
<p>Besides these, character, string, and <a href="arrayrepr.html#list-literals">list literals</a> always have a subject role, and the role of a <a href="block.html">block</a> is determined by its type, which depends either on the header it has or which special variables it uses.</p>
<p>The role of a compound expression, formed by applying an operation to some inputs, depends on the operation applied. This system is discussed in the remaining sections below.</p>
-<h2 id="kinds-of-application">Kinds of application</h2>
+<h2 id="kinds-of-application"><a class="header" href="#kinds-of-application">Kinds of application</a></h2>
<p>Here is a table of the modifier and function application rules:</p>
<table>
<thead>
diff --git a/docs/doc/fill.html b/docs/doc/fill.html
index b4ac35ef..e350fa6e 100644
--- a/docs/doc/fill.html
+++ b/docs/doc/fill.html
@@ -4,10 +4,10 @@
<title>BQN: Fill elements</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="fill-elements">Fill elements</h1>
+<h1 id="fill-elements"><a class="header" href="#fill-elements">Fill elements</a></h1>
<p>A few array operations need an array element to use when no existing element applies. BQN tries to maintain a &quot;default&quot; element for every array, known as a fill element, for this purpose. If it's known, the fill element is a nested array structure where each atom is either <code><span class='Number'>0</span></code> or <code><span class='String'>' '</span></code>. If no fill is known, a function that requests it results in an error.</p>
<p>Fills are used by <a href="take.html">Take</a> (<code><span class='Function'>↑</span></code>) when a value in <code><span class='Value'>𝕨</span></code> is larger than the corresponding length in <code><span class='Value'>𝕩</span></code>, by the two <a href="shift.html">Nudge</a> functions (<code><span class='Function'>»«</span></code>) when <code><span class='Value'>𝕩</span></code> is non-empty, by <a href="couple.html">Merge</a> (<code><span class='Function'>&gt;</span></code>) when <code><span class='Value'>𝕩</span></code> is empty, and by <a href="reshape.html">Reshape</a> (<code><span class='Function'>⥊</span></code>) when <code><span class='Value'>𝕨</span></code> contains <code><span class='Function'>↑</span></code>. Except for these specific cases, the fill value an array has can't affect the program. The result of <a href="match.html">Match</a> (<code><span class='Function'>≡</span></code>) doesn't depend on fills, and any attempt to compute a fill can't cause side effects.</p>
-<h2 id="using-fills">Using fills</h2>
+<h2 id="using-fills"><a class="header" href="#using-fills">Using fills</a></h2>
<p>For the examples in this section we'll use the fact that an all-number array usually has <code><span class='Number'>0</span></code> as a fill while a string has <code><span class='String'>' '</span></code> (BQN maintains fills alongside array values rather than deriving them from arrays, so it's possible to construct arrays where this isn't true, but this probably wouldn't happen in ordinary code).</p>
<p><a href="take.html">Take</a> (<code><span class='Function'>↑</span></code>) and <a href="shift.html">Nudge</a> (<code><span class='Function'>»«</span></code>) in either direction use the fill for padding, to extend the array past its boundary. For example, <code><span class='Value'>𝕨</span><span class='Function'>↑</span><span class='Value'>𝕩</span></code> will add elements to one side when a number in <code><span class='Function'>|</span><span class='Value'>𝕨</span></code> is larger than the corresponding length in <code><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=wq83IOKGkSA04qWKMyAgICAgIyBGaWxsIHdpdGggMAoKwq83IOKGkSAicXJzdCIgICMgRmlsbCB3aXRoIHNwYWNl">↗️</a><pre> <span class='Number'>¯7</span> <span class='Function'>↑</span> <span class='Number'>4</span><span class='Function'>⥊</span><span class='Number'>3</span> <span class='Comment'># Fill with 0
@@ -38,7 +38,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqRwrsx4oaR4qWKInN0cmluZyI=">↗️</a><pre> <span class='Function'>⊑»</span><span class='Number'>1</span><span class='Function'>↑⥊</span><span class='String'>&quot;string&quot;</span>
' '
</pre>
-<h2 id="how-fills-are-computed">How fills are computed</h2>
+<h2 id="how-fills-are-computed"><a class="header" href="#how-fills-are-computed">How fills are computed</a></h2>
<p>For the exact requirements placed on fill, see <a href="../spec/inferred.html#fill-elements">the specification</a> (particularly &quot;required functions&quot;). This section loosely describes behavior in existing BQN implementations, and includes some parts that aren't required in the specification.</p>
<p>A fill element should encompass something that's necessarily true for all elements of an array. If the way an array is computed implies it's all numbers, the fill should be <code><span class='Number'>0</span></code>. If every element is a list of two numbers, then the fill should be <code><span class='Bracket'>⟨</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Bracket'>⟩</span></code>. If every element is a list but the lengths might vary, <code><span class='Bracket'>⟨⟩</span></code> is probably a reasonable fill element.</p>
<p>For <a href="arithmetic.html">arithmetic</a> primitives, the fill is found by the rules of pervasion, applying the function to both argument fills. Generally this means it consists of <code><span class='Number'>0</span></code>, but character arithmetic also allows space fills.</p>
diff --git a/docs/doc/find.html b/docs/doc/find.html
index 689d8415..85f26297 100644
--- a/docs/doc/find.html
+++ b/docs/doc/find.html
@@ -4,7 +4,7 @@
<title>BQN: Find</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="find">Find</h1>
+<h1 id="find"><a class="header" href="#find">Find</a></h1>
<p>Find (<code><span class='Function'>⍷</span></code>) searches for occurrences of an array <code><span class='Value'>𝕨</span></code> within <code><span class='Value'>𝕩</span></code>. The result contains a boolean for each possible location, which is 1 if <code><span class='Value'>𝕨</span></code> was found there and 0 if not.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Inh4IiDijbcgInh4YmR4eHhjeCI=">↗️</a><pre> <span class='String'>&quot;xx&quot;</span> <span class='Function'>⍷</span> <span class='String'>&quot;xxbdxxxcx&quot;</span>
⟨ 1 0 0 0 1 1 0 0 ⟩
@@ -43,7 +43,7 @@ ERROR
0
</pre>
<p>This pattern also works in the high-rank case discussed below, testing whether <code><span class='Value'>𝕨</span></code> is a multi-dimensional prefix starting at the lowest-index corner of <code><span class='Value'>𝕩</span></code>.</p>
-<h3 id="higher-ranks">Higher ranks</h3>
+<h3 id="higher-ranks"><a class="header" href="#higher-ranks">Higher ranks</a></h3>
<p>If <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code> are two-dimensional then Find does a two-dimensional search. The cells used are also found in <code><span class='Value'>𝕨</span><span class='Function'>≢</span><span class='Modifier2'>⊸</span><span class='Function'>↕</span><span class='Value'>𝕩</span></code>. For example, the bottom-right corner of <code><span class='Value'>𝕩</span></code> below matches <code><span class='Value'>𝕨</span></code>, so there's a 1 in the bottom-right corner of the result.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGEg4oaQIDcgKDR84ouGy5wp4oyc4peL4oaVIDkgICAjIEFycmF5IHdpdGggcGF0dGVybnMKCigw4oC/M+KAvzDiiY0w4oC/MeKAvzApIOKNtyBh">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='Number'>7</span> <span class='Paren'>(</span><span class='Number'>4</span><span class='Function'>|⋆</span><span class='Modifier'>˜</span><span class='Paren'>)</span><span class='Modifier'>⌜</span><span class='Modifier2'>○</span><span class='Function'>↕</span> <span class='Number'>9</span> <span class='Comment'># Array with patterns
</span>┌─
diff --git a/docs/doc/fold.html b/docs/doc/fold.html
index 2890eb4d..b9dddf8b 100644
--- a/docs/doc/fold.html
+++ b/docs/doc/fold.html
@@ -4,7 +4,7 @@
<title>BQN: Fold and Insert</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="fold-and-insert">Fold and Insert</h1>
+<h1 id="fold-and-insert"><a class="header" href="#fold-and-insert">Fold and Insert</a></h1>
<svg viewBox='-184.8 -12 588 288'>
<g font-size='21px' fill='currentColor' stroke-linecap='round' text-anchor='middle' font-family='BQN,monospace'>
<rect class='code' stroke-width='1.5' rx='12' x='-128.8' y='0' width='476' height='264'/>
@@ -43,7 +43,7 @@
<p>The closely related 1-modifiers Fold (<code><span class='Modifier'>´</span></code>) and Insert (<code><span class='Modifier'>˝</span></code>) apply a dyadic operand function <code><span class='Function'>𝔽</span></code> repeatedly between elements or major cells of <code><span class='Value'>𝕩</span></code>. Neither is quite like the APL2-style Reduce operator (<code><span class='Function'>/</span></code> or <code><span class='Value'>⌿</span></code> in APL), although I sometimes use the term &quot;reduction&quot; to mean either Fold or Insert. There are a bunch of other names like &quot;accumulate&quot; and &quot;aggregate&quot; for this class of calculations—I don't know which is best but I know &quot;catamorphism&quot; is worst.</p>
<p>A distinguishing feature of APL-family reductions is that they don't use an initial value, and try to derive an &quot;identity element&quot; from the operand if the argument array is empty. BQN retains this capability but also allows the programmer to supply an initial value as <code><span class='Value'>𝕨</span></code>.</p>
-<h2 id="fold">Fold</h2>
+<h2 id="fold"><a class="header" href="#fold">Fold</a></h2>
<p>As its glyph suggests, Fold is slightly simpler than Insert. The argument <code><span class='Value'>𝕩</span></code> must always be a list, and Fold applies <code><span class='Function'>𝔽</span></code> between elements—always two at a time—of the list to yield a single result value. In this sense, <code><span class='Function'>𝔽</span><span class='Modifier'>´</span></code> removes a layer of <a href="depth.html">depth</a> from <code><span class='Value'>𝕩</span></code>, although it's not necessarily true that the depth of <code><span class='Function'>𝔽</span><span class='Modifier'>´</span><span class='Value'>𝕩</span></code> is less than that of <code><span class='Value'>𝕩</span></code> because the function <code><span class='Function'>𝔽</span></code> might increase depth.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=K8K0IDLigL804oC/M+KAvzEKK8K0IOKfqDLigL80LCAz4oC/MeKfqQ==">↗️</a><pre> <span class='Function'>+</span><span class='Modifier'>´</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span>
10
@@ -64,7 +64,7 @@
<span class='Function'>∨</span><span class='Modifier'>´</span> <span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span>
1
</pre>
-<h3 id="identity-values">Identity values</h3>
+<h3 id="identity-values"><a class="header" href="#identity-values">Identity values</a></h3>
<p>Folding over a list of length 1 never calls the operand function: it returns the lone element unchanged.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IcK0IOKfqOKOiuKfqQ==">↗️</a><pre> <span class='Function'>!</span><span class='Modifier'>´</span> <span class='Bracket'>⟨</span><span class='Modifier2'>⎊</span><span class='Bracket'>⟩</span>
@@ -132,7 +132,7 @@
</tr>
</tbody>
</table>
-<h3 id="right-to-left">Right-to-left</h3>
+<h3 id="right-to-left"><a class="header" href="#right-to-left">Right-to-left</a></h3>
<p>The functions we've shown so far are associative (ignoring floating point imprecision), meaning it's equally valid to combine elements of the argument list in any order. But it can be useful to fold using a non-associative function. In this case you must know that Fold performs a <em>right fold</em>, starting from the end of the array and working towards the beginning.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4omN4peLPMK0ICJhYmNkIgoKJ2EnIOKJjeKXizwgJ2InIOKJjeKXizwgJ2MnIOKJjeKXizwgJ2QnICAjIEV4cGFuZGVkIGZvcm0=">↗️</a><pre> <span class='Function'>≍</span><span class='Modifier2'>○</span><span class='Function'>&lt;</span><span class='Modifier'>´</span> <span class='String'>&quot;abcd&quot;</span>
⟨ 'a' ⟨ 'b' "cd" ⟩ ⟩
@@ -153,7 +153,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=K+KfnMO3wrQgMuKAvzHigL8y4oC/MeKAvzHigL804oC/MeKAvzE=">↗️</a><pre> <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'>2</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'>4</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>1</span>
2.7183098591549295
</pre>
-<h3 id="initial-element">Initial element</h3>
+<h3 id="initial-element"><a class="header" href="#initial-element">Initial element</a></h3>
<p>When the operand isn't just an arithmetic primitive, folding with no initial element can be dangerous. Even if you know <code><span class='Value'>𝕩</span></code> isn't empty, saving you from an &quot;Identity not found&quot; error, the case with only one element can easily violate expectations. Here's a somewhat silly example of a function meant to merge elements of the argument into a single list (<code><span class='Function'>∾⥊</span><span class='Modifier'>¨</span></code> is a much better way to do this):</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oi+4peL4qWKwrQg4p+oMuKAvzTiiY024oC/OCwiYWJjZCIsMOKfqQoK4oi+4peL4qWKwrQg4p+oMuKAvzTiiY024oC/OCwiYWJjZCLin6kKCuKIvuKXi+KlisK0IOKfqDLigL804omNNuKAvzjin6k=">↗️</a><pre> <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'>4</span><span class='Function'>≍</span><span class='Number'>6</span><span class='Ligature'>‿</span><span class='Number'>8</span><span class='Separator'>,</span><span class='String'>&quot;abcd&quot;</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Bracket'>⟩</span>
⟨ 2 4 6 8 'a' 'b' 'c' 'd' 0 ⟩
@@ -180,7 +180,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IlNUT1AiIOKMveKKuOKIvsK0ICJBQkNERSLigL8iMDEyIuKAvyJhYmNkIg==">↗️</a><pre> <span class='String'>&quot;STOP&quot;</span> <span class='Function'>⌽</span><span class='Modifier2'>⊸</span><span class='Function'>∾</span><span class='Modifier'>´</span> <span class='String'>&quot;ABCDE&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;012&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;abcd&quot;</span>
"EDCBA210dcbaSTOP"
</pre>
-<h2 id="insert">Insert</h2>
+<h2 id="insert"><a class="header" href="#insert">Insert</a></h2>
<p>Fold only works on lists. What if you want to, say, sum the columns of a table?</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIHRhYiDihpAgKDIr4oaVNSkgfOKMnCA5K+KGlTMKCivLnSB0YWI=">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>tab</span> <span class='Gets'>←</span> <span class='Paren'>(</span><span class='Number'>2</span><span class='Function'>+↕</span><span class='Number'>5</span><span class='Paren'>)</span> <span class='Function'>|</span><span class='Modifier'>⌜</span> <span class='Number'>9</span><span class='Function'>+↕</span><span class='Number'>3</span>
┌─
@@ -241,7 +241,7 @@
</span>⟨ 0 4 ⟩
</pre>
<p>As a historical note, Insert is named after J's adverb <code><span class='Function'>/</span></code>, which comes from SHARP APL's <code><span class='Value'>⌿</span></code>, reduce-down. In the original APL, only arithmetic reductions were defined, and nested arrays didn't exist—arrays were either all characters or all numbers. SHARP extended them by splitting the array into cells as we've shown. However, there's another interpretation, which is what you'll find in mainstream APLs today…</p>
-<h2 id="apl2-reduction">APL2 reduction?</h2>
+<h2 id="apl2-reduction"><a class="header" href="#apl2-reduction">APL2 reduction?</a></h2>
<p>If you try an expression like <code><span class='Value'>⍪⌿</span></code> in Dyalog APL, you'll get results very different from BQN's <code><span class='Function'>∾</span><span class='Modifier'>˝</span></code>. Instead of combining the cells like we see above, APL applies the function on pairs of <em>elements</em> much like Fold. The difference is that, because reduction happens only along one axis but an array might have other axes, there can be multiple values in the result, so that it will always be an array like the argument. BQN can perform this operation as well: <code><span class='Value'>⍪⌿</span></code> is written <code><span class='Function'>∾</span><span class='Modifier'>¨˝</span></code> in BQN.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oi+wqjLnSB0YWI=">↗️</a><pre> <span class='Function'>∾</span><span class='Modifier'>¨˝</span> <span class='Value'>tab</span>
⟨ ⟨ 1 0 1 4 3 ⟩ ⟨ 0 1 2 0 4 ⟩ ⟨ 1 2 3 1 5 ⟩ ⟩
diff --git a/docs/doc/fromDyalog.html b/docs/doc/fromDyalog.html
index 1662a543..84928cca 100644
--- a/docs/doc/fromDyalog.html
+++ b/docs/doc/fromDyalog.html
@@ -4,10 +4,10 @@
<title>BQN–Dyalog APL dictionary</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="bqndyalog-apl-dictionary">BQN–Dyalog APL dictionary</h1>
+<h1 id="bqndyalog-apl-dictionary"><a class="header" href="#bqndyalog-apl-dictionary">BQN–Dyalog APL dictionary</a></h1>
<p>A few tables to help users of Dyalog APL (or similar) get started quickly on BQN. Here we assume <code><span class='Value'>⎕</span><span class='Function'>ML</span></code> is 1 for Dyalog.</p>
-<h2 id="terminology">Terminology</h2>
-<h3 id="array-model">Array model</h3>
+<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>, so that a Dyalog simple scalar corresponds to many BQN values: an atom, its enclose, and so on.</p>
<table>
<thead>
@@ -37,7 +37,7 @@
</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>
-<h3 id="roles">Roles</h3>
+<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>
<thead>
@@ -69,7 +69,7 @@
</tr>
</tbody>
</table>
-<h2 id="syntax">Syntax</h2>
+<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>
<table>
@@ -109,7 +109,7 @@
<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>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>
-<h2 id="for-reading">For reading</h2>
+<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>
<table>
<thead>
@@ -272,7 +272,7 @@
</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>
-<h2 id="for-writing">For writing</h2>
+<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>
<table>
diff --git a/docs/doc/fromJ.html b/docs/doc/fromJ.html
index 46d312be..10dff0d7 100644
--- a/docs/doc/fromJ.html
+++ b/docs/doc/fromJ.html
@@ -4,15 +4,15 @@
<title>BQN–J dictionary</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="bqnj-dictionary">BQN–J dictionary</h1>
+<h1 id="bqnj-dictionary"><a class="header" href="#bqnj-dictionary">BQN–J dictionary</a></h1>
<style>.Comment { color: inherit; }</style>
<p>A guide to help users of J get up to speed with BQN quickly.</p>
-<h2 id="terminology">Terminology</h2>
-<h3 id="array-model">Array model</h3>
+<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>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">Roles</h3>
+<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>
<table>
<thead>
@@ -40,7 +40,7 @@
</tr>
</tbody>
</table>
-<h2 id="syntax">Syntax</h2>
+<h2 id="syntax"><a class="header" href="#syntax">Syntax</a></h2>
<table>
<thead>
<tr>
@@ -108,7 +108,7 @@
</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>
-<h2 id="for-reading">For reading</h2>
+<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>
<table>
@@ -329,7 +329,7 @@
</tr>
</tbody>
</table>
-<h2 id="for-writing">For writing</h2>
+<h2 id="for-writing"><a class="header" href="#for-writing">For writing</a></h2>
<p>J's primitive nouns are easily defined in BQN.</p>
<table>
<thead>
diff --git a/docs/doc/functional.html b/docs/doc/functional.html
index 1595e5ae..d48b78d1 100644
--- a/docs/doc/functional.html
+++ b/docs/doc/functional.html
@@ -4,7 +4,7 @@
<title>BQN: Functional programming</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="functional-programming">Functional programming</h1>
+<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>
@@ -61,14 +61,14 @@
<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 Haskell, F#, and Idris (the last of which even supports <em>dependently-typed 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+ 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">Functions in APL</h2>
+<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>
<p>Another reason for APL's reluctance to adopt first-class functions is that Iverson and others seemed to believe that functions fundamentally are not a kind of data, because it's impossible to uniquely represent, compare, and order them. One effect of this viewpoint is J's gerund mechanism, which converts a function to an array representation, primarily so that lists of gerunds can be created. Gerunds are nested arrays containing character vectors at the leaves, so they are arrays as Iverson thought of them. However, I consider this conversion of functions to arrays, intended to avoid arrays that contain &quot;black box&quot; functions, to be a mistake: while it doesn't compromise the purity of arrays, it gives the illusion that a function corresponds to a particular array, which is not true from the mathematical perspective of functions as mappings from an arbitrary input to an output. I also think the experience of countless languages with first-class functions shows that there is no practical issue with arrays that contain functions. While having all arrays be concrete entities with a unique canonical representation seems desirable, I don't find the existence of arrays without this property to be detract from working with arrays that do have it.</p>
-<h2 id="functional-programming-in-bqn">Functional programming in BQN</h2>
+<h2 id="functional-programming-in-bqn"><a class="header" href="#functional-programming-in-bqn">Functional programming in BQN</a></h2>
<p><em>Reminder: I am discussing only first-class functional programming here, and not other concepts like pure or typed functional programming!</em></p>
<p>What does functional programming in BQN look like? How is it different from the typical APL style of manipulating functions with operators?</p>
-<h3 id="working-with-roles">Working with roles</h3>
+<h3 id="working-with-roles"><a class="header" href="#working-with-roles">Working with roles</a></h3>
<p>First, let's look at the basics: a small program that has functions as its argument and result. The function <code><span class='Function'>Lin</span></code> below gives a linear approximation to its function argument based on the values at 0 and 1. To find these two values, we call the argument as a function by using its uppercase spelling, <code><span class='Function'>𝕏</span></code>.</p>
<pre><span class='Function'>Lin</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='Value'>v0</span> <span class='Gets'>←</span> <span class='Function'>𝕏</span> <span class='Number'>0</span>
@@ -105,7 +105,7 @@
</span> <span class='Function'>Exp</span> <span class='Modifier'>_lin</span> <span class='Number'>5</span>
9.591409142295225
</pre>
-<h3 id="arrays-of-functions">Arrays of functions</h3>
+<h3 id="arrays-of-functions"><a class="header" href="#arrays-of-functions">Arrays of functions</a></h3>
<p>It's very convenient to put a function in an array, which is fortunate because this is one of the most important uses of functions as subjects. Here's an example of an array of functions with a <a href="fold.html">fold</a> applied to it, composing them together.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=e/CdlY7iiJjwnZWPfcK0IOKLhuKAvy3igL8ow5fLnCk=">↗️</a><pre> <span class='Brace'>{</span><span class='Function'>𝕎</span><span class='Modifier2'>∘</span><span class='Function'>𝕏</span><span class='Brace'>}</span><span class='Modifier'>´</span> <span class='Function'>⋆</span><span class='Ligature'>‿</span><span class='Function'>-</span><span class='Ligature'>‿</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>˜</span><span class='Paren'>)</span>
⋆∘(-∘(ט))
diff --git a/docs/doc/glossary.html b/docs/doc/glossary.html
index b24ce012..8aeb819a 100644
--- a/docs/doc/glossary.html
+++ b/docs/doc/glossary.html
@@ -4,9 +4,9 @@
<title>BQN glossary</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="bqn-glossary">BQN glossary</h1>
+<h1 id="bqn-glossary"><a class="header" href="#bqn-glossary">BQN glossary</a></h1>
<p>Below are short, and sometimes vague, definitions of terms used to describe BQN code.</p>
-<h2 id="types">Types</h2>
+<h2 id="types"><a class="header" href="#types">Types</a></h2>
<ul>
<li><strong>Value</strong>: Something that can be stored in variables and manipulated by a BQN programmer.</li>
<li><a href="types.html"><strong>Type</strong></a>: One of seven possible kinds of value.</li>
@@ -37,7 +37,7 @@
<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">Roles</h2>
+<h2 id="roles"><a class="header" href="#roles">Roles</a></h2>
<ul>
<li><a href="context.html"><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>
@@ -48,7 +48,7 @@
<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">Arrays</h2>
+<h2 id="arrays"><a class="header" href="#arrays">Arrays</a></h2>
<ul>
<li><strong>Array</strong>: A multidimensional collection of values.</li>
<li><strong>Element</strong>: One of the values contained in an array.</li>
@@ -77,7 +77,7 @@
<ul>
<li><a href="indices.html"><strong>Index</strong></a>: One of a variety of ways to select an element, cell, axis, or position along an axis of an array.</li>
</ul>
-<h2 id="operations">Operations</h2>
+<h2 id="operations"><a class="header" href="#operations">Operations</a></h2>
<ul>
<li><strong>Operation</strong>: A value that is called on inputs to perform computation and return a result or cause an error.</li>
<li><strong>Call</strong>: Submit inputs to an operation and receive any result.</li>
@@ -99,7 +99,7 @@
<li><strong>Error</strong>: A condition that stops compilation or execution.</li>
<li><strong>Inferred property</strong>: A property of a value that is derived by BQN based on constraints. If it cannot be derived then the value will not have the property.</li>
</ul>
-<h2 id="tokens">Tokens</h2>
+<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>
<li><strong>Token</strong>: A name, literal, primitive, or other syntactic element.</li>
@@ -112,7 +112,7 @@
<li><strong>Character literal</strong>: A literal written with single quotes <code><span class='String'>''</span></code>, indicating a string.</li>
<li><strong>Null literal</strong>: The literal <code><span class='String'>@</span></code>, indicating the null character (code point 0).</li>
</ul>
-<h2 id="parsing">Parsing</h2>
+<h2 id="parsing"><a class="header" href="#parsing">Parsing</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>
@@ -121,7 +121,7 @@
<li><strong>Ligature</strong>: 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>
</ul>
-<h2 id="assignment-and-scoping">Assignment and scoping</h2>
+<h2 id="assignment-and-scoping"><a class="header" href="#assignment-and-scoping">Assignment and scoping</a></h2>
<ul>
<li><a href="syntax.html#assignment"><strong>Assignment</strong></a>: An operation that sets a variable's value. Definition (<code><span class='Gets'>←</span></code>) or a change of definition (<code><span class='Gets'>↩</span></code>).</li>
<li><strong>Assignment arrow</strong>: <code><span class='Gets'>←</span></code> or <code><span class='Gets'>↩</span></code>, used to denote assignment.</li>
@@ -131,7 +131,7 @@
<li><strong>Scope</strong>: An environment where variables are defined and manipulated, which is created before evaluating a body.</li>
<li><strong>Identifier</strong>: An instance of a name in a program, with two identifiers considered the same if they correspond to the same definition.</li>
</ul>
-<h2 id="blocks">Blocks</h2>
+<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><strong>Immediate block</strong>: A block that is evaluated and returns a value immediately; it has a subject role.</li>
diff --git a/docs/doc/group.html b/docs/doc/group.html
index 1e3afd03..03357675 100644
--- a/docs/doc/group.html
+++ b/docs/doc/group.html
@@ -4,7 +4,7 @@
<title>BQN: Group</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="group">Group</h1>
+<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'>
@@ -29,7 +29,7 @@
</g>
</svg>
-<h2 id="definition">Definition</h2>
+<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>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MOKAvzHigL8y4oC/MOKAvzEg4omNICJhYmNkZSIgICMgQ29ycmVzcG9uZGluZyBpbmRpY2VzIGFuZCB2YWx1ZXMKMOKAvzHigL8y4oC/MOKAvzEg4oqUICJhYmNkZSIgICMgVmFsdWVzIGdyb3VwZWQgYnkgaW5kZXg=">↗️</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>┌─
@@ -102,7 +102,7 @@
</pre>
<p>Here, the index 2 appears at indices 0 and 3 while the index 3 appears at index 1.</p>
-<h3 id="multidimensional-grouping">Multidimensional grouping</h3>
+<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>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>
@@ -119,7 +119,7 @@
</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>
<p>The monadic case works similarly: Group Indices always satisfies <code><span class='Function'>⊔</span><span class='Value'>𝕩</span> <span class='Gets'>←→</span> <span class='Value'>𝕩</span><span class='Function'>⊔↕≠</span><span class='Modifier2'>⚇</span><span class='Number'>1</span><span class='Value'>𝕩</span></code>. 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. A depth-0 argument is not allowed.</p>
-<h2 id="properties">Properties</h2>
+<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 ⟩
@@ -137,7 +137,7 @@
"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>
-<h2 id="applications">Applications</h2>
+<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>
<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>
@@ -171,7 +171,7 @@
"ZW" ⟨⟩
</pre>
-<h3 id="partitioning">Partitioning</h3>
+<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>
<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" ⟩
diff --git a/docs/doc/identity.html b/docs/doc/identity.html
index 36795e61..5b710809 100644
--- a/docs/doc/identity.html
+++ b/docs/doc/identity.html
@@ -4,7 +4,7 @@
<title>BQN: Identity functions</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="identity-functions">Identity functions</h1>
+<h1 id="identity-functions"><a class="header" href="#identity-functions">Identity functions</a></h1>
<p>Here are the simplest functions in BQN: Right (<code><span class='Function'>⊢</span></code>) always returns its right argument, and Left (<code><span class='Function'>⊣</span></code>) returns its left argument if called with two arguments, and the right argument otherwise.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiICJvbmx5IgoK4oqjICJvbmx5IgoKImxlZnQiIOKKoiAicmlnaHQiCgoibGVmdCIg4oqjICJyaWdodCI=">↗️</a><pre> <span class='Function'>⊢</span> <span class='String'>&quot;only&quot;</span>
"only"
@@ -20,7 +20,7 @@
</pre>
<p>Depending on your past experiences, this could cause some confusion: built-in support for functions that do nothing? Documentation should say why a feature's there and how to use it, not just what it does, so we'll try to address this below. The most important single use is for tacit programming, but there are a variety of other uses as well.</p>
<p>Of course, it's easy to write block functions <code><span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> and <code><span class='Brace'>{</span><span class='Value'>𝕨</span><span class='Brace'>}</span></code> that return particular arguments. While I would already make <code><span class='Function'>⊣</span></code> and <code><span class='Function'>⊢</span></code> primitives just because they are common and important, there are also specific disadvantages to using blocks. They fail to indicate that there are no side effects, as primitives would, and they also need special casing for the interpreter to manipulate them when applying <a href="undo.html">Undo</a> (<code><span class='Modifier'>⁼</span></code>) or making other inferences.</p>
-<h2 id="filling-arrays">Filling arrays</h2>
+<h2 id="filling-arrays"><a class="header" href="#filling-arrays">Filling arrays</a></h2>
<p>What's the easiest way to create a matrix with 0 on the first row, 1 on the second, and so on? Probably this one, with <a href="map.html#table">table</a>:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKGlTQpIOKKo+KMnCDihpU1">↗️</a><pre> <span class='Paren'>(</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'>5</span>
┌─
@@ -49,7 +49,7 @@
</pre>
<p>This method can replace even values nested deeply in arrays, as long as you can write the function to get at them. The parts that aren't accessed don't even need to have matching shapes!</p>
-<h2 id="as-a-variable">As a variable</h2>
+<h2 id="as-a-variable"><a class="header" href="#as-a-variable">As a variable</a></h2>
<p>Suppose you want a list of a matrix, its transpose, and its negation. One way to do this is to put together a list of functions for each of these values: the first one is an identity.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqi4oC/4o2J4oC/LSB78J2VjvCdlal9wqg8IDDigL/CrzHiiY0x4oC/MA==">↗️</a><pre> <span class='Function'>⊢</span><span class='Ligature'>‿</span><span class='Function'>⍉</span><span class='Ligature'>‿</span><span class='Function'>-</span> <span class='Brace'>{</span><span class='Function'>𝕎</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier'>¨</span><span class='Function'>&lt;</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>¯1</span><span class='Function'>≍</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span>
┌─
@@ -60,7 +60,7 @@
</pre>
<p>Here <code><span class='Function'>⊢</span></code> ends up being used as <code><span class='Function'>𝕎</span></code>. A similar case might be a function or program with a caller-specified processing step. For example, a function to write some kind of file, with a parameter function to encrypt data before writing. To use no encryption, you'd pass a parameter <code><span class='Function'>⊢</span></code>. Or it might happen that you write a Choose (<code><span class='Modifier2'>◶</span></code>) expression where one of the cases should do nothing <code><span class='Function'>⊢</span></code>, or return the left argument <code><span class='Function'>⊣</span></code>.</p>
-<h2 id="in-tacit-functions">In tacit functions</h2>
+<h2 id="in-tacit-functions"><a class="header" href="#in-tacit-functions">In tacit functions</a></h2>
<p>In a tacit context, <code><span class='Function'>⊣</span></code> is roughly equivalent to <code><span class='Value'>𝕨</span></code> and <code><span class='Function'>⊢</span></code> to <code><span class='Value'>𝕩</span></code>. In some (not too common) cases, it's even possible to translate a block function to tacit code directly by replacing the variables in this way.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyB78J2VqS3wnZWow7cxK/Cdlal9IDUKMyAo4oqiLeKKo8O3MSviiqIpIDU=">↗️</a><pre> <span class='Number'>3</span> <span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Function'>-</span><span class='Value'>𝕨</span><span class='Function'>÷</span><span class='Number'>1</span><span class='Function'>+</span><span class='Value'>𝕩</span><span class='Brace'>}</span> <span class='Number'>5</span>
4.5
@@ -68,7 +68,7 @@
4.5
</pre>
<p>A larger class of block functions can be translated just by adding parentheses and <code><span class='Modifier'>˙</span></code> (there's a discussion of this technique in APL <a href="https://dfns.dyalog.com/n_tacit.htm">here</a>). It's helpful when writing tacit code to know that <code><span class='Function'>Fn</span><span class='Modifier2'>∘</span><span class='Function'>⊣</span></code> applies <code><span class='Function'>Fn</span></code> to the left argument only and <code><span class='Function'>Fn</span><span class='Modifier2'>∘</span><span class='Function'>⊢</span></code> applies it to the right argument—these can be read &quot;Fn of left&quot; and &quot;Fn of right&quot;.</p>
-<h2 id="syntax-tricks">Syntax tricks</h2>
+<h2 id="syntax-tricks"><a class="header" href="#syntax-tricks">Syntax tricks</a></h2>
<p>You've probably seen <code><span class='Function'>⊢</span></code> used in documentation to display the value of a variable being assigned. This is a hack, and in most contexts <code><span class='Function'>•Show</span></code> should be used to display values.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGEg4oaQICJzaG93IHRoaXMi">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='String'>&quot;show this&quot;</span>
"show this"
diff --git a/docs/doc/index.html b/docs/doc/index.html
index ec0e46eb..3f4e2d2c 100644
--- a/docs/doc/index.html
+++ b/docs/doc/index.html
@@ -4,7 +4,7 @@
<title>BQN documentation</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a></div>
-<h1 id="bqn-documentation">BQN documentation</h1>
+<h1 id="bqn-documentation"><a class="header" href="#bqn-documentation">BQN documentation</a></h1>
<p>BQN's documentation describes what features it has, how to use them (with examples), and why they were chosen. For a linear introduction to the language, see the <a href="../tutorial/index.html">tutorials</a>. While the core language <a href="../spec/index.html">specification</a> is complete, the documentation still has minor gaps.</p>
<p>Overview:</p>
<ul>
diff --git a/docs/doc/indices.html b/docs/doc/indices.html
index fe67492d..8ed4317e 100644
--- a/docs/doc/indices.html
+++ b/docs/doc/indices.html
@@ -4,7 +4,7 @@
<title>BQN: Indices</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="indices">Indices</h1>
+<h1 id="indices"><a class="header" href="#indices">Indices</a></h1>
<p>One-dimensional arrays such as K lists or Python arrays have only one kind of index, a single number that refers to an element. For <a href="array.html">multidimensional arrays</a> using the <a href="leading.html">leading axis theory</a>, there are several types of indexing that can be useful. Historically, nested APL designs have equivocated between these, which I believe can lead to subtle errors when programming. BQN focuses on single-number (atomic) indices, which can refer to list elements or array major cells (or more generally indexing along any particular axis). When using atomic indices to select elements, the indexed array has to be a list. In contrast, elements of any array can be indicated by list indices with length equal to that array's rank. Only two BQN primitives use these list indices: <a href="range.html">Range</a> (<code><span class='Function'>↕</span></code>), which returns an array of them if given a list argument, and <a href="pick.html">Pick</a> (<code><span class='Function'>⊑</span></code>), where the depth-1 components of an array left argument are list indices.</p>
<p>The following functions take or return indices. Except where marked, the indices are in the result; this is by far the most common type of index use. <a href="group.html">Group</a> (<code><span class='Function'>⊔</span></code>) is given two rows as it falls into both cases. Note that in the result case, there is usually no possibility for the programmer to select the format of indices. Instead, the language should be carefully designed to make sure that the kind of index returned is as useful as possible.</p>
<table>
@@ -86,15 +86,15 @@
</tbody>
</table>
<p>In Dyadic <a href="transpose.html#dyadic-transpose">Transpose</a> (<code><span class='Function'>⍉</span></code>), <code><span class='Value'>𝕨</span></code> is made up of indices into axes of <code><span class='Value'>𝕩</span></code>. Since array shape is 1-dimensional, there is only one sensible choice for these elements, a single number each.</p>
-<h2 id="element-indices">Element indices</h2>
+<h2 id="element-indices"><a class="header" href="#element-indices">Element indices</a></h2>
<p>In general, the index of an element of an array is a list whose length matches the array rank. It is also possible to use a number for an index into a list, as the list index is a singleton, but this must be kept consistent with the rest of the language. NARS-family APLs make the Index Generator (<code><span class='Function'>↕</span></code> in BQN) return a numeric list when the argument has length 1 but a nested array otherwise. This means that the depth of the result depends on the shape of the argument, inverting the typical hierarchy. BQN shouldn't have such an inconsistency.</p>
<p>Functions <a href="range.html">Range</a> (<code><span class='Function'>↕</span></code>), <a href="replicate.html">Indices</a> (<code><span class='Function'>/</span></code>), <a href="group.html">Group</a> (<code><span class='Function'>⊔</span></code>), and <a href="pick.html">Pick</a> (<code><span class='Function'>⊑</span></code>) naturally deal with element indices. Each of these can be defined to use list indices. However, this usually rules out the possibility of using atomic indices, which makes these functions harder to use both with generic array manipulation and with the major cell indices discussed in the next section. For this reason BQN restricts <code><span class='Function'>⊔</span></code> and <code><span class='Function'>/</span></code> to use atomic indices, which comes with the requirement that the arguments to Group and Indices, and the result of Group Indices, must be lists. For dyadic Group the depth-1 elements of <code><span class='Value'>𝕨</span></code> are arrays of indices along axes of the result (<a href="group.html#multidimensional-grouping">multi-axis documentation</a>). This means each axis of <code><span class='Value'>𝕩</span></code> can only be related to one axis of the result.</p>
<p>Unlike <code><span class='Function'>/</span></code> and <code><span class='Function'>⊔</span></code>, <code><span class='Function'>↕</span></code> and <code><span class='Function'>⊑</span></code> do use list element indices. For <code><span class='Function'>↕</span></code> this is because the output format can be controlled by the argument format: if passed a single number, the result uses atomic indices (so it's a numeric list); if passed a list, it uses list indices and the result has depth 2 (the result depth is always one greater than the argument depth). For <code><span class='Function'>⊑</span></code>, list indices are chosen because <a href="select.html">Select</a> (<code><span class='Function'>⊏</span></code>) handles atomic indices well already. When selecting multiple elements from a list, they would typically have to be placed in an array, which is equivalent to <code><span class='Function'>⊏</span></code> with a numeric list <code><span class='Value'>𝕨</span></code>. An atom <code><span class='Value'>𝕨</span></code> in Pick is converted to a list, so it can be used to select a single element if only one is wanted. To select multiple elements, <code><span class='Function'>⊑</span></code> uses each depth-1 array in <code><span class='Value'>𝕨</span></code> as an index and replaces it with that element from the right argument. Because this uses elements as elements (not cells), it is impossible to have conformability errors where elements do not fit together (invalid index errors are of course still possible). Atoms also cannot be used in this context, as it would create ambiguity: is a one-element list an index, or does it contain an index?</p>
-<h2 id="major-cell-indices">Major cell indices</h2>
+<h2 id="major-cell-indices"><a class="header" href="#major-cell-indices">Major cell indices</a></h2>
<p>One of the successes of the <a href="https://aplwiki.com/wiki/Leading_axis_theory">leading axis model</a> is to introduce a kind of index for multidimensional arrays that is easier to work with than list indices. The model introduces <a href="https://aplwiki.com/wiki/Cell">cells</a>, where a cell index is a list of any length up to the containing array's rank. General cell indices are discussed in the next section; first we introduce a special case, indices into major cells or ¯1-cells. These cells naturally form a list, so the index of a major cell is a single number. Such an index can also be considered to select along the first axis, since an index along any axis is a single number.</p>
<p><a href="order.html">Ordering</a> functions <code><span class='Function'>⍋⍒</span></code> and <a href="search.html">search</a>/<a href="selfcmp.html">self-search</a> functions <code><span class='Function'>⊐⊒</span></code> that depend on cell ordering only really make sense with major cell indices: while other indices have an ordering, it's not very natural. Note that <code><span class='Function'>⊐</span></code> only uses the ordering in an incidental way, because it's defined to return the <em>first</em> index where a cell in <code><span class='Value'>𝕩</span></code> is found. A mathematician would be more interested in a &quot;pre-image&quot; function that returns the set of all indices where a particular value appears. However, programming usefulness and consistency with the other search functions makes searching for the first index a reasonable choice.</p>
<p>Only one other function—but an important one!—deals with cells rather than elements: <a href="select.html">Select</a> (<code><span class='Function'>⊏</span></code>). Select <a href="leading.html#multiple-axes">allows</a> either a simple first-axis case where <code><span class='Value'>𝕨</span></code> has depth 1 or less (a depth-0 argument is automatically enclosed), and a multi-axis case where it is a list of depth-1 elements. In each case the depth-1 arrays index along a single axis.</p>
-<h2 id="general-cell-indices">General cell indices</h2>
+<h2 id="general-cell-indices"><a class="header" href="#general-cell-indices">General cell indices</a></h2>
<p>BQN does not use general cell indices directly, but it is useful to consider how they might work, and how a programmer might implement functions that use them in BQN if needed. The functions <code><span class='Function'>/</span></code>, <code><span class='Function'>⊔</span></code>, and <code><span class='Function'>⊏</span></code> are the ones that can work with indices for multidimensional arrays but don't already. Here we will examine how multidimensional versions would work.</p>
<p>A cell index into an array of rank <code><span class='Value'>r</span></code> is a numeric list of length <code><span class='Value'>l</span><span class='Function'>≤</span><span class='Value'>r</span></code>, which then refers to a cell of rank <code><span class='Value'>r</span><span class='Function'>-</span><span class='Value'>l</span></code>. In BQN, the cell at index <code><span class='Value'>i</span></code> of array <code><span class='Value'>a</span></code> is <code><span class='Value'>i</span><span class='Function'>&lt;</span><span class='Modifier'>¨</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span><span class='Value'>a</span></code>.</p>
<p>Because the shape of a cell index relates to the shape of the indexed array, it makes sense not to enclose cell indices, instead treating them as rows of an index array. A definition for <code><span class='Function'>⊏</span></code> for depth-1 left arguments of rank at least 1 follows: replace each row of the left argument with the indexed cell of the right, yielding a result with the same depth as the right argument and shape <code><span class='Value'>𝕨</span><span class='Paren'>((</span><span class='Number'>¯1</span><span class='Function'>↓⊣</span><span class='Paren'>)</span><span class='Function'>∾</span><span class='Paren'>(</span><span class='Number'>¯1</span><span class='Function'>↑⊣</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>↓</span><span class='Paren'>)</span><span class='Modifier2'>○</span><span class='Function'>≢</span><span class='Value'>𝕩</span></code>.</p>
diff --git a/docs/doc/join.html b/docs/doc/join.html
index 414f19b0..220c6631 100644
--- a/docs/doc/join.html
+++ b/docs/doc/join.html
@@ -4,9 +4,9 @@
<title>BQN: Join and Join To</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="join-and-join-to">Join and Join To</h1>
+<h1 id="join-and-join-to"><a class="header" href="#join-and-join-to">Join and Join To</a></h1>
<p>The glyph <code><span class='Function'>∾</span></code> combines arrays along an existing axis, a concept that other languages might call &quot;concatenation&quot; or &quot;catenation&quot; but BQN names &quot;Join&quot;. The one-argument form Join and two-argument form Join To are parallel to <a href="couple.html">the functions</a> that combine arrays along a new axis, Merge (<code><span class='Function'>&gt;</span></code>) and Couple (<code><span class='Function'>≍</span></code>).</p>
-<h2 id="join-to">Join To</h2>
+<h2 id="join-to"><a class="header" href="#join-to">Join To</a></h2>
<p>Join To connects its two arguments together, for example to join two strings:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ImFiY2QiIOKIviAiRUZHIg==">↗️</a><pre> <span class='String'>&quot;abcd&quot;</span> <span class='Function'>∾</span> <span class='String'>&quot;EFG&quot;</span>
"abcdEFG"
@@ -50,7 +50,7 @@
⟨ 3 'c' ⟩
</pre>
<p>This case is unusual because the rank of the result is higher than that of either argument. It's also identical to Couple (<code><span class='Function'>≍</span></code>); Couple should be preferred because it doesn't require a special case for this situation. See <a href="couple.html#coupling-units">coupling units</a>.</p>
-<h2 id="join">Join</h2>
+<h2 id="join"><a class="header" href="#join">Join</a></h2>
<p>The monadic form of <code><span class='Function'>∾</span></code>, called simply Join, is more complicated than Join To because it really takes not just one argument but an entire array of them. Join is an extension of the monadic function <a href="https://aplwiki.com/wiki/Raze">Raze</a> from A+ and J to arbitrary argument ranks. It has the same relationship to Join to, the dyadic function sharing the same glyph, as <a href="couple.html">Merge</a> (<code><span class='Function'>&gt;</span></code>) does to Couple (<code><span class='Function'>≍</span></code>): <code><span class='Value'>a</span><span class='Function'>≍</span><span class='Value'>b</span></code> is <code><span class='Function'>&gt;</span><span class='Value'>a</span><span class='Ligature'>‿</span><span class='Value'>b</span></code> and <code><span class='Value'>a</span><span class='Function'>∾</span><span class='Value'>b</span></code> is <code><span class='Function'>∾</span><span class='Value'>a</span><span class='Ligature'>‿</span><span class='Value'>b</span></code>. While Merge and Couple combine arrays (the elements of Merge's argument, or the arguments themselves for Couple) along a new leading axis, Join and Join to combine them along the existing leading axis. Both Merge and Join can also be called on a higher-rank array, causing Merge to add multiple leading axes while Join combines elements along multiple existing axes.</p>
<p>Join can be used to combine several strings into a single string, like <code><span class='Value'>array.join</span><span class='Paren'>()</span></code> in Javascript (but it doesn't force the result to be a string).</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oi+InRpbWUi4oC/InRvIuKAvyJqb2luIuKAvyJzb21lIuKAvyJ3b3JkcyI=">↗️</a><pre> <span class='Function'>∾</span><span class='String'>&quot;time&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;to&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;join&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;some&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;words&quot;</span>
diff --git a/docs/doc/leading.html b/docs/doc/leading.html
index ac7d2d49..55b72a40 100644
--- a/docs/doc/leading.html
+++ b/docs/doc/leading.html
@@ -4,10 +4,10 @@
<title>BQN: The leading axis convention</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="the-leading-axis-convention">The leading axis convention</h1>
+<h1 id="the-leading-axis-convention"><a class="header" href="#the-leading-axis-convention">The leading axis convention</a></h1>
<p>Several primitive functions manipulate the right argument, or sometimes both arguments, of an <a href="array.html">array</a> along one or more axes. According to the <a href="https://aplwiki.com/wiki/Leading_axis_theory">leading axis model</a>, it's best to make the primitives operate on initial axes, because the Rank modifier then allows it to apply to later axes as well. Here we'll see how this pattern works in BQN.</p>
-<h2 id="monadic-functions">Monadic functions</h2>
-<h3 id="manipulating-cells">Manipulating cells</h3>
+<h2 id="monadic-functions"><a class="header" href="#monadic-functions">Monadic functions</a></h2>
+<h3 id="manipulating-cells"><a class="header" href="#manipulating-cells">Manipulating cells</a></h3>
<p>Most non-arithmetic monadic functions work only on the first axis of the argument—that is, they treat it as a list of its major cells. The function <a href="shape.html">Length</a> (<code><span class='Function'>≠</span></code>) counts these major cells, while <a href="prefixes.html">Prefixes</a> (<code><span class='Function'>↑</span></code>), Suffixes (<code><span class='Function'>↓</span></code>), <a href="reverse.html">Reverse</a> (<code><span class='Function'>⌽</span></code>), and <a href="select.html">First Cell</a> (<code><span class='Function'>⊏</span></code>) move them around. The <a href="fold.html#insert">Insert</a> (<code><span class='Modifier'>˝</span></code>) and <a href="scan.html">Scan</a> (<code><span class='Modifier'>`</span></code>) modifiers also yield functions that work along the first axis; in contrast, <a href="fold.html">Fold</a> (<code><span class='Modifier'>´</span></code>) requires <code><span class='Value'>𝕩</span></code> to be a list, as it works on elements.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGEg4oaQIDPigL8yIOKliiAiYWJjZGVmIiAgIyBBbiBhcnJheSB3aXRoIHRocmVlIG1ham9yIGNlbGxzCuKKjyBhICAgICAgICAgICAgICAgICAgICMgR2V0IHRoZSBmaXJzdCBtYWpvciBjZWxsCuKMvSBhICAgICAgICAgICAgICAgICAgICMgUmV2ZXJzZSB0aGUgY2VsbHMK4oqjYCBhICAgICAgICAgICAgICAgICAgIyBSZXBsaWNhdGUgdGhlIGZpcnN0IGNlbGw=">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span> <span class='Function'>⥊</span> <span class='String'>&quot;abcdef&quot;</span> <span class='Comment'># An array with three major cells
</span>┌─
@@ -80,7 +80,7 @@
<span class='Function'>≢</span> <span class='Function'>≍</span><span class='Modifier2'>⎉</span><span class='Number'>0</span> <span class='Value'>a</span> <span class='Comment'># …or deeper still.
</span>⟨ 3 2 1 ⟩
</pre>
-<h3 id="comparing-cells">Comparing cells</h3>
+<h3 id="comparing-cells"><a class="header" href="#comparing-cells">Comparing cells</a></h3>
<p>The functions in the last section manipulate cells in the same way regardless of what data they contain. Other functions compare cells to each other, either testing whether they match or how they are ordered relative to one another. The two <a href="order.html">Grade</a> functions <code><span class='Function'>⍋⍒</span></code>, and the <a href="selfcmp.html">self-search</a> functions Classify (<code><span class='Function'>⊐</span></code>), Mark Firsts (<code><span class='Function'>∊</span></code>), and Occurrence Count (<code><span class='Function'>⊒</span></code>), each give a list result, with one number for each cell. We can see below that Occurrence Count returns the same results even as we make the argument cells more complicated, because the changes made preserve the matching of cells.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=cyDihpAgImFicmFjYWRhYnJhIgriipIgcwriipIg4omNy5ggcwriipIgcyDiiL7ijokw4oC/MSAic3VmZml4Ig==">↗️</a><pre> <span class='Value'>s</span> <span class='Gets'>←</span> <span class='String'>&quot;abracadabra&quot;</span>
<span class='Function'>⊒</span> <span class='Value'>s</span>
@@ -106,13 +106,13 @@
3 3 2 1 0
</pre>
-<h3 id="other-monadic-functions">Other monadic functions</h3>
+<h3 id="other-monadic-functions"><a class="header" href="#other-monadic-functions">Other monadic functions</a></h3>
<p>Not all functions work on the first axis in a straightforward manner. <a href="transpose.html">Transpose</a> <code><span class='Function'>⍉</span></code> moves the first axis to the end, so while it focuses on the first one, it shifts every axis of <code><span class='Value'>𝕩</span></code>. <a href="join.html">Join</a> <code><span class='Function'>∾</span></code> also works on every axis of its argument, and applies to the leading axes of <code><span class='Value'>𝕩</span></code>'s <em>elements</em> instead: these leading inner axes are matched up with the outer axes, and trailing inner axes are allowed but the elements must have rank at least as high as the argument array.</p>
<p>The other two monadic functions that work on high-rank arguments are <a href="reshape.html#deshape">Deshape</a> (<code><span class='Function'>⥊</span></code>) and <a href="pick.html#first">First</a> (<code><span class='Function'>⊑</span></code>). These treat <code><span class='Value'>𝕩</span></code> as one long list, ordered by its element indices. This ordering privileges leading axes (in fact, it is the reason for the choice of leading axes in the leading axis convention), but these functions can't really be said to work on leading axes: they apply to all axes.</p>
<p>The <a href="map.html">Each</a> (<code><span class='Modifier'>¨</span></code>) and <a href="map.html#table">Table</a> (<code><span class='Modifier'>⌜</span></code>) modifiers return functions which are the same in the monadic case. These functions simply go through all elements of the argument array without regard for its multi-dimensional structure (the operand is applied to elements in index order, matching Deshape; this matters if it has side effects). Similarly, monadic arithmetic functions do not have any sort of leading axis dependence.</p>
-<h2 id="dyadic-functions">Dyadic functions</h2>
+<h2 id="dyadic-functions"><a class="header" href="#dyadic-functions">Dyadic functions</a></h2>
<p>For dyadic functions the pattern of working on only one argument axis is not so common. Only two functions can be said to follow it roughly: <a href="join.html">Join to</a> (<code><span class='Function'>∾</span></code>) combines two arrays along one axis, using the first axis of both arguments if they have the same rank and of the higher-rank argument if they differ by one. <a href="couple.html">Couple</a> (<code><span class='Function'>≍</span></code>), like Solo, does not manipulate the argument axes but adds a result axis. There are also some functions that can't be limited to leading axes: <a href="reshape.html">Reshape</a> (<code><span class='Function'>⥊</span></code>) treats <code><span class='Value'>𝕩</span></code> as one long list, and <a href="pick.html">Pick</a> (<code><span class='Function'>⊑</span></code>) requires each index to be as long as <code><span class='Value'>𝕩</span></code>'s rank, because it selects elements and not cells from <code><span class='Value'>𝕩</span></code>.</p>
-<h3 id="multiple-axes">Multiple axes</h3>
+<h3 id="multiple-axes"><a class="header" href="#multiple-axes">Multiple axes</a></h3>
<p>Instead of always working on a single axis, many dyadic functions work on one axis by default, but also allow a left argument with multiple elements corresponding to leading axes of <code><span class='Value'>𝕩</span></code>. To decide which of the two possibilities applies, these functions test the depth of <code><span class='Value'>𝕨</span></code>, a convention that is discussed in the <a href="depth.html#testing-depth-for-multiple-axis-primitives">depth</a> documentation. A left argument that applies to one axis has a particular depth; <code><span class='Value'>𝕨</span></code> can also be a list of such arguments.</p>
<table>
<thead>
@@ -145,7 +145,7 @@
⟨ 4 5 7 7 ⟩
</pre>
<p>Functions with single-axis depth 1 tend to be more complicated; see for example <a href="group.html#multidimensional-grouping">Group</a>.</p>
-<h3 id="leading-axis-agreement">Leading axis agreement</h3>
+<h3 id="leading-axis-agreement"><a class="header" href="#leading-axis-agreement">Leading axis agreement</a></h3>
<p><a href="arithmetic.html">Arithmetic</a> functions, and the <a href="map.html#each">Each</a> (<code><span class='Modifier'>¨</span></code>) and <a href="depth.html#the-depth-modifier">Depth</a> (<code><span class='Modifier2'>⚇</span></code>) modifiers, use leading axis agreement to match their arguments together. All axes of the lower-rank argument are matched with the leading axes of the higher-rank one, and axes matched together must have the same length. After pairing axes in this way, a single element of the lower-rank argument might correspond to any number of elements of the higher-rank one. It's reused for each of those corresponding elements.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIHgg4oaQIDPigL8y4oC/NCDipYog4oaVNjAgICAgICMgQSByYW5rLTMgYXJyYXkKMTAw4oC/MOKAvzIwMCArIHggICAgICAgICAjIDAtY2VsbHMgcGFpcmVkIHdpdGggMi1jZWxscwriiqIgYyDihpAgMTAwIMOXIDMgPeKMnOKXi+KGlSAyICAjIEEgcmFuay0yIGFycmF5IHRvIGFkZApjICsgeCAgICAgICAgICAgICAgICAgIyAwLWNlbGxzIHBhaXJlZCB3aXRoIDEtY2VsbHMKeCArIHggICAgICAgICAgICAgICAgICMgUGFpcndpc2UgYWRkaXRpb24=">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>x</span> <span class='Gets'>←</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>4</span> <span class='Function'>⥊</span> <span class='Function'>↕</span><span class='Number'>60</span> <span class='Comment'># A rank-3 array
</span>┌─
@@ -200,7 +200,7 @@
</pre>
<p>If one argument is a unit, that is, it has no axes, then leading axis agreement reduces to APL's &quot;scalar extension&quot; (where &quot;scalar&quot; is equivalent to BQN's &quot;unit&quot;), where a single unit is matched with an entire array by repeating it at every application. A unit always agrees with any other array under leading axis agreement because it has no axes whose lengths would need to be checked.</p>
<p>With leading axis agreement, there are <code><span class='Value'>k</span><span class='Function'>+</span><span class='Number'>1</span></code> shapes for arrays that can be added (or any other function with Each) to a given array <code><span class='Value'>x</span></code> without changing its rank. These are precisely the prefixes of <code><span class='Function'>≢</span><span class='Value'>x</span></code>, with ranks from <code><span class='Number'>0</span></code> to <code><span class='Value'>k</span></code> inclusive. Arrays with larger rank can also be used as the other argument, but then the result shape will match that argument and not <code><span class='Value'>x</span></code>.</p>
-<h3 id="search-functions">Search functions</h3>
+<h3 id="search-functions"><a class="header" href="#search-functions">Search functions</a></h3>
<p>The <a href="search.html">search functions</a>, Index of (<code><span class='Function'>⊐</span></code>), Progressive Index of (<code><span class='Function'>⊒</span></code>), and Member of (<code><span class='Function'>∊</span></code>), and also <a href="order.html#bins">Bins</a> (<code><span class='Function'>⍋⍒</span></code>), look through cells of one argument to find cells of the other. Find (<code><span class='Function'>⍷</span></code>) also does a search, but a slightly different one: it tries to find <em>slices</em> of cells of <code><span class='Value'>𝕩</span></code> that match <code><span class='Value'>𝕨</span></code>.</p>
<table>
<thead>
diff --git a/docs/doc/lexical.html b/docs/doc/lexical.html
index 2ce2cfc9..ec3f6567 100644
--- a/docs/doc/lexical.html
+++ b/docs/doc/lexical.html
@@ -4,10 +4,10 @@
<title>BQN: Lexical scoping</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="lexical-scoping">Lexical scoping</h1>
+<h1 id="lexical-scoping"><a class="header" href="#lexical-scoping">Lexical scoping</a></h1>
<p>BQN uses lexical scope, like most modern functional programming languages including Javascript, Scheme, and Julia, and like Dyalog APL's dfns (tradfns are dynamically scoped). This document describes how lexical scoping works, and a few small details relevant to BQN's version of it.</p>
<p>In short, every <a href="block.html">block</a> is a separate scope that can refer to identifiers in containing scopes. When evaluated, the block makes a variable for each identifier defined in it (including arguments and operands). The blocks that it contains will now access these variables. In the first level of a block, variables must be defined before they can be used, but in child blocks, a variable can be used regardless of where it's defined, as long as the definition is evaluated before the child block is.</p>
-<h2 id="scopes">Scopes</h2>
+<h2 id="scopes"><a class="header" href="#scopes">Scopes</a></h2>
<p>Scoping is a mechanism that allows the same variable name to refer to different variables depending on program context. For example, the following code uses the name <code><span class='Value'>a</span></code> in two ways: once for a value at the top level, and once locally in a function. With scoping, once you write <code><span class='Brace'>{}</span></code> to create a block, you can define any name you want inside without worrying whether it's taken.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=YSDihpAgNgpGIOKGkCB7IGEgw5cgMSArIGEg4oaQIPCdlakgfQoKRiA0ICAgICMgU2V0cyBh4oaQNCBpbnRlcm5hbGx5CmEgICAgICAjIFRoZSBvdXRlciBhIGlzIHVuY2hhbmdlZA==">↗️</a><pre> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='Number'>6</span>
<span class='Function'>F</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Value'>a</span> <span class='Function'>×</span> <span class='Number'>1</span> <span class='Function'>+</span> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='Value'>𝕩</span> <span class='Brace'>}</span>
@@ -35,7 +35,7 @@
</pre>
<p>Each call creates the <a href="range.html">list of indices</a> <code><span class='Value'>i</span></code>, then calls itself using <code><span class='Function'>𝕊</span></code> on each element of <code><span class='Value'>𝕩</span></code> <a href="repeat.html">if</a> it's a list, then <a href="couple.html">couples</a> <code><span class='Value'>i</span></code> to the result. This requires <code><span class='Value'>i</span></code> to be unaffected by other calls to the function, which works because <code><span class='Value'>i</span></code> is scoped not only to the source code location but also to the particular evaluation of the block that creates it.</p>
<p>These examples probably work like you expect—they're meant to highlight the features that scoping should have, in order to help show how less intuitive cases work later on.</p>
-<h2 id="visibility">Visibility</h2>
+<h2 id="visibility"><a class="header" href="#visibility">Visibility</a></h2>
<p>A scope can view and modify (with <code><span class='Gets'>↩</span></code>) variables in other scopes that contain it. We say these variables are visible in the inner scopes. Variables at the top level of a program are visible to all the code in that program, so that we might call them &quot;global&quot;. That would be a little misleading though, because for example each file is an entire program, so if one file is imported from another then it can't read the first file's variables.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Y291bnRlciDihpAgMAppbmMg4oaQIDYKQ291bnQg4oaQIHsgY291bnRlciAr4oapIPCdlakgw5cgaW5jIH0KCkNvdW50IDAKQ291bnQgMQpDb3VudCAxCkNvdW50IDU=">↗️</a><pre> <span class='Value'>counter</span> <span class='Gets'>←</span> <span class='Number'>0</span>
<span class='Value'>inc</span> <span class='Gets'>←</span> <span class='Number'>6</span>
@@ -77,7 +77,7 @@ ERROR
</span>42
</pre>
<p>The function <code><span class='Function'>C3_7</span></code> uses the versions of <code><span class='Value'>counter</span></code> and <code><span class='Value'>inc</span></code> created in <code><span class='Modifier'>_makeCount</span></code>, even though it's called not from inside <code><span class='Modifier'>_makeCount</span></code>, but from the top-level program. This is what it means for BQN's scoping to be lexical rather than dynamic. Which identifiers are visible is determined by where the code containing them is located in the source code, not how it's called at runtime. The static nature of lexical scoping makes it much easier to keep track of how variables are used (for compilers, this means optimization opportunities), and for this reason dynamic scoping is very rare in programming languages today.</p>
-<h3 id="post-definition">Post-definition</h3>
+<h3 id="post-definition"><a class="header" href="#post-definition">Post-definition</a></h3>
<p>In the top level a block, a variable can only be used after it's defined, and the compiler rejects any code that tries to use an undefined variable. But blocks contained in that block see variables it defines regardless of the positioning. Below, <code><span class='Function'>PlusC</span></code> references the variable <code><span class='Value'>c</span></code> that's defined after it (but when code is executed one line at a time like it is here, I still have to put both definitions on the same line so they are compiled together).</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=UGx1c0Mg4oaQIHsg8J2VqStjIH0g4ouEIGPihpDCrzEKUGx1c0MgNw==">↗️</a><pre> <span class='Function'>PlusC</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Value'>𝕩</span><span class='Function'>+</span><span class='Value'>c</span> <span class='Brace'>}</span> <span class='Separator'>⋄</span> <span class='Value'>c</span><span class='Gets'>←</span><span class='Number'>¯1</span>
<span class='Function'>PlusC</span> <span class='Number'>7</span>
@@ -88,7 +88,7 @@ ERROR
ERROR
</pre>
<p>Why define things this way? It's easier to see if you imagine the variable used is also a function. It's normal for a function to call other functions defined at the top level, of course. And it would be pretty unpleasant for BQN to enforce a specific ordering for them. It would also make recursive functions impossible except by using <code><span class='Function'>𝕊</span></code>, and mutually recursive ones completely impossible. A simple rule that makes all these things just work smoothly seems much better than any alternative.</p>
-<h2 id="closures">Closures</h2>
+<h2 id="closures"><a class="header" href="#closures">Closures</a></h2>
<p>Let's run <code><span class='Modifier'>_makeCount</span></code> from above a few more times.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=QzRfMiDihpAgNOKAvzIgX21ha2VDb3VudCAgIyBTdGFydCBhdCA0OyBpbmNyZW1lbnQgYnkgMgpDMV80IOKGkCAx4oC/NCBfbWFrZUNvdW50ICAjICAgICAgICAgIDE7ICAgICAgICAgICAgICA0CgpDNF8yIDAKQzFfNCAwCkM0XzIgMTAKQzFfNCAxMApDNF8yIDAKQzNfNyAwICAjIFRoZSBmaXJzdCBvbmUncyBzdGlsbCBhcm91bmQgdG9v">↗️</a><pre> <span class='Function'>C4_2</span> <span class='Gets'>←</span> <span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>2</span> <span class='Modifier'>_makeCount</span> <span class='Comment'># Start at 4; increment by 2
</span> <span class='Function'>C1_4</span> <span class='Gets'>←</span> <span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>4</span> <span class='Modifier'>_makeCount</span> <span class='Comment'># 1; 4
@@ -121,12 +121,12 @@ ERROR
</pre>
<p>The variable <code><span class='Function'>Mean</span></code> is visible only within the outer immediate block. The only way it can be accessed is by code in this block: the two calls in the returned function, which will later be renamed <code><span class='Value'>stdDev</span></code>. Nothing in the block modifies it, so its value is constant. It's just a little utility that exists only for code in the block. Making it visible elsewhere is as simple as moving it out of the block, but it's best not to do this without reason. Keeping a variable in the smallest possible scope makes it easier to understand the program, because it reduces the amount of information needed to understand scopes where that variable doesn't apply.</p>
<p>Neither the specification nor a typical implementation keep track of what is and isn't a closure, although an advanced interpreter will probably work with some related properties. The existence of closures is an ordinary feature of lexical scoping and not a special case. However, it's sometimes a useful term for discussing the operation of a program. We might define a closure as a block that can be run and access variables from a parent scope even after the block that created that scope finishes execution.</p>
-<h3 id="environments-form-a-tree">Environments form a tree</h3>
+<h3 id="environments-form-a-tree"><a class="header" href="#environments-form-a-tree">Environments form a tree</a></h3>
<p>So a block has access to every environment that it might need a variable from, for as long as it needs. This idea is a little fuzzy, so let's clarify by describing how an implementation would support figure out what can access where.</p>
<p>The mechanism is that each environment can have a <em>parent</em> environment (the topmost environment, which corresponds to the entire program, has no parent). When a variable is accessed, it might be in the current environment, or its parent, or that environment's parent, and so on. Every environment corresponds to one block in the source code, and its parent corresponds to the parent block, so a compiler can figure out how many levels up it will have to go based on the source code.</p>
<p>We've seen that one block can create many environments. An environment can have only one parent, but many children, so environments form a tree. A forest to be precise, as one execution of BQN can involve multiple programs.</p>
<p>How does an environment know which of the many environments corresponding to the parent scope is its parent? This information is saved when the block is reached in the program and a <em>block instance</em> is created. Unless it's an immediate block, the block instance won't be run right away: a block instance isn't the same as a block evaluation. But each block evaluation starts with a block instance, and that's where it gets the parent environment. Unlike block evaluation, which can happen anywhere, a block instance is created only during evaluation of the parent block. So the saved parent environment is simply the current environment.</p>
-<h2 id="mutation">Mutation</h2>
+<h2 id="mutation"><a class="header" href="#mutation">Mutation</a></h2>
<p>The value of a variable can be modified with <code><span class='Gets'>↩</span></code>. It's similar to definition <code><span class='Gets'>←</span></code> in that it sets the value of the variable, but the way it interacts with scoping is completely different. Defining creates a new variable in the current scope, and modifying refers to an existing variable in the current scope or a parent. In scoping terms, modifying is more like an ordinary variable reference than a definition.</p>
<p>When a variable's modified, functions with access to it see the new value. They have access to the variable, not any particular value that it has.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ZmFjdG9yIOKGkCAzCk11bCDihpAgeyBmYWN0b3Igw5cg8J2VqSB9CgpNdWwgNgpmYWN0b3Ig4oapIDUKTXVsIDYgICAjIEEgbmV3IHJlc3VsdA==">↗️</a><pre> <span class='Value'>factor</span> <span class='Gets'>←</span> <span class='Number'>3</span>
diff --git a/docs/doc/logic.html b/docs/doc/logic.html
index 2635814c..8fc23c44 100644
--- a/docs/doc/logic.html
+++ b/docs/doc/logic.html
@@ -4,12 +4,12 @@
<title>BQN Logic functions: And, Or, Not (also Span)</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="logic-functions-and-or-not-also-span">Logic functions: And, Or, Not (also Span)</h1>
+<h1 id="logic-functions-and-or-not-also-span"><a class="header" href="#logic-functions-and-or-not-also-span">Logic functions: And, Or, Not (also Span)</a></h1>
<p>BQN retains the APL symbols <code><span class='Function'>∧</span></code> and <code><span class='Function'>∨</span></code> for logical <em>and</em> and <em>or</em>, and changed APL's <code><span class='Value'>~</span></code> to <code><span class='Function'>¬</span></code> for <em>not</em>, since <code><span class='Value'>~</span></code> looks too much like <code><span class='Modifier'>˜</span></code> and <code><span class='Function'>¬</span></code> is more common in mathematics today. Like J, BQN extends Not to the linear function <code><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>-</span></code>. However, it discards <a href="https://aplwiki.com/wiki/GCD">GCD</a> and <a href="https://aplwiki.com/wiki/LCM">LCM</a> as extensions of And and Or, and instead uses bilinear extensions: And is identical to Times (<code><span class='Function'>×</span></code>), while Or is <code><span class='Function'>×</span><span class='Modifier2'>⌾</span><span class='Function'>¬</span></code>, following De Morgan's laws (other ways of obtaining a function for Or give an equivalent result—there is only one bilinear extension).</p>
<p>If the arguments are probabilities of independent events, then an extended function gives the probability of the boolean function on their outcomes (for example, if <em>A</em> occurs with probability <code><span class='Value'>a</span></code> and <em>B</em> with probability <code><span class='Value'>b</span></code> independent of <em>A</em>, then <em>A</em> or <em>B</em> occurs with probability <code><span class='Value'>a</span><span class='Function'>∨</span><span class='Value'>b</span></code>). These extensions have also been used in complexity theory, because they allow mathematicians to transfer a logical circuit from the discrete to the continuous domain in order to use calculus on it.</p>
<p>Both valences of <code><span class='Function'>¬</span></code> are equivalent to the fork <code><span class='Number'>1</span><span class='Function'>+-</span></code>. The dyadic valence, called &quot;Span&quot;, computes the number of integers in the range from <code><span class='Value'>𝕩</span></code> to <code><span class='Value'>𝕨</span></code>, inclusive, when both arguments are integers and <code><span class='Value'>𝕩</span><span class='Function'>≤</span><span class='Value'>𝕨</span></code> (note the reversed order, which is used for consistency with subtraction). This function has many uses, and in particular is relevant to the <a href="windows.html">Windows</a> function.</p>
<p>These functions are considered <a href="arithmetic.html">arithmetic</a> functions and thus are <a href="arithmetic.html#pervasion">pervasive</a>.</p>
-<h2 id="definitions">Definitions</h2>
+<h2 id="definitions"><a class="header" href="#definitions">Definitions</a></h2>
<p>We define:</p>
<pre><span class='Function'>Not</span> <span class='Gets'>←</span> <span class='Number'>1</span><span class='Function'>+-</span> <span class='Comment'># also Span
</span><span class='Function'>And</span> <span class='Gets'>←</span> <span class='Function'>×</span>
@@ -18,7 +18,7 @@
<p>Note that <code><span class='Function'>¬</span><span class='Modifier'>⁼</span> <span class='Gets'>←→</span> <span class='Function'>¬</span></code>, since when applying <code><span class='Function'>¬</span></code> twice the first added 1 will be negated but the second won't; the two 1s cancel leaving two subtractions, and <code><span class='Function'>-</span><span class='Modifier'>⁼</span> <span class='Gets'>←→</span> <span class='Function'>-</span></code>. An alternate definition of Or that matches the typical formula from probability theory is</p>
<pre><span class='Function'>Or</span> <span class='Gets'>←</span> <span class='Function'>+-×</span>
</pre>
-<h2 id="examples">Examples</h2>
+<h2 id="examples"><a class="header" href="#examples">Examples</a></h2>
<p>We can form truth <a href="map.html#table">tables</a> including the non-integer value one-half:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=wqwgMOKAvzAuNeKAvzEKCuKIp+KMnMucIDDigL8wLjXigL8xCgriiKjijJzLnCAw4oC/MC414oC/MQ==">↗️</a><pre> <span class='Function'>¬</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0.5</span><span class='Ligature'>‿</span><span class='Number'>1</span>
⟨ 1 0.5 0 ⟩
@@ -38,10 +38,10 @@
</pre>
<p>As with logical And and Or, any value and 0 is 0, while any value or 1 is 1. The other boolean values give the identity values for the two functions: 1 and any value gives that value, as does 0 or the value.</p>
-<h2 id="why-not-gcd-and-lcm">Why not GCD and LCM?</h2>
+<h2 id="why-not-gcd-and-lcm"><a class="header" href="#why-not-gcd-and-lcm">Why not GCD and LCM?</a></h2>
<p>The main reason for omitting these functions is that they are complicated and, when applied to real or complex numbers, require a significant number of design decisions where there is no obvious choice (for example, whether to use comparison tolerance). On the other hand, these functions are fairly easy to implement, which allows the programmer to control the details, and also add functionality such as the extended GCD.</p>
<p>A secondary reason is that the GCD falls short as an extension of Or, because its identity value 0 is not total. <code><span class='Number'>0</span><span class='Function'>∨</span><span class='Value'>x</span></code>, for a real number <code><span class='Value'>x</span></code>, is actually equal to <code><span class='Function'>|</span><span class='Value'>x</span></code> and not <code><span class='Value'>x</span></code>: for example, <code><span class='Number'>0</span><span class='Function'>∨</span><span class='Number'>¯2</span></code> is <code><span class='Number'>2</span></code> in APL. This means the identity <code><span class='Number'>0</span><span class='Function'>∨</span><span class='Value'>x</span> <span class='Gets'>←→</span> <span class='Value'>x</span></code> isn't reliable in APL.</p>
-<h2 id="identity-values">Identity values</h2>
+<h2 id="identity-values"><a class="header" href="#identity-values">Identity values</a></h2>
<p>It's common to apply a <a href="fold.html">fold</a> <code><span class='Function'>∧</span><span class='Modifier'>´</span></code> or <code><span class='Function'>∨</span><span class='Modifier'>´</span></code> to a list (checking whether all elements are true and whether any are true, respectively), and so it's important for extensions to And and Or to share their <a href="fold.html#identity-values">identity</a> value. <a href="arithmetic.html#additional-arithmetic">Minimum and Maximum</a> do match And and Or when restricted to booleans, but they have different identity values. It would be dangerous to use Maximum to check whether any element of a list is true because <code><span class='Function'>⌈</span><span class='Modifier'>´</span><span class='Bracket'>⟨⟩</span></code> yields <code><span class='Number'>¯∞</span></code> instead of <code><span class='Number'>0</span></code>—a bug waiting to happen. To avoid this the programmer would have to use an initial value <code><span class='Value'>𝕨</span></code> of <code><span class='Number'>0</span></code>, which is easy to forget.</p>
<p>It's not hard to prove that the bilinear extensions have the identity values we want. Of course <code><span class='Number'>1</span><span class='Function'>∧</span><span class='Value'>x</span></code> is <code><span class='Number'>1</span><span class='Function'>×</span><span class='Value'>x</span></code>, or <code><span class='Value'>x</span></code>, and <code><span class='Number'>0</span><span class='Function'>∨</span><span class='Value'>x</span></code> is <code><span class='Number'>0</span><span class='Function'>×</span><span class='Modifier2'>⌾</span><span class='Function'>¬</span><span class='Value'>x</span></code>, or <code><span class='Function'>¬</span><span class='Number'>1</span><span class='Function'>׬</span><span class='Value'>x</span></code>, giving <code><span class='Function'>¬¬</span><span class='Value'>x</span></code> or <code><span class='Value'>x</span></code> again. Both functions are commutative, so these values are identities on the right as well.</p>
<p>Other logical identities do not necessarily hold. For example, in boolean logic And distributes over Or and vice-versa: <code><span class='Value'>a</span><span class='Function'>∧</span><span class='Value'>b</span><span class='Function'>∨</span><span class='Value'>c</span> <span class='Gets'>←→</span> <span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>∧</span><span class='Value'>b</span><span class='Paren'>)</span><span class='Function'>∨</span><span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>∧</span><span class='Value'>c</span><span class='Paren'>)</span></code>. But substituting <code><span class='Function'>×</span></code> for <code><span class='Function'>∧</span></code> and <code><span class='Function'>+-×</span></code> for <code><span class='Function'>∨</span></code> we find that the left hand side is <code><span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>×</span><span class='Value'>b</span><span class='Paren'>)</span><span class='Function'>+</span><span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>×</span><span class='Value'>c</span><span class='Paren'>)</span><span class='Function'>+</span><span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>×</span><span class='Value'>b</span><span class='Function'>×</span><span class='Value'>c</span><span class='Paren'>)</span></code> while the right gives <code><span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>×</span><span class='Value'>b</span><span class='Paren'>)</span><span class='Function'>+</span><span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>×</span><span class='Value'>c</span><span class='Paren'>)</span><span class='Function'>+</span><span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>×</span><span class='Value'>b</span><span class='Function'>×</span><span class='Value'>a</span><span class='Function'>×</span><span class='Value'>c</span><span class='Paren'>)</span></code>. These are equivalent for arbitrary <code><span class='Value'>b</span></code> and <code><span class='Value'>c</span></code> only if <code><span class='Value'>a</span><span class='Function'>=</span><span class='Value'>a</span><span class='Function'>×</span><span class='Value'>a</span></code>, that is, <code><span class='Value'>a</span></code> is 0 or 1. In terms of probabilities the difference when <code><span class='Value'>a</span></code> is not boolean is caused by failure of independence. On the left hand side, the two arguments of every logical function are independent. On the right hand side, each pair of arguments to <code><span class='Function'>∧</span></code> are independent, but the two arguments to <code><span class='Function'>∨</span></code>, <code><span class='Value'>a</span><span class='Function'>∧</span><span class='Value'>b</span></code> and <code><span class='Value'>a</span><span class='Function'>∧</span><span class='Value'>c</span></code>, are not. The relationship between these arguments means that logical equivalences no longer apply.</p>
diff --git a/docs/doc/map.html b/docs/doc/map.html
index 91c27caf..b7c4afe5 100644
--- a/docs/doc/map.html
+++ b/docs/doc/map.html
@@ -4,10 +4,10 @@
<title>BQN: Mapping modifiers</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="mapping-modifiers">Mapping modifiers</h1>
+<h1 id="mapping-modifiers"><a class="header" href="#mapping-modifiers">Mapping modifiers</a></h1>
<p>Mapping a function over an array means to call it on each element of that array, creating an array of results. It's also possible to map over two arrays, applying the function to various choices of one element from each, but there's no longer a single correct way to iterate over these elements.</p>
<p>BQN has two 1-modifiers to map over arrays: Each (<code><span class='Modifier'>¨</span></code>) and Table (<code><span class='Modifier'>⌜</span></code>). On two arguments, Table applies its operand to all combinations of elements while Each creates a one-to-one or one-to-many matching. Since they apply to elements, these modifiers are different from Cells (<code><span class='Modifier'>˘</span></code>) or its generalization Rank (<code><span class='Modifier2'>⎉</span></code>), which apply the function to array cells. The modifier <a href="depth.html#the-depth-modifier">Depth</a> (<code><span class='Modifier2'>⚇</span></code>) is a generalization of Each, so that <code><span class='Modifier'>¨</span></code> is <code><span class='Modifier2'>⚇</span><span class='Number'>¯1</span></code>; however, it can't be used to implement Table without some additional array operations.</p>
-<h2 id="one-argument-mapping">One-argument mapping</h2>
+<h2 id="one-argument-mapping"><a class="header" href="#one-argument-mapping">One-argument mapping</a></h2>
<svg viewBox='-224 -21.6 680 187.2'>
<g fill='currentColor' font-family='BQN,monospace'>
<rect class='code' stroke-width='1.5' rx='12' x='-184' y='0' width='600' height='158.4'/>
@@ -66,7 +66,7 @@
"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>
-<h2 id="table">Table</h2>
+<h2 id="table"><a class="header" href="#table">Table</a></h2>
<svg viewBox='-206.4 -21.6 696 345.6'>
<g fill='currentColor' font-family='BQN,monospace'>
<rect class='code' stroke-width='1.5' rx='12' x='-126.4' y='0' width='536' height='316.8'/>
@@ -158,7 +158,7 @@
⟨ 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>
-<h2 id="each">Each</h2>
+<h2 id="each"><a class="header" href="#each">Each</a></h2>
<svg viewBox='-224 -21.6 680 259.2'>
<defs>
<linearGradient id='gr' gradientUnits='userSpaceOnUse' x1='0' x2='0' y1='14.4' y2='216'>
diff --git a/docs/doc/match.html b/docs/doc/match.html
index 74fc83a3..b162bd3b 100644
--- a/docs/doc/match.html
+++ b/docs/doc/match.html
@@ -4,7 +4,7 @@
<title>BQN: Match</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="match">Match</h1>
+<h1 id="match"><a class="header" href="#match">Match</a></h1>
<p>The primitive Match (<code><span class='Function'>≡</span></code>) tests whether its two argument arrays are considered equivalent in BQN, returning <code><span class='Number'>1</span></code> if so and <code><span class='Number'>0</span></code> otherwise. Not Match (<code><span class='Function'>≢</span></code>) is the opposite, returning <code><span class='Number'>1</span></code> if the two arrays aren't equivalent and <code><span class='Number'>0</span></code> if they are.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ImFiYyIg4omhICdhJ+KAvydiJ+KAvydjJwo0IOKJoiA8NA==">↗️</a><pre> <span class='String'>&quot;abc&quot;</span> <span class='Function'>≡</span> <span class='String'>'a'</span><span class='Ligature'>‿</span><span class='String'>'b'</span><span class='Ligature'>‿</span><span class='String'>'c'</span>
1
@@ -24,7 +24,7 @@
</pre>
<p>Match compares arrays based on their fundamental properties—<a href="shape.html">shape</a> and elements—and not the <a href="fill.html">fill element</a>, which is an inferred property. Since it can be computed differently in different implementations, using the fill element in Match could lead to some confusing results. Even if the implementation doesn't define a fill for <code><span class='String'>'a'</span><span class='Ligature'>‿</span><span class='String'>'b'</span><span class='Ligature'>‿</span><span class='String'>'c'</span></code>, it should still be considered to match <code><span class='String'>&quot;abc&quot;</span></code>.</p>
<p>To give a precise definition, two arrays are considered to match if they have the same shape and all corresponding elements from the two arrays match. Every array has a finite <a href="depth.html">depth</a> so this recursive definition always ends up comparing non-arrays, or atoms. An array never matches an atom, so the result if only one argument is an atom is <code><span class='Number'>0</span></code>. The interesting case is when both arguments are atoms, discussed below.</p>
-<h2 id="atomic-equality">Atomic equality</h2>
+<h2 id="atomic-equality"><a class="header" href="#atomic-equality">Atomic equality</a></h2>
<p>Atoms in BQN have six possible <a href="types.html">types</a>: number, character, function, 1-modifier, 2-modifier, and namespace. Equality is not allowed to fail for any two arguments, so it needs to be defined on all of these types.</p>
<p>Starting with the easiest rules, values with different types are never equal to each other.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oJ2EnLCArLCAz4p+pID0g4p+oLeKfnMK7LCAnKycsIDPLmeKfqQ==">↗️</a><pre> <span class='Bracket'>⟨</span><span class='String'>'a'</span><span class='Separator'>,</span> <span class='Function'>+</span><span class='Separator'>,</span> <span class='Number'>3</span><span class='Bracket'>⟩</span> <span class='Function'>=</span> <span class='Bracket'>⟨</span><span class='Function'>-</span><span class='Modifier2'>⟜</span><span class='Function'>»</span><span class='Separator'>,</span> <span class='String'>'+'</span><span class='Separator'>,</span> <span class='Number'>3</span><span class='Modifier'>˙</span><span class='Bracket'>⟩</span>
@@ -54,7 +54,7 @@
⟨ 1 ⟩
</pre>
<p>This approach can't tell you whether two functions are mathematically different—that is, whether they ever return different results given the same arguments (this is an undecidable problem, and also gets confusing since &quot;different&quot; is included in its own definition). However, if two functions compare equal, then they will always return the same results.</p>
-<h3 id="block-equality">Block equality</h3>
+<h3 id="block-equality"><a class="header" href="#block-equality">Block equality</a></h3>
<p>The final point above about block instances is subtler. An instance of a block function or modifier is mutable, meaning that its behavior can change over the course of a program. Consider the following two functions:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=RuKAv0cg4oaQIHsgYeKGkDEwIOKLhCB7YSvwnZWpfeKAv3th4oap8J2VqX0gfQoKRiA1ICAgIyBPbmUgcmVzdWx0CkcgOApGIDUgICAjIEFub3RoZXIgcmVzdWx04oCUdGhlIGRlZmluaXRpb24gb2YgaW5zYW5pdHkh">↗️</a><pre> <span class='Function'>F</span><span class='Ligature'>‿</span><span class='Function'>G</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Value'>a</span><span class='Gets'>←</span><span class='Number'>10</span> <span class='Separator'>⋄</span> <span class='Brace'>{</span><span class='Value'>a</span><span class='Function'>+</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Ligature'>‿</span><span class='Brace'>{</span><span class='Value'>a</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Brace'>}</span> <span class='Brace'>}</span>
⟨ *function* *function* ⟩
diff --git a/docs/doc/namespace.html b/docs/doc/namespace.html
index 667e323d..a0c06d75 100644
--- a/docs/doc/namespace.html
+++ b/docs/doc/namespace.html
@@ -4,7 +4,7 @@
<title>BQN: Namespaces</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="namespaces">Namespaces</h1>
+<h1 id="namespaces"><a class="header" href="#namespaces">Namespaces</a></h1>
<p>A namespace is a type of value that groups together several values (fields) from the same scope. A block or file returns a namespace if it contains any export arrows <code><span class='Gets'>⇐</span></code> at the top level, and fields from namespaces can be accessed with either dot syntax or destructuring assignment. A namespace can be mutable only if any of the code in it uses <code><span class='Gets'>↩</span></code> to change the value of a field.</p>
<p>The following quick example shows a few ways to use a namespace returned by <code><span class='Function'>•Import</span></code>:</p>
<pre><span class='Value'>ns</span> <span class='Gets'>←</span> <span class='Function'>•Import</span> <span class='String'>&quot;file.bqn&quot;</span>
@@ -17,12 +17,12 @@
</span><span class='Modifier'>_something</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>𝕗</span><span class='Brace'>}</span> <span class='Comment'># Separate definition
</span><span class='Function'>DoThing</span> <span class='Gets'>←</span> <span class='String'>&quot;TODO&quot;</span><span class='Modifier2'>⊸</span><span class='Function'>!</span>
</pre>
-<h2 id="uses">Uses</h2>
+<h2 id="uses"><a class="header" href="#uses">Uses</a></h2>
<p>The features of namespaces that make them useful in BQN programming are encapsulation and mutability. But these are exactly the same features that <a href="lexical.html#closures">closures</a> provide! In fact a namespace is not much more than a closure with a name lookup system. Consequently namespaces don't really expand the basic functionality of the language, but just make it easier to use.</p>
<p>Namespaces improve encapsulation by allowing many values to be exported at once. With only one way to call them, functions and modifiers aren't such a good way to define a large part of a program. With a namespace you can define lots of things and expose exactly the ones you want to the rest of the world. For example, it's typical for files to define namespaces. A reader can see the exported values just by searching for <code><span class='Gets'>⇐</span></code>, and if you're nice, you might declare them all at the beginning of the file. Careful use of exports can guarantee that potentially dangerous functions are used correctly: if it's only valid to call function <code><span class='Function'>B</span></code> after function <code><span class='Function'>A</span></code> has been called, export <code><span class='Function'>AB</span><span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Function'>A</span><span class='Value'>𝕩</span><span class='Separator'>⋄</span><span class='Function'>B</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> and don't export <code><span class='Function'>B</span></code>.</p>
<p>Mutability means that the behavior of one namespace can change over the course of the program. Mutability is often a liability, so make sure you really need it before leaning too heavily on this property. While there's no way to tell from the outside that a particular namespace is mutable, you can tell it isn't if the source code doesn't contain <code><span class='Gets'>↩</span></code>, as this is the only way it can modify the variables it contains.</p>
<p>A namespace that makes use of mutability is essentially an object: a collection of state along with operations that act on it. <a href="oop.html">Object-oriented programming</a> is the other major use of namespaces. Contrary to the name, there's never a need to orient your programming around objects, and it's perfectly fine to use an object here or there when you need to, for instance to build a mutable queue of values.</p>
-<h2 id="exports">Exports</h2>
+<h2 id="exports"><a class="header" href="#exports">Exports</a></h2>
<p>The double arrow <code><span class='Gets'>⇐</span></code> is used to export variables from a block or file, making the result a namespace instead of the result of the last line. There are two ways to export variables. First, <code><span class='Gets'>←</span></code> in the variable definition can be replaced with <code><span class='Gets'>⇐</span></code> to export the variable as it's defined. Second, an export statement consisting of an assignment target followed by <code><span class='Gets'>⇐</span></code>, with nothing to the right, exports the variables in the target and does nothing else. These export statements can be placed anywhere in the relevant program or body, including before declaration or on the last line, and a given variable can be exported any number of times. The block in the example below has two statements that export variables, exporting <code><span class='Value'>a</span></code>, <code><span class='Value'>b</span></code>, and <code><span class='Value'>c</span></code>.</p>
<pre><span class='Value'>example</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='Value'>b</span><span class='Ligature'>‿</span><span class='Value'>c</span><span class='Gets'>⇐</span> <span class='Comment'># Non-definition exports can go anywhere
@@ -31,7 +31,7 @@
<span class='Value'>c</span><span class='Gets'>←</span><span class='Value'>b</span><span class='Ligature'>‿</span><span class='String'>&quot;str&quot;</span>
<span class='Brace'>}</span>
</pre>
-<h2 id="imports">Imports</h2>
+<h2 id="imports"><a class="header" href="#imports">Imports</a></h2>
<p>There are also two ways to get values out of a namespace, such as <code><span class='Value'>example</span></code> defined above. First, it might be used in a destructuring assignment like the one below. This assignment's target looks like a list, where each entry specifies one of the names exported by the block and what it should be assigned to. The element can be either a single name, like <code><span class='Value'>b</span></code>, which gives both, or an aliasing expression like <code><span class='Value'>b2</span><span class='Gets'>⇐</span><span class='Value'>b</span></code>. In this case, the value <code><span class='Value'>b</span></code> from the namespace is used, but it's given the name <code><span class='Value'>b2</span></code> instead of <code><span class='Value'>b</span></code>. Imported names can be repeated—but the variables defined can't—and all the names can be spelled with any role (the role is ignored).</p>
<pre><span class='Bracket'>⟨</span><span class='Value'>alias</span><span class='Gets'>⇐</span><span class='Value'>a</span><span class='Separator'>,</span> <span class='Value'>b</span><span class='Separator'>,</span> <span class='Value'>c0</span><span class='Ligature'>‿</span><span class='Value'>c1</span><span class='Gets'>⇐</span><span class='Value'>c</span><span class='Separator'>,</span> <span class='Value'>b2</span><span class='Gets'>⇐</span><span class='Value'>b</span><span class='Bracket'>⟩</span> <span class='Gets'>←</span> <span class='Value'>example</span>
</pre>
diff --git a/docs/doc/oop.html b/docs/doc/oop.html
index 916a4eef..ce3afd66 100644
--- a/docs/doc/oop.html
+++ b/docs/doc/oop.html
@@ -4,7 +4,7 @@
<title>Object-oriented programming in BQN</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="object-oriented-programming-in-bqn">Object-oriented programming in BQN</h1>
+<h1 id="object-oriented-programming-in-bqn"><a class="header" href="#object-oriented-programming-in-bqn">Object-oriented programming in BQN</a></h1>
<p>BQN's <a href="namespace.html">namespaces</a> can be used to support a simple form of <a href="https://en.wikipedia.org/wiki/Object-oriented_programming">object-oriented programming</a> (OOP) without type checking or inheritance. It's suitable for some program architectures but not others: making OOP work as a solution to every problem isn't a BQN design goal. In fact, BQN was never designed to support OOP at all! I added namespaces or modules as a way to structure programs. The techniques we're going to discuss are all just ways to use namespaces, and if it ever starts seeming like confusing magic it might help to go back to this model. However, thinking of namespaces as objects can be quite powerful in the right circumstances, and on this page I'm going to frame things in OOP terms. The following table shows which well-known aspects of OOP are supported in BQN:</p>
<table>
<thead>
@@ -64,7 +64,7 @@
</tr>
</tbody>
</table>
-<h2 id="objects">Objects</h2>
+<h2 id="objects"><a class="header" href="#objects">Objects</a></h2>
<p>An object in BQN is simply a namespace: its fields and methods are variables in the namespace, and one of these can be accessed outside of the namespace with dot syntax if it's exported with <code><span class='Gets'>⇐</span></code>. Unexported variables are instance-private in OOP parlance, meaning that only they're only visible to the object containing them. They could be utilities, or hold state for the object. As an example, the object below implements the <a href="https://en.wikipedia.org/wiki/Tower_of_Hanoi">Tower of Hanoi</a> puzzle with five disks. You can view the state (a list of disks occupying each of the three rods) with <code><span class='Value'>towerOfHanoi.</span><span class='Function'>View</span></code>, or move the top disk from one rod to another with <code><span class='Value'>towerOfHanoi.</span><span class='Function'>Move</span></code>.</p>
<pre><span class='Value'>towerOfHanoi</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='Value'>l</span> <span class='Gets'>←</span> <span class='Function'>↕</span><span class='Modifier'>¨</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span>
@@ -100,7 +100,7 @@
<span class='Value'>t.</span><span class='Function'>Move</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span>
<span class='Bracket'>⟨</span> <span class='Bracket'>⟨</span> <span class='Number'>2</span> <span class='Number'>3</span> <span class='Number'>4</span> <span class='Bracket'>⟩</span> <span class='Bracket'>⟨</span> <span class='Number'>0</span> <span class='Number'>1</span> <span class='Bracket'>⟩</span> <span class='Bracket'>⟨⟩</span> <span class='Bracket'>⟩</span>
</pre>
-<h2 id="classes">Classes</h2>
+<h2 id="classes"><a class="header" href="#classes">Classes</a></h2>
<p>The object above is a singleton: there's just one of it, at least in the scope it occupies. It's often more useful to have a class that can be used to create objects. What we'll call a &quot;class&quot; is a namespace function, that is, a function that contains <code><span class='Gets'>⇐</span></code> and so returns a namespace. It's very easy to convert a singleton object to a class: just add a no-op <code><span class='Value'>𝕤</span></code> line to force it to be a function, and call it with <code><span class='String'>@</span></code> when needed.</p>
<pre><span class='Function'>MakeStack</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>𝕤</span>
<span class='Value'>st</span><span class='Gets'>←</span><span class='String'>@</span>
@@ -117,7 +117,7 @@
<span class='Brace'>}</span>
</pre>
<p>A stack is a particularly simple class to make because its state can be represented efficiently as a BQN value. Other data structures don't allow this, and will often require an extra <code><span class='Function'>Node</span></code> class when they are implemented—see <code><span class='Function'>MakeQueue</span></code> below.</p>
-<h2 id="mutability">Mutability</h2>
+<h2 id="mutability"><a class="header" href="#mutability">Mutability</a></h2>
<p>An object is one way to transform <em>variable mutation</em> <code><span class='Gets'>↩</span></code> into <em>mutable data</em>. These are two different concepts: <code><span class='Gets'>↩</span></code> changes which value is attached to a <em>name</em> in a scope, while mutable data means that the behavior of a particular <em>value</em> can change. But if a value is linked to a scope (for an object, the scope that contains its fields), then variable mutation in that scope can change the value's behavior. In fact, in BQN this is the only way to create mutable data. Which doesn't mean it's rare: functions, modifiers, and namespaces are all potentially mutable. The difference between objects and the operations is just a matter of syntax. Mutability in operations can only be observed by calling them. For instance <code><span class='Function'>F</span> <span class='Number'>10</span></code> or <code><span class='Function'>-</span><span class='Modifier'>_m</span></code> could return a different result even if the variables involved don't change value. Mutability in an object can only be observed by accessing a member, meaning that <code><span class='Value'>obj.field</span></code> or <code><span class='Bracket'>⟨</span><span class='Value'>field</span><span class='Bracket'>⟩</span><span class='Gets'>←</span><span class='Value'>obj</span></code> can yield different values over the course of a program even if <code><span class='Value'>obj</span></code> is still the same object.</p>
<p>Let's look at how mutability plays out in an example class for a single-ended queue. This queue works by linking new nodes to the tail <code><span class='Value'>t</span></code> of the queue, and detaching nodes from the head <code><span class='Value'>h</span></code> when requested (a detached node will still point to <code><span class='Value'>h</span></code>, but nothing in the queue points to <em>it</em>, so it's unreachable and will eventually be garbage collected). Each node has some data <code><span class='Value'>v</span></code> and a single node reference <code><span class='Value'>n</span></code> directed tailwards; in a double-ended queue or more complicated structure it would have more references. You can find every mutable variable in the queue by searching for <code><span class='Gets'>↩</span></code>, which shows that <code><span class='Value'>t</span></code> and <code><span class='Value'>h</span></code> in the queue, and <code><span class='Value'>n</span></code> in a node, may be mutated. It's impossible for the other variables to change value once they're assigned.</p>
<pre><span class='Function'>MakeQueue</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>𝕤</span>
@@ -128,7 +128,7 @@
<span class='Brace'>}</span>
</pre>
<p>Unlike a stack, a node's successor isn't known when it's created, and it has to be set. You might be inclined to make <code><span class='Value'>n</span></code> settable directly, but we'll get more mileage out of a setter function <code><span class='Function'>SetN</span></code>. This allows us to create a pseudo-node <code><span class='Value'>e</span></code> (for &quot;empty&quot;) indicating there are no values in the queue. Because it has no <code><span class='Value'>.v</span></code> field, if <code><span class='Value'>h</span></code> is <code><span class='Value'>e</span></code> then <code><span class='Function'>Pop</span></code> gives an error (but in a real implementation you'd want to test explicitly instead in order to give an appropriate error message). In fact it doesn't have an <code><span class='Value'>n</span></code> field, and essentially uses the queue head <code><span class='Value'>h</span></code> instead. With this empty &quot;node&quot;, the queue definition is straightforward. The only tricky part to remember is that if <code><span class='Function'>Pop</span></code> removes the last node, resulting in <code><span class='Value'>e</span><span class='Function'>=</span><span class='Value'>h</span></code>, then the tail has to be set to <code><span class='Value'>e</span></code> as well, or it will keep pointing to the removed node and cause bugs.</p>
-<h2 id="composition">Composition</h2>
+<h2 id="composition"><a class="header" href="#composition">Composition</a></h2>
<p>BQN classes don't support inheritance because there's no way to extend an existing class with new fields. But a lot of OOP enthusiasts these days are promoting <a href="https://en.wikipedia.org/wiki/Composition_over_inheritance">composition over inheritance</a>, and here BQN does pretty well. Forwarding methods from another class is as simple as a multiple assignment, like <code><span class='Bracket'>⟨</span><span class='Function'>View</span><span class='Bracket'>⟩</span></code> below (in a real program <code><span class='Value'>undoableTowerOfHanoi</span></code> should almost certainly be a class, but I introduced <code><span class='Value'>towerOfHanoi</span></code> before classes, and I'm not about to write it again just to add an <code><span class='Value'>𝕤</span></code>).</p>
<pre><span class='Value'>undoableTowerOfHanoi</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='Function'>Push</span><span class='Ligature'>‿</span><span class='Function'>Pop</span> <span class='Gets'>←</span> <span class='Function'>MakeStack</span><span class='String'>@</span> <span class='Comment'># Copy methods as private
@@ -139,7 +139,7 @@
</pre>
<p>This class composes a Tower of Hanoi with an undo stack that stores previous moves. To undo a move from <code><span class='Value'>a</span></code> to <code><span class='Value'>b</span></code>, it moves from <code><span class='Value'>b</span></code> to <code><span class='Value'>a</span></code>, although if you felt really fancy you might define <code><span class='Function'>Move</span><span class='Modifier'>⁼</span></code> in <code><span class='Value'>towerOfHanoi</span></code> instead with <code><span class='Function'>𝕊</span><span class='Modifier'>⁼</span><span class='Value'>𝕩:</span> <span class='Function'>𝕊⌽</span><span class='Value'>𝕩</span></code>.</p>
<p>It's also possible to copy several variables and only export some of them, with an export statement. For example, if I wasn't going to make another method called <code><span class='Function'>Move</span></code>, I might have written <code><span class='Function'>View</span><span class='Ligature'>‿</span><span class='Function'>Move</span> <span class='Gets'>←</span> <span class='Value'>towerOfHanoi</span></code> and then <code><span class='Function'>View</span><span class='Gets'>⇐</span></code>. In fact, depending on your personal style and how complicated your classes are, you might prefer to avoid inline <code><span class='Gets'>⇐</span></code> exports entirely, and declare all the exports at the top.</p>
-<h2 id="self-reference">Self-reference</h2>
+<h2 id="self-reference"><a class="header" href="#self-reference">Self-reference</a></h2>
<p>An object's class is given by <code><span class='Function'>𝕊</span></code>. Remember, a class is an ordinary BQN function! It might be useful for an object to produce another object of the same class (particularly if it's immutable), and an object might also expose a field <code><span class='Value'>class</span><span class='Gets'>⇐</span><span class='Value'>𝕤</span></code> to test whether an object <code><span class='Value'>o</span></code> belongs to a class <code><span class='Value'>c</span></code> with <code><span class='Value'>o.class</span> <span class='Function'>=</span> <span class='Value'>c</span></code>.</p>
<p>It's not currently possible for an object to know its own value without some outside help, such as a special constructor:</p>
<pre><span class='Function'>IntrospectiveClass</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
@@ -151,7 +151,7 @@
<span class='Brace'>}</span>
</pre>
<p>This is a pretty clunky solution, and exports a useless method <code><span class='Function'>SetThis</span></code> (which gives an error if it's ever called). It would be possible for BQN to define a system value <code><span class='Value'>•this</span></code> that just gets the namespace's value. It would work only at the top level, so it would have to be assigned (<code><span class='Value'>this</span><span class='Gets'>←</span><span class='Value'>•this</span></code>) in order to use it in functions. This means it's always used before the namespace is done being defined, so a drawback is that it introduces the possibility that an object used in a program has undefined fields. The reason this isn't possible for objects without <code><span class='Value'>•this</span></code> is that BQN's blocks don't have any sort of control flow, so that they always execute every statement in order. The namespace becomes accessible as a value once the block finishes, and at this point every statement has been executed and every field is initialized.</p>
-<h2 id="class-members">Class members</h2>
+<h2 id="class-members"><a class="header" href="#class-members">Class members</a></h2>
<p>As with <code><span class='Value'>this</span></code>, giving a class variables that belong to it is a do-it-yourself sort of thing (or more positively, not at all magic (funny how programmer jargon goes the opposite way to ordinary English)). It's an easy one though, as this is exactly what <a href="lexical.html">lexical scoping</a> does:</p>
<pre><span class='Value'>staticClass</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='Value'>counter</span> <span class='Gets'>←</span> <span class='Number'>0</span>
diff --git a/docs/doc/order.html b/docs/doc/order.html
index 1737ebd1..bd13f64a 100644
--- a/docs/doc/order.html
+++ b/docs/doc/order.html
@@ -4,7 +4,7 @@
<title>BQN: Ordering functions</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="ordering-functions">Ordering functions</h1>
+<h1 id="ordering-functions"><a class="header" href="#ordering-functions">Ordering functions</a></h1>
<p>BQN has six functions that order arrays as part of their operation (the <a href="arithmetic.html#comparisons">comparison functions</a> <code><span class='Function'>≤&lt;&gt;≥</span></code> only order atoms, so they aren't included). These come in three pairs, where one of each pair uses an ascending ordering and the other uses a descending ordering.</p>
<ul>
<li><code><span class='Function'>∨∧</span></code>, Sort, rearranges the argument to order it</li>
@@ -13,7 +13,7 @@
</ul>
<p>The array ordering shared by all six is described last. For lists it's &quot;dictionary ordering&quot;: two lists are compared one element at a time until one runs out, and the shorter one comes first in case of a tie. Operation values aren't ordered, so if an argument to an ordering function has a function or modifier somewhere in it then it will fail unless all the orderings can be decided without checking that value.</p>
<p>You can't provide a custom ordering function to Sort. The function would have to be called on one pair of cells at a time, which is contrary to the idea of array programming, and passing in a function with side effects could lead to implementation-specific behavior. Instead, build another array that will sort in the order you want (for example, by selecting or deriving the property you want to sort on). Then Grade it, and use the result to select from the original array.</p>
-<h2 id="sort">Sort</h2>
+<h2 id="sort"><a class="header" href="#sort">Sort</a></h2>
<p>You've probably seen it before. Sort Up (<code><span class='Function'>∧</span></code>) reorders the major cells of its argument to place them in ascending order, and Sort Down (<code><span class='Function'>∨</span></code>) puts them in descending order. Every ordering function follows this naming convention—there's an &quot;Up&quot; version pointing up and a &quot;Down&quot; version going the other way.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oinICJkZWx0YSLigL8iYWxwaGEi4oC/ImJldGEi4oC/ImdhbW1hIgoK4oioICLOtM6xzrLOsyI=">↗️</a><pre> <span class='Function'>∧</span> <span class='String'>&quot;delta&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;alpha&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;beta&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;gamma&quot;</span>
⟨ "alpha" "beta" "delta" "gamma" ⟩
@@ -22,7 +22,7 @@
"δγβα"
</pre>
<p>Sort Down always <a href="match.html">matches</a> Sort Up <a href="reverse.html">reversed</a>, <code><span class='Function'>⌽</span><span class='Modifier2'>∘</span><span class='Function'>∧</span></code>. The reason for this is that BQN's array ordering is a <a href="https://en.wikipedia.org/wiki/Total_order">total order</a>, meaning that if one array doesn't come earlier or later that another array in the ordering then the two arrays match. Since any two non-matching argument cells are strictly ordered, they will have one ordering in <code><span class='Function'>∧</span></code> and the opposite ordering in <code><span class='Function'>∨</span></code>. With the reverse, any pair of non-matching cells are ordered the same way in <code><span class='Function'>⌽</span><span class='Modifier2'>∘</span><span class='Function'>∧</span></code> and <code><span class='Function'>∨</span></code>. Since these two results have the same major cells in the same order, they match. However, note that the results will not always behave identically because Match doesn't take <a href="fill.html">fill elements</a> into account (if you're curious, take a look at <code><span class='Function'>⊑</span><span class='Modifier'>¨</span><span class='Function'>∨</span><span class='Bracket'>⟨</span><span class='Function'>↕</span><span class='Number'>0</span><span class='Separator'>,</span><span class='String'>&quot;&quot;</span><span class='Bracket'>⟩</span></code> versus <code><span class='Function'>⊑</span><span class='Modifier'>¨</span><span class='Function'>⌽</span><span class='Modifier2'>∘</span><span class='Function'>∧</span><span class='Bracket'>⟨</span><span class='Function'>↕</span><span class='Number'>0</span><span class='Separator'>,</span><span class='String'>&quot;&quot;</span><span class='Bracket'>⟩</span></code>).</p>
-<h2 id="grade">Grade</h2>
+<h2 id="grade"><a class="header" href="#grade">Grade</a></h2>
<p><em>See the <a href="https://aplwiki.com/wiki/Grade">APL Wiki page</a> for a few more examples. BQN only has the monadic form.</em></p>
<p>Grade is more abstract than Sort. Rather than rearranging the argument's cells immediately, it returns a list of indices (more precisely, a permutation) giving the ordering that would sort them.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGwg4oaQICJwbGFuZXQi4oC/Im1vb24i4oC/InN0YXIi4oC/ImFzdGVyb2lkIgoK4oinIGwKCuKNiyBs">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>l</span> <span class='Gets'>←</span> <span class='String'>&quot;planet&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;moon&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;star&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;asteroid&quot;</span>
@@ -38,7 +38,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKNi2wpIOKKjyBs">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>⍋</span><span class='Value'>l</span><span class='Paren'>)</span> <span class='Function'>⊏</span> <span class='Value'>l</span>
⟨ "asteroid" "moon" "planet" "star" ⟩
</pre>
-<h3 id="ordinals">Ordinals</h3>
+<h3 id="ordinals"><a class="header" href="#ordinals">Ordinals</a></h3>
<p>So the elements of the Grade of an array correspond to the cells of that array after it's sorted. It's tempting if you don't have the sorted list handy to try to match them up with major cells of the original array, but this never makes sense—there's no relationship. However, applying Grade <em>twice</em> gives us a list that does correspond to the original argument quite usefully: it says, for each major cell of that argument, what rank it has relative to the others (smallest is 0, next is 1, and so on, breaking ties in favor of which cell comes earlier in the argument). Experienced APL programmers call this pattern the &quot;ordinals&quot; idiom.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=bCDiiY0g4o2L4o2LIGw=">↗️</a><pre> <span class='Value'>l</span> <span class='Function'>≍</span> <span class='Function'>⍋⍋</span> <span class='Value'>l</span>
┌─
@@ -49,7 +49,7 @@
<p>How does it work? First, let's note that <code><span class='Function'>⍋</span><span class='Value'>l</span></code> is a <em>permutation</em>: it contains exactly the numbers <code><span class='Function'>↕≠</span><span class='Value'>l</span></code>, possibly in a different order. In other words, <code><span class='Function'>∧⍋</span><span class='Value'>l</span></code> is <code><span class='Function'>↕≠</span><span class='Value'>l</span></code>. Permuting an array rearranges the cells but doesn't remove or duplicate any. This implies it's always invertible: given a permutation <code><span class='Value'>p</span></code>, some other permutation <code><span class='Value'>q</span></code> will have <code><span class='Value'>𝕩</span> <span class='Function'>≡</span> <span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> for every <code><span class='Value'>𝕩</span></code> of the right length. This would mean that while <code><span class='Function'>⍋</span><span class='Value'>l</span></code> transforms <code><span class='Value'>l</span></code> to <code><span class='Function'>∧</span><span class='Value'>l</span></code>, the inverse of <code><span class='Function'>⍋</span><span class='Value'>l</span></code> transforms <code><span class='Function'>∧</span><span class='Value'>l</span></code> back into <code><span class='Value'>l</span></code>. That's what we want: for each cell of <code><span class='Value'>l</span></code>, the corresponding number in the inverse of <code><span class='Function'>⍋</span><span class='Value'>l</span></code> is what index that cell has after sorting.</p>
<p>But what's the inverse <code><span class='Value'>q</span></code> of a permutation <code><span class='Value'>p</span></code>? Our requirement is that <code><span class='Value'>𝕩</span> <span class='Function'>≡</span> <span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> for any <code><span class='Value'>𝕩</span></code> with the same length as <code><span class='Value'>p</span></code>. Setting <code><span class='Value'>𝕩</span></code> to <code><span class='Function'>↕≠</span><span class='Value'>p</span></code> (the identity permutation), we have <code><span class='Paren'>(</span><span class='Function'>↕≠</span><span class='Value'>p</span><span class='Paren'>)</span> <span class='Function'>≡</span> <span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span></code>, because <code><span class='Value'>p</span><span class='Function'>⊏↕≠</span><span class='Value'>p</span></code> is just <code><span class='Value'>p</span></code>. But if <code><span class='Value'>p</span></code> is a permutation then <code><span class='Function'>∧</span><span class='Value'>p</span></code> is <code><span class='Function'>↕≠</span><span class='Value'>p</span></code>, so our requirement could also be written <code><span class='Paren'>(</span><span class='Function'>∧</span><span class='Value'>p</span><span class='Paren'>)</span> <span class='Function'>≡</span> <span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span></code>. Now it's all coming back around again. We know exactly how to get <code><span class='Value'>q</span></code>! Defining <code><span class='Value'>q</span><span class='Gets'>←</span><span class='Function'>⍋</span><span class='Value'>p</span></code>, we have <code><span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span> <span class='Value'>↔</span> <span class='Paren'>(</span><span class='Function'>⍋</span><span class='Value'>p</span><span class='Paren'>)</span><span class='Function'>⊏</span><span class='Value'>p</span> <span class='Value'>↔</span> <span class='Function'>∧</span><span class='Value'>p</span> <span class='Value'>↔</span> <span class='Function'>↕≠</span><span class='Value'>p</span></code>, and <code><span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span><span class='Function'>⊏</span><span class='Value'>𝕩</span> <span class='Value'>↔</span> <span class='Paren'>(</span><span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span><span class='Paren'>)</span><span class='Function'>⊏</span><span class='Value'>𝕩</span> <span class='Value'>↔</span> <span class='Paren'>(</span><span class='Function'>↕≠</span><span class='Value'>p</span><span class='Paren'>)</span><span class='Function'>⊏</span><span class='Value'>𝕩</span> <span class='Value'>↔</span> <span class='Value'>𝕩</span></code>.</p>
<p>The fact that Grade Up inverts a permutation is useful in itself. Note that this applies to Grade Up specifically, and not Grade Down. This is because the identity permutation is ordered in ascending order. Grade Down would actually invert the reverse of a permutation, which is unlikely to be useful. So the ordinals idiom that goes in the opposite direction is actually not <code><span class='Function'>⍒⍒</span></code> but <code><span class='Function'>⍋⍒</span></code>. The initial grade is different, but the way to invert it is the same.</p>
-<h3 id="stability">Stability</h3>
+<h3 id="stability"><a class="header" href="#stability">Stability</a></h3>
<p>When sorting an array, we usually don't care how matching cells are ordered relative to each other (although it's possible to detect it by using fill elements carefully. They maintain their ordering). Grading is a different matter, because often the grade of one array is used to order another one.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIHQg4oaQID7in6ggImRvZyLigL80LCAiYW50IuKAvzYsICJwaWdlb24i4oC/MiwgInBpZyLigL80IOKfqQoKMSDiio/LmCB0CgooMeKKj8uYdCkg4o2L4oq44oqPIHQ=">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>t</span> <span class='Gets'>←</span> <span class='Function'>&gt;</span><span class='Bracket'>⟨</span> <span class='String'>&quot;dog&quot;</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Separator'>,</span> <span class='String'>&quot;ant&quot;</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Separator'>,</span> <span class='String'>&quot;pigeon&quot;</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Separator'>,</span> <span class='String'>&quot;pig&quot;</span><span class='Ligature'>‿</span><span class='Number'>4</span> <span class='Bracket'>⟩</span>
┌─
@@ -83,7 +83,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKMveKNki8z4oC/NOKAvzUpIOKKjyAiMDEyYWJjZEFCQ0RFIg==">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>⌽⍒/</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>5</span><span class='Paren'>)</span> <span class='Function'>⊏</span> <span class='String'>&quot;012abcdABCDE&quot;</span>
"210dcbaEDCBA"
</pre>
-<h2 id="bins">Bins</h2>
+<h2 id="bins"><a class="header" href="#bins">Bins</a></h2>
<p><em>There's also an <a href="https://aplwiki.com/wiki/Interval_Index">APL Wiki page</a> on this function, but be careful as the Dyalog version has subtle differences.</em></p>
<p>The two Bins functions are written with the same symbols <code><span class='Function'>⍋</span></code> and <code><span class='Function'>⍒</span></code> as Grade, but take two arguments instead of one. More complicated? A little, but once you understand Bins you'll find that it's a basic concept that shows up in the real world all the time.</p>
<p>Bins behaves like a <a href="search.html">search function</a> with respect to rank: it looks up cells from <code><span class='Value'>𝕩</span></code> relative to major cells of <code><span class='Value'>𝕨</span></code>. However, there's an extra requirement: the left argument to Bins is already sorted according to whichever ordering is used. If it isn't, you'll get an error.</p>
@@ -100,7 +100,7 @@ ERROR
⟨ 3 5 0 1 ⟩
</pre>
<p>A score of <code><span class='Number'>565e7</span></code> sits between <code><span class='Number'>578e7</span></code> and <code><span class='Number'>553e7</span></code> at rank 3, <code><span class='Number'>322e7</span></code> wouldn't make the list, <code><span class='Number'>788e7</span></code> would beat everyone, and <code><span class='Number'>627e7</span></code> would tie the high score but not beat it. The same principles apply to less spring-loaded things like character indices and line numbers (<code><span class='Value'>𝕨</span></code> is the index of the start of each line), or percentage scores and letter grades on a test (<code><span class='Value'>𝕨</span></code> is the minimum score possible for each grade). In each case, it's better to think of Bins not as a counting exercise but as finding &quot;what bin&quot; something fits into.</p>
-<h2 id="array-ordering">Array ordering</h2>
+<h2 id="array-ordering"><a class="header" href="#array-ordering">Array ordering</a></h2>
<p>Most of the time you won't need to worry about the details of how BQN arrays are ordered. It's documented here because, well, that's what documentation does.</p>
<p>The array ordering defines some arrays to be smaller or larger than others. All of the &quot;Up&quot; ordering functions use this ordering directly, so that smaller arrays come earlier, and the &quot;Down&quot; ones use the opposite ordering, with larger arrays coming earlier. For arrays consisting only of characters and numbers, with arbitrary nesting, the ordering is always defined. If an array contains an operation, trying to order it relative to another array might give an error. If comparing two arrays succeeds, there are three possibilities: the first array is smaller, the second is smaller, or the two arrays <a href="match.html">match</a>.</p>
<p>Comparing two atoms is defined to work the same way as the <a href="arithmetic.html#comparisons">comparison functions</a> <code><span class='Function'>≤&lt;&gt;≥</span></code>. Numbers come earlier than characters and otherwise these two types are ordered in the obvious way. To compare an atom to an array, the atom enclosing and then compared with the array ordering defined below. The result of this comparison is used except when the two arrays match: in that case, the atom is considered smaller.</p>
diff --git a/docs/doc/paradigms.html b/docs/doc/paradigms.html
index 73fe750c..a0305aa9 100644
--- a/docs/doc/paradigms.html
+++ b/docs/doc/paradigms.html
@@ -4,15 +4,15 @@
<title>BQN in programming paradigms</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="bqn-in-programming-paradigms">BQN in programming paradigms</h1>
+<h1 id="bqn-in-programming-paradigms"><a class="header" href="#bqn-in-programming-paradigms">BQN in programming paradigms</a></h1>
<p>It hangs onto weakly positive connotations somehow, but the term &quot;multi-paradigm&quot; shouldn't impress you. Let's dig into exactly which paradigms BQN supports and how.</p>
<p>This information doesn't tell you what tasks BQN is good for: after all, it turns out you can write an efficient compiler entirely using array programming, something many people assumed was impossible. Instead, it tells you what approaches you can take to writing programs, and how comfortable you'll find it to start using BQN—or how much you can use it to stretch your brain in new directions.</p>
<p>When programming in BQN, I almost always use array, tacit, and (slightly impure) functional styles, and encapsulate code in medium or large projects using namespaces. I sometimes use object-oriented or imperative programming in addition to these.</p>
-<h2 id="typing">Typing</h2>
+<h2 id="typing"><a class="header" href="#typing">Typing</a></h2>
<p>BQN is a <strong>dynamically typed</strong> language with a coarse <a href="types.html">type system</a> that only distinguishes types when the difference is blindingly obvious. There is a single numeric type and a single unicode character type. A fast implementation such as CBQN will check to see when it can represent the data with a smaller type than the one offered by the language. BQN usually avoids implicit type conversion, with the exception that many primitives automatically convert atoms to unit arrays. The fact that a data value can be applied as a function to return itself could also be considered an implicit conversion.</p>
<p>BQN has no &quot;pointer&quot; or &quot;reference&quot; type, and uses <strong>automatic memory management</strong>. Its data types are <strong>immutable</strong> while operations and namespaces are mutable; mutable data can create reference loops, which the implementation must account for in garbage collection but the programmer doesn't have to worry about.</p>
<p>Dynamic types and garbage collection introduce overhead relative to a statically-typed or manually managed language. The impact of this overhead can be greatly reduced with array programming, because an array of numbers or characters can be stored as a single unit of memory and processed with functions specialized to its element type.</p>
-<h2 id="styles">Styles</h2>
+<h2 id="styles"><a class="header" href="#styles">Styles</a></h2>
<p>BQN is designed for <strong>array</strong> programming. The array is its only built-in collection type and it has many primitives designed to work with arrays.</p>
<p>BQN is okay for <strong>imperative</strong> programming. Blocks are lists of statements. Variables can be modified with <code><span class='Gets'>↩</span></code>, and while there are no truly global variables, <a href="lexical.html">lexical scoping</a> allows variables at the top level of a file, which are similar (<code><span class='Function'>•Import</span></code> with no left argument saves and reuses results, so that data can be shared between files by loading the same namespace-defining file in each). BQN doesn't directly support <strong>structured</strong> programming (which refers to a particular way to structure programs; it also doesn't have a Goto statement, the &quot;unstructured&quot; alternative when the term was coined). However, its first-class functions allow a reasonably similar <a href="control.html">imitation</a> of control structures.</p>
<p><strong>Functional</strong> programming is a term with many meanings. Using the terms defined in the <a href="functional.html">functional programming document</a>, BQN supports first-class functions and function-level programming, allows but doesn't encourage pure functional programming, and does not support typed functional programming. BQN uses <strong>lexical scope</strong> and has full support for <strong>closures</strong>. In this way BQN is very similar to Lisp, although it lacks Lisp's macro system.</p>
diff --git a/docs/doc/pick.html b/docs/doc/pick.html
index 76f9bfe9..d3166012 100644
--- a/docs/doc/pick.html
+++ b/docs/doc/pick.html
@@ -4,11 +4,11 @@
<title>BQN: Pick</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="pick">Pick</h1>
+<h1 id="pick"><a class="header" href="#pick">Pick</a></h1>
<p>Pick (<code><span class='Function'>⊑</span></code>) chooses elements from <code><span class='Value'>𝕩</span></code> based on <a href="indices.html">index</a> lists from <code><span class='Value'>𝕨</span></code>. <code><span class='Value'>𝕨</span></code> can be a plain list, or even one number if <code><span class='Value'>𝕩</span></code> is a list, in order to get one element from <code><span class='Value'>𝕩</span></code>. It can also be an array of index lists, or have deeper array structure: each index list will be replaced with the element of <code><span class='Value'>𝕩</span></code> at that index, effectively applying to <code><span class='Value'>𝕨</span></code> at <a href="depth.html#the-depth-modifier">depth</a> 1.</p>
<p>With no <code><span class='Value'>𝕨</span></code>, monadic <code><span class='Function'>⊑</span><span class='Value'>𝕩</span></code> takes the first element of <code><span class='Value'>𝕩</span></code> in index order, with an error if <code><span class='Value'>𝕩</span></code> is empty.</p>
<p>While sometimes &quot;scatter-point&quot; indexing is necessary, using Pick to select multiple elements from <code><span class='Value'>𝕩</span></code> is less array-oriented than <a href="select.html">Select</a> (<code><span class='Function'>⊏</span></code>), and probably slower. Consider rearranging your data so that you can select along axes instead of picking out elements.</p>
-<h2 id="one-element">One element</h2>
+<h2 id="one-element"><a class="header" href="#one-element">One element</a></h2>
<p>When the left argument is a number, Pick gets an element from a list:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MiDiipEgMOKAvzHigL8y4oC/M+KAvzQKMiDiipEgImFiYyIKMiDiipEg4p+oQCwgMOKAvzHigL8y4oC/MywgImFiYyLin6k=">↗️</a><pre> <span class='Number'>2</span> <span class='Function'>⊑</span> <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'>3</span><span class='Ligature'>‿</span><span class='Number'>4</span>
2
@@ -46,7 +46,7 @@
<span class='Bracket'>⟨⟩</span> <span class='Function'>⊑</span> <span class='String'>'a'</span>
'a'
</pre>
-<h3 id="first">First</h3>
+<h3 id="first"><a class="header" href="#first">First</a></h3>
<p>With no left argument, <code><span class='Function'>⊑</span></code> is called First, and performs a slight generalization of Pick with a default left argument <code><span class='Number'>0</span><span class='Modifier'>¨</span><span class='Function'>≢</span><span class='Value'>𝕩</span></code>. For a non-empty array it returns the first element in index order.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqRIDwnYScK4oqRICJGaXJzdCIK4oqRIOKGlTTigL8y4oC/NeKAvzE=">↗️</a><pre> <span class='Function'>⊑</span> <span class='Function'>&lt;</span><span class='String'>'a'</span>
'a'
@@ -69,7 +69,7 @@ ERROR
<span class='Function'>⊢</span><span class='Modifier'>´</span> <span class='String'>&quot;last&quot;</span>
't'
</pre>
-<h2 id="many-elements">Many elements</h2>
+<h2 id="many-elements"><a class="header" href="#many-elements">Many elements</a></h2>
<p>Pick also accepts a list of indices:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=YSAgIyBEZWZpbmVkIGFib3ZlCgrin6gy4oC/MCwgMeKAv8KvMSwgM+KAvzEsIMKvMeKAv8KvMeKfqSDiipEgYQ==">↗️</a><pre> <span class='Value'>a</span> <span class='Comment'># Defined above
</span>┌─
diff --git a/docs/doc/prefixes.html b/docs/doc/prefixes.html
index 59e94b21..dd27b18c 100644
--- a/docs/doc/prefixes.html
+++ b/docs/doc/prefixes.html
@@ -4,7 +4,7 @@
<title>BQN: Prefixes and Suffixes</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="prefixes-and-suffixes">Prefixes and Suffixes</h1>
+<h1 id="prefixes-and-suffixes"><a class="header" href="#prefixes-and-suffixes">Prefixes and Suffixes</a></h1>
<p>The Prefixes (<code><span class='Function'>↑</span></code>) function gives a list of all prefixes of its argument array along the <a href="leading.html">first axis</a>, and Suffixes (<code><span class='Function'>↓</span></code>) gives a similar list for suffixes. Because the result can be much larger than the argument, these functions may not be used often in high-performance code, but they are a powerful conceptual tool and can make sense for algorithms that are inherently quadratic.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oaRICJhYmNkZSIK4oaTICJhYmNkZSI=">↗️</a><pre> <span class='Function'>↑</span> <span class='String'>&quot;abcde&quot;</span>
⟨ ⟨⟩ "a" "ab" "abc" "abcd" "abcde" ⟩
@@ -26,9 +26,9 @@
⟨ "abcde" "abcde" "abcde" "abcde" "abcde" "abcde" ⟩
</pre>
<p>Joining corresponding elements of <code><span class='Function'>↑</span><span class='Value'>𝕩</span></code> and <code><span class='Function'>↓</span><span class='Value'>𝕩</span></code> gives <code><span class='Value'>𝕩</span></code> again. This is because <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Paren'>(</span><span class='Function'>↑∾</span><span class='Modifier'>¨</span><span class='Function'>↓</span><span class='Paren'>)</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='Paren'>(</span><span class='Value'>i</span><span class='Function'>⊑↓</span><span class='Value'>𝕩</span><span class='Paren'>)</span></code>, or, using the Take and Drop correspondences, <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='Paren'>(</span><span class='Value'>i</span><span class='Function'>↓</span><span class='Value'>𝕩</span><span class='Paren'>)</span></code>, which is <code><span class='Value'>𝕩</span></code>. Element-wise, we are combining the first <code><span class='Value'>i</span></code> cells of <code><span class='Value'>𝕩</span></code> with all but the first <code><span class='Value'>i</span></code>. Looking at the entire result, we now know that <code><span class='Paren'>(</span><span class='Function'>↑∾</span><span class='Modifier'>¨</span><span class='Function'>↓</span><span class='Paren'>)</span><span class='Value'>𝕩</span></code> is <code><span class='Paren'>(</span><span class='Number'>1</span><span class='Function'>+≠</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Function'>⥊&lt;</span><span class='Value'>𝕩</span></code>. The total number of cells in this combined array is therefore <code><span class='Paren'>(</span><span class='Number'>1</span><span class='Function'>+≠</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Function'>×≠</span><span class='Value'>𝕩</span></code>, or <code><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Modifier2'>⊸</span><span class='Function'>×≠</span><span class='Value'>𝕩</span></code>. Each of Prefixes and Suffixes must have the same total number of cells (in fact, <code><span class='Function'>↑</span><span class='Value'>𝕩</span></code> is <code><span class='Function'>⌽</span><span class='Modifier'>¨</span><span class='Modifier2'>∘</span><span class='Function'>↓</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</span><span class='Value'>𝕩</span></code>, and Reverse doesn't change an array's shape). So the total number in either one is <code><span class='Number'>2</span><span class='Function'>÷</span><span class='Modifier'>˜</span><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Modifier2'>⊸</span><span class='Function'>×≠</span><span class='Value'>𝕩</span></code>. With <code><span class='Value'>n</span><span class='Gets'>←</span><span class='Function'>≠</span><span class='Value'>𝕩</span></code>, it is <code><span class='Number'>2</span><span class='Function'>÷</span><span class='Modifier'>˜</span><span class='Value'>n</span><span class='Function'>×</span><span class='Number'>1</span><span class='Function'>+</span><span class='Value'>n</span></code>.</p>
-<h2 id="definition">Definition</h2>
+<h2 id="definition"><a class="header" href="#definition">Definition</a></h2>
<p>Knowing the <a href="shape.html">length</a> and the elements, it's easy to define functions for Prefixes and Suffixes: <code><span class='Function'>↑</span></code> is equivalent to <code><span class='Paren'>(</span><span class='Function'>↕</span><span class='Number'>1</span><span class='Function'>+≠</span><span class='Paren'>)</span><span class='Function'>↑</span><span class='Modifier'>¨</span><span class='Function'>&lt;</span></code> while <code><span class='Function'>↓</span></code> is <code><span class='Paren'>(</span><span class='Function'>↕</span><span class='Number'>1</span><span class='Function'>+≠</span><span class='Paren'>)</span><span class='Function'>↓</span><span class='Modifier'>¨</span><span class='Function'>&lt;</span></code>. Each primitive is defined only on arrays with at least one axis.</p>
-<h2 id="working-with-pairs">Working with pairs</h2>
+<h2 id="working-with-pairs"><a class="header" href="#working-with-pairs">Working with pairs</a></h2>
<p>Sometimes it's useful to apply an operation to every unordered pair of elements from a list. For example, consider all possible products of numbers between 1 and 6:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=w5fijJzLnCAxK+KGlTY=">↗️</a><pre> <span class='Function'>×</span><span class='Modifier'>⌜˜</span> <span class='Number'>1</span><span class='Function'>+↕</span><span class='Number'>6</span>
┌─
@@ -70,7 +70,7 @@
<span class='Paren'>(</span><span class='Function'>&lt;</span><span class='Modifier'>˘</span> <span class='Function'>≍</span><span class='Modifier'>¨¨</span> <span class='Function'>≠</span> <span class='Function'>↑</span> <span class='Function'>↑</span><span class='Paren'>)</span> <span class='String'>&quot;abc&quot;</span>
⟨ ⟨⟩ ⟨ "ba" ⟩ ⟨ "ca" "cb" ⟩ ⟩
</pre>
-<h2 id="slices">Slices</h2>
+<h2 id="slices"><a class="header" href="#slices">Slices</a></h2>
<p>Prefixes and Suffixes give certain restricted slices of the argument array, where a slice is a contiguous selection of cells. If we want all slices along the first axis, we can take the suffixes of each prefix, or vice-versa:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oaTwqjihpEgImFiYyIK4oaRwqjihpMgImFiYyI=">↗️</a><pre> <span class='Function'>↓</span><span class='Modifier'>¨</span><span class='Function'>↑</span> <span class='String'>&quot;abc&quot;</span>
┌─
diff --git a/docs/doc/primitive.html b/docs/doc/primitive.html
index ef7f8d86..ebb09c09 100644
--- a/docs/doc/primitive.html
+++ b/docs/doc/primitive.html
@@ -4,11 +4,11 @@
<title>BQN primitives</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="bqn-primitives">BQN primitives</h1>
+<h1 id="bqn-primitives"><a class="header" href="#bqn-primitives">BQN primitives</a></h1>
<p><em>Primitives</em> are the basic functions and modifiers built into the language, written with individual glyphs (more about the concept <a href="../commentary/primitive.html">here</a>). The role of a primitive when written always matches its type (but you can use its value in other roles by assigning it, or other methods).</p>
<p>Primitives have no side effects other than errors, and can't perform infinite computations, except when a primitive modifier calls an operand function that does one of these things (this can only happen when arguments are passed, as primitive modifiers are always deferred). Side effects here include both writing state such as variables or printed output, and reading any outside state, so that a function without them always returns the same result if passed the same arguments. Since trains and list notation have the same nice properties, tacit code written entirely with primitives, trains, and lists always describes finite, self-contained computations.</p>
<p>Recursion is the primary way to perform potentially infinite computations in BQN, and it can be packaged into <a href="control.html">control structures</a> like <code><span class='Function'>While</span></code> for ease of use. A given BQN implementation might also provide <a href="../spec/system.html">system values</a> for &quot;impure&quot; tasks like file access or other I/O.</p>
-<h2 id="functions">Functions</h2>
+<h2 id="functions"><a class="header" href="#functions">Functions</a></h2>
<p>Functions that have significant differences from APL equivalents or don't appear in APL are marked with an asterisk.</p>
<table>
<thead>
@@ -236,7 +236,7 @@
</tr>
</tbody>
</table>
-<h2 id="modifiers">Modifiers</h2>
+<h2 id="modifiers"><a class="header" href="#modifiers">Modifiers</a></h2>
<svg viewBox='0 0 850 530'>
<g font-size='20px' text-anchor='middle' transform='translate(145,20)'>
<rect class='code' stroke-width='1' rx='12' x='-120.4' y='1' width='240.8' height='205'/>
diff --git a/docs/doc/range.html b/docs/doc/range.html
index 8d73bf0b..6a8409ac 100644
--- a/docs/doc/range.html
+++ b/docs/doc/range.html
@@ -4,7 +4,7 @@
<title>BQN: Range</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="range">Range</h1>
+<h1 id="range"><a class="header" href="#range">Range</a></h1>
<p>Range (<code><span class='Function'>↕</span></code>) is a monadic function that creates arrays of <a href="indices.html">indices</a> (like APL's famous <a href="https://aplwiki.com/wiki/Index_Generator">iota</a> function). Each element in the result is its own index.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oaVIDYKCuKGlSAy4oC/Mw==">↗️</a><pre> <span class='Function'>↕</span> <span class='Number'>6</span>
⟨ 0 1 2 3 4 5 ⟩
@@ -43,7 +43,7 @@
⟨ 3 0 ⟩ ⟨ 3 1 ⟩
</pre>
-<h2 id="number-range">Number range</h2>
+<h2 id="number-range"><a class="header" href="#number-range">Number range</a></h2>
<p>Calling <code><span class='Function'>↕</span></code> on an atom, which must be a natural number, is the more common case. This gives us the list of natural numbers less than <code><span class='Value'>𝕩</span></code> (and starting at <code><span class='Number'>0</span></code>, the first natural number as BQN defines it). You can also get the first <code><span class='Value'>b</span></code> integers starting at <code><span class='Value'>a</span></code> with <code><span class='Value'>a</span><span class='Function'>+↕</span><span class='Value'>b</span></code>, or the natural numbers from <code><span class='Value'>a</span></code> to <code><span class='Value'>b</span></code> with <code><span class='Value'>a</span><span class='Function'>↓↕</span><span class='Value'>b</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oaVNAoKNSArIOKGlTQKCjIg4oaTIOKGlTQ=">↗️</a><pre> <span class='Function'>↕</span><span class='Number'>4</span>
⟨ 0 1 2 3 ⟩
@@ -96,7 +96,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oyIYCBiIMOXIDEgKyDihpXiiaBi">↗️</a><pre> <span class='Function'>⌈</span><span class='Modifier'>`</span> <span class='Value'>b</span> <span class='Function'>×</span> <span class='Number'>1</span> <span class='Function'>+</span> <span class='Function'>↕≠</span><span class='Value'>b</span>
⟨ 0 2 3 3 3 3 7 7 ⟩
</pre>
-<h2 id="list-range">List range</h2>
+<h2 id="list-range"><a class="header" href="#list-range">List range</a></h2>
<p>When the argument is a list of numbers, the result is an array of lists.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oaVIDLigL8z4oC/NA==">↗️</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'>4</span>
┌─
diff --git a/docs/doc/repeat.html b/docs/doc/repeat.html
index aaa68219..b5e4ba06 100644
--- a/docs/doc/repeat.html
+++ b/docs/doc/repeat.html
@@ -4,7 +4,7 @@
<title>BQN: The Repeat modifier</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="the-repeat-modifier">The Repeat modifier</h1>
+<h1 id="the-repeat-modifier"><a class="header" href="#the-repeat-modifier">The Repeat modifier</a></h1>
<p>Repeat (<code><span class='Modifier2'>⍟</span></code>) is a 2-modifier that applies its operand function <code><span class='Function'>𝔽</span></code> multiple times.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=wrvCu8K7ICJBQkNERSIKCsK74o2fMyAiQUJDREUi">↗️</a><pre> <span class='Function'>»»»</span> <span class='String'>&quot;ABCDE&quot;</span>
" AB"
@@ -18,7 +18,7 @@
</pre>
<p><code><span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Number'>0</span></code> repeats <code><span class='Function'>F</span></code> zero times, that is, does nothing. Like <code><span class='Value'>n</span><span class='Function'>⋆</span><span class='Number'>0</span></code> gives the multiplicative identity <code><span class='Number'>1</span></code>, <code><span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Number'>0</span></code> is the compositional <a href="identity.html">identity</a>, <code><span class='Function'>⊢</span></code>. Since <code><span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Number'>1</span></code> applies <code><span class='Function'>F</span></code> and <code><span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Number'>0</span></code> doesn't, Repeat might be pronounced &quot;if&quot; or &quot;conditional&quot; when <code><span class='Function'>𝔾</span></code> is boolean.</p>
<p>BQN's Repeat modifier has some extra functionality relative to the mathematical version. It allows a left argument, and some extensions to the right operand <code><span class='Function'>𝔾</span></code>. As usual for 2-modifiers, <code><span class='Function'>𝔾</span></code> is actually a function that applies to the arguments to give a result. The result can be a natural number as shown above, or a negative number to <a href="undo.html">Undo</a> (<code><span class='Modifier'>⁼</span></code>) <code><span class='Function'>𝔽</span></code>, or an array of values.</p>
-<h2 id="left-argument">Left argument</h2>
+<h2 id="left-argument"><a class="header" href="#left-argument">Left argument</a></h2>
<p>If <code><span class='Value'>𝕨</span></code> is given, it's passed as the left argument to <code><span class='Function'>𝔽</span></code> for every invocation.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyAr4o2fMiA3CjMgKyAzICsgNw==">↗️</a><pre> <span class='Number'>3</span> <span class='Function'>+</span><span class='Modifier2'>⍟</span><span class='Number'>2</span> <span class='Number'>7</span>
13
@@ -26,7 +26,7 @@
13
</pre>
<p>This kind of composition can't be represented by <code><span class='Modifier2'>∘</span></code> anymore (you'd need a <a href="train.html">train</a>), but it's similar in spirit. <code><span class='Value'>𝕨</span> <span class='Function'>𝔽</span><span class='Modifier2'>⍟</span><span class='Value'>n</span> <span class='Value'>𝕩</span></code> is always equivalent to <code><span class='Value'>𝕨</span><span class='Modifier2'>⊸</span><span class='Function'>𝔽</span><span class='Modifier2'>⍟</span><span class='Value'>n</span> <span class='Value'>𝕩</span></code>, provided <code><span class='Value'>n</span></code> is a constant—not a function, as discussed in the next section.</p>
-<h2 id="dynamic-repetition-count">Dynamic repetition count</h2>
+<h2 id="dynamic-repetition-count"><a class="header" href="#dynamic-repetition-count">Dynamic repetition count</a></h2>
<p>In the general case, <code><span class='Function'>𝔾</span></code> is a function, which is applied to all arguments to get the repetition count. That is, the <em>actual</em> count is <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=4oi+4p+cMeKNn+KKoiA0Cgox4oq4K+KNn+KJoCDihpU0">↗️</a><pre> <span class='Function'>∾</span><span class='Modifier2'>⟜</span><span class='Number'>1</span><span class='Modifier2'>⍟</span><span class='Function'>⊢</span> <span class='Number'>4</span>
⟨ 4 1 1 1 1 ⟩
@@ -42,13 +42,13 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyDiiqPijZ88wqggMuKAvzTigL82ICAjIExlZnQgaWYgbGVzcywgaS5lLiBtaW5pbXVt">↗️</a><pre> <span class='Number'>3</span> <span class='Function'>⊣</span><span class='Modifier2'>⍟</span><span class='Function'>&lt;</span><span class='Modifier'>¨</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>6</span> <span class='Comment'># Left if less, i.e. minimum
</span>⟨ 2 3 3 ⟩
</pre>
-<h2 id="negative-repetition">Negative repetition</h2>
+<h2 id="negative-repetition"><a class="header" href="#negative-repetition">Negative repetition</a></h2>
<p>What does it mean to repeat a function a negative number of times? For a negative integer <code><span class='Function'>-</span><span class='Value'>n</span></code>, BQN defines <code><span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Function'>-</span><span class='Value'>n</span><span class='Paren'>)</span></code> to be <code><span class='Function'>F</span><span class='Modifier'>⁼</span><span class='Modifier2'>⍟</span><span class='Value'>n</span></code>. In particular, <code><span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Number'>¯1</span></code> simply undoes <code><span class='Function'>F</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MSDijL3ijZ/CrzEgImFiY2RlIiAgIyBSb3RhdGUgYmFja3dhcmRz">↗️</a><pre> <span class='Number'>1</span> <span class='Function'>⌽</span><span class='Modifier2'>⍟</span><span class='Number'>¯1</span> <span class='String'>&quot;abcde&quot;</span> <span class='Comment'># Rotate backwards
</span>"eabcd"
</pre>
<p>Because BQN's Undo is a little looser than a strict mathematical inverse, this is an extension of the function inverse written f⁻¹ in mathematics. As a result, it doesn't have all the same properties. For natural numbers, Repeat follows the rule that <code><span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Value'>m</span> <span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Value'>n</span> <span class='Value'>𝕩</span></code> is <code><span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Value'>m</span><span class='Function'>+</span><span class='Value'>n</span><span class='Paren'>)</span> <span class='Value'>𝕩</span></code>. For integers, we have <code><span class='Value'>𝕩</span> <span class='Function'>≡</span> <span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Value'>n</span> <span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Function'>-</span><span class='Value'>n</span><span class='Paren'>)</span> <span class='Value'>𝕩</span></code>, but not necessarily <code><span class='Value'>𝕩</span> <span class='Function'>≡</span> <span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Function'>-</span><span class='Value'>n</span><span class='Paren'>)</span> <span class='Function'>F</span><span class='Modifier2'>⍟</span><span class='Value'>n</span> <span class='Value'>𝕩</span></code>.</p>
-<h2 id="array-of-repetition-counts">Array of repetition counts</h2>
+<h2 id="array-of-repetition-counts"><a class="header" href="#array-of-repetition-counts">Array of repetition counts</a></h2>
<p>The value of <code><span class='Value'>𝕨</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span></code> might also be an array, whose elements are any valid repetition values—integers, or other arrays. Each integer in the nested structure is replaced with the result of repeating <code><span class='Function'>𝔽</span></code> that many times.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MuKKuMOX4o2f4p+oMizin6g0LMKvMiwx4p+p4p+pIDE=">↗️</a><pre> <span class='Number'>2</span><span class='Modifier2'>⊸</span><span class='Function'>×</span><span class='Modifier2'>⍟</span><span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Bracket'>⟨</span><span class='Number'>4</span><span class='Separator'>,</span><span class='Number'>¯2</span><span class='Separator'>,</span><span class='Number'>1</span><span class='Bracket'>⟩⟩</span> <span class='Number'>1</span>
⟨ 4 ⟨ 16 0.25 2 ⟩ ⟩
diff --git a/docs/doc/replicate.html b/docs/doc/replicate.html
index 844b67c9..4e8aba5d 100644
--- a/docs/doc/replicate.html
+++ b/docs/doc/replicate.html
@@ -4,7 +4,7 @@
<title>BQN: Indices and Replicate</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="indices-and-replicate">Indices and Replicate</h1>
+<h1 id="indices-and-replicate"><a class="header" href="#indices-and-replicate">Indices and Replicate</a></h1>
<svg viewBox='-134.4 -37.4 595.2 198'>
<g font-family='BQN,monospace' font-size='18px' text-anchor='middle'>
<rect class='code' stroke-width='1.5' rx='12' x='-100.8' y='-28.6' width='528' height='180.4'/>
@@ -87,7 +87,7 @@
<p>The functions Indices and Replicate are used to copy or filter data. They might be described as transforming a <a href="https://en.wikipedia.org/wiki/Run-length_encoding">run-length encoding</a> into unencoded form. On the other hand, Indices might be described as giving a sparse representation of <code><span class='Value'>𝕩</span></code>, which is smaller if <code><span class='Value'>𝕩</span></code> mostly consists of zeros.</p>
<p>BQN doesn't have any of the various features used in APL to add fills to the result of Replicate, like negative numbers in <code><span class='Value'>𝕨</span></code> or an Expand (<code><span class='Value'>\</span></code>) primitive. An alternative to Expand is to use Replicate with structural Under (<code><span class='Modifier2'>⌾</span></code>) to insert values into an array of fills.</p>
-<h2 id="replicate">Replicate</h2>
+<h2 id="replicate"><a class="header" href="#replicate">Replicate</a></h2>
<p>Given a list of natural numbers <code><span class='Value'>𝕨</span></code>, Replicate repeats each major cell in <code><span class='Value'>𝕩</span></code> the corresponding number of times. That is, <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code> must have the same length, and the result includes <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>𝕨</span></code> copies of each cell <code><span class='Value'>i</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code>, in order.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MuKAvzHigL8w4oC/MiAvICJhYmNkIgoK4oqiIGEg4oaQID4iYWEwIuKAvyJiYjEi4oC/ImNjMiLigL8iZGQzIgoKMuKAvzHigL8w4oC/MiAvIGE=">↗️</a><pre> <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='Ligature'>‿</span><span class='Number'>2</span> <span class='Function'>/</span> <span class='String'>&quot;abcd&quot;</span>
"aabdd"
@@ -128,7 +128,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ezErJyInPfCdlal94oq4LyAiZm9yICIiZXNjYXBpbmciIiBxdW90ZXMi">↗️</a><pre> <span class='Brace'>{</span><span class='Number'>1</span><span class='Function'>+</span><span class='String'>'&quot;'</span><span class='Function'>=</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier2'>⊸</span><span class='Function'>/</span> <span class='String'>&quot;for &quot;&quot;escaping&quot;&quot; quotes&quot;</span>
"for """"escaping"""" quotes"
</pre>
-<h3 id="compound-replicate">Compound Replicate</h3>
+<h3 id="compound-replicate"><a class="header" href="#compound-replicate">Compound Replicate</a></h3>
<p>If <code><span class='Value'>𝕨</span></code> has <a href="depth.html">depth</a> two, then its elements give the amounts to copy along each <a href="leading.html">leading axis</a> 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=4oqiIGIg4oaQIDLigL81IOKliiDihpUxMAoK4p+oMuKAvzAsIDHigL8w4oC/MOKAvzHigL8x4p+pIC8gYgoKMuKAvzAgLyAx4oC/MOKAvzDigL8x4oC/MeKKuC/LmCBi">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>b</span> <span class='Gets'>←</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>5</span> <span class='Function'>⥊</span> <span class='Function'>↕</span><span class='Number'>10</span>
┌─
@@ -172,7 +172,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=YiDiiaEg4p+o4p+pIC8gYg==">↗️</a><pre> <span class='Value'>b</span> <span class='Function'>≡</span> <span class='Bracket'>⟨⟩</span> <span class='Function'>/</span> <span class='Value'>b</span>
1
</pre>
-<h2 id="indices">Indices</h2>
+<h2 id="indices"><a class="header" href="#indices">Indices</a></h2>
<p>The monadic form of <code><span class='Function'>/</span></code> is much simpler than the dyadic one, with no multidimensional case or mismatched argument ranks. <code><span class='Value'>𝕩</span></code> must be a list of natural numbers, and <code><span class='Function'>/</span><span class='Value'>𝕩</span></code> is the list <code><span class='Value'>𝕩</span><span class='Function'>/↕≠</span><span class='Value'>𝕩</span></code>. Its elements are the <a href="indices.html">indices</a> for <code><span class='Value'>𝕩</span></code>, with index <code><span class='Value'>i</span></code> repeated <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>𝕩</span></code> times.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=LyAz4oC/MOKAvzHigL8y">↗️</a><pre> <span class='Function'>/</span> <span class='Number'>3</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'>2</span>
⟨ 0 0 0 2 3 3 ⟩
@@ -212,7 +212,7 @@
</pre>
<p>This means the transitions can be grouped exactly in pairs, the beginning and end of each group. Reshape with a <a href="reshape.html#computed-lengths">computed length</a> <code><span class='Modifier2'>∘</span><span class='Ligature'>‿</span><span class='Number'>2</span></code> groups these pairs, and then a scan <code><span class='Function'>-</span><span class='Modifier'>˜`˘</span></code> can be used to convert the start/end format to start/length if wanted.</p>
-<h3 id="inverse">Inverse</h3>
+<h3 id="inverse"><a class="header" href="#inverse">Inverse</a></h3>
<p>The result of Indices <code><span class='Function'>/</span><span class='Value'>n</span></code> is an ordered list of natural numbers, where the number <code><span class='Value'>i</span></code> appears <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>n</span></code> times. Given an ordered list of natural numbers <code><span class='Value'>k</span></code>, the <a href="undo.html"><em>inverse</em></a> of indices returns a corresponding <code><span class='Value'>n</span></code>: one where the value <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>n</span></code> is the number of times <code><span class='Value'>i</span></code> appears in <code><span class='Value'>k</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=LyAz4oC/MuKAvzEKCi/igbwgMOKAvzDigL8w4oC/MeKAvzHigL8y">↗️</a><pre> <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>
⟨ 0 0 0 1 1 2 ⟩
diff --git a/docs/doc/reshape.html b/docs/doc/reshape.html
index 58b7dece..e9523103 100644
--- a/docs/doc/reshape.html
+++ b/docs/doc/reshape.html
@@ -4,7 +4,7 @@
<title>BQN: Deshape and Reshape</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="deshape-and-reshape">Deshape and Reshape</h1>
+<h1 id="deshape-and-reshape"><a class="header" href="#deshape-and-reshape">Deshape and Reshape</a></h1>
<svg viewBox='-64 -15 608 377'>
<g fill='currentColor' stroke-linecap='round' font-family='BQN,monospace'>
<rect class='code' stroke-width='1.5' rx='12' x='0' y='0' width='480' height='347'/>
@@ -60,7 +60,7 @@
<p>The glyph <code><span class='Function'>⥊</span></code> indicates BQN's facilities to reflow the data in an array, giving it a different shape. Its monadic form, Deshape, simply removes all shape information, returning a list of all the elements from the array in reading order. With a left argument, <code><span class='Function'>⥊</span></code> is called Reshape and is a more versatile tool for rearranging the data in an array into the desired shape.</p>
<p>Because of its dependence on the reading order of an array, Reshape is less fundamental than other array operations. Using Reshape in the central computations of a program can be a sign of imperfect usage of arrays. For example, it may be useful to use Reshape to create a constant array or repeat a sequence of values several times, but the same task might also be accomplished more simply with <a href="map.html#table">Table</a> <code><span class='Modifier'>⌜</span></code>, or by taking advantage of <a href="leading.html#leading-axis-agreement">leading axis agreement</a> in arithmetic primitives.</p>
-<h2 id="deshape">Deshape</h2>
+<h2 id="deshape"><a class="header" href="#deshape">Deshape</a></h2>
<p>The result of Deshape is a list containing the same elements as the argument.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGEg4oaQICvijJzCtCDin6gxMDDigL8yMDAsIDMw4oC/NDAsIDXigL824oC/N+KfqQoK4qWKIGE=">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='Function'>+</span><span class='Modifier'>⌜´</span> <span class='Bracket'>⟨</span><span class='Number'>100</span><span class='Ligature'>‿</span><span class='Number'>200</span><span class='Separator'>,</span> <span class='Number'>30</span><span class='Ligature'>‿</span><span class='Number'>40</span><span class='Separator'>,</span> <span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Ligature'>‿</span><span class='Number'>7</span><span class='Bracket'>⟩</span>
┌─
@@ -94,10 +94,10 @@
<span class='Function'>≍</span> <span class='Number'>2</span>
⟨ 2 ⟩
</pre>
-<h2 id="reshape">Reshape</h2>
+<h2 id="reshape"><a class="header" href="#reshape">Reshape</a></h2>
<p>While Deshape removes all shape information from its argument array, Reshape adds shape information back based on the left argument. Reshape ignores the shape of its original argument, treating it like a list of elements as though it were deshaped initially.</p>
<p>The left argument of Reshape gives the shape of the result, except that one entry can be left unspecified for BQN to fill in. We'll look at the cases where a full shape is given first.</p>
-<h3 id="matching-lengths">Matching lengths</h3>
+<h3 id="matching-lengths"><a class="header" href="#matching-lengths">Matching lengths</a></h3>
<p>If the number of elements implied by the given shape—that is, <code><span class='Function'>×</span><span class='Modifier'>´</span><span class='Value'>𝕨</span></code>—is equal to the number of elements in <code><span class='Value'>𝕩</span></code>, then <code><span class='Value'>𝕩</span></code> is simply rearranged to match that shape. The element list is kept the same, so that the deshaped result matches the deshaped right argument.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=YQoKNuKAvzIg4qWKIGEKCijipYphKSDiiaEg4qWKIDbigL8y4qWKYQ==">↗️</a><pre> <span class='Value'>a</span>
┌─
@@ -133,7 +133,7 @@
7 8 9 10 11 12 13
</pre>
-<h3 id="non-matching-lengths">Non-matching lengths</h3>
+<h3 id="non-matching-lengths"><a class="header" href="#non-matching-lengths">Non-matching lengths</a></h3>
<p>If <code><span class='Value'>𝕨</span></code> implies a smaller number of elements than are present initially, then only the initial elements of <code><span class='Value'>𝕩</span></code> are used. Here the result stops at <code><span class='Number'>237</span></code>, three-quarters of the way through <code><span class='Value'>a</span></code>, because at that point the result is filled up.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=M+KAvzMg4qWKIGE=">↗️</a><pre> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>3</span> <span class='Function'>⥊</span> <span class='Value'>a</span>
┌─
@@ -160,7 +160,7 @@ ERROR
<span class='Number'>5</span> <span class='Function'>⥊</span> <span class='Function'>&lt;</span> <span class='String'>&quot;string&quot;</span>
⟨ "string" "string" "string" "string" "string" ⟩
</pre>
-<h3 id="computed-lengths">Computed lengths</h3>
+<h3 id="computed-lengths"><a class="header" href="#computed-lengths">Computed lengths</a></h3>
<p>What if you want to reshape an array into, say, rows of length 2, but don't want to write out the number of rows?</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oiY4oC/MiDipYogImFBZUVpSW9PdVUi">↗️</a><pre> <span class='Modifier2'>∘</span><span class='Ligature'>‿</span><span class='Number'>2</span> <span class='Function'>⥊</span> <span class='String'>&quot;aAeEiIoOuU&quot;</span>
┌─
diff --git a/docs/doc/reverse.html b/docs/doc/reverse.html
index 104a7e44..d1a9ccec 100644
--- a/docs/doc/reverse.html
+++ b/docs/doc/reverse.html
@@ -4,10 +4,10 @@
<title>BQN: Reverse and Rotate</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="reverse-and-rotate">Reverse and Rotate</h1>
+<h1 id="reverse-and-rotate"><a class="header" href="#reverse-and-rotate">Reverse and Rotate</a></h1>
<p>The symbol <code><span class='Function'>⌽</span></code> indicates two different array transformations: with no left argument, it reverses the major cells of the array, but with a left argument, it rotates or cycles them around. These two possibilities, first put together in very early versions of APL, can't be considered restrictions or different views of some unifying function, but there are connections between them. Each returns an array with the same <a href="shape.html">shape</a> and all the same elements as <code><span class='Value'>𝕩</span></code>, possibly in a different arrangement. And elements that start out next to each other in <code><span class='Value'>𝕩</span></code> generally stay next to each other—always, if we consider an element on one edge to be next to the one opposite to it. One might think of them as <a href="https://en.wikipedia.org/wiki/Isometry">isometries</a> preserving a discrete subgroup of the torus, if one were inclined to think such things. On major cells, the two functions decompose the <a href="https://en.wikipedia.org/wiki/Dihedral_group">dihedral group</a> okay I'll stop.</p>
<p>Many uses of Rotate in APL are better handled by <a href="shift.html">shift</a> functions in BQN. If there's no reason to treat the data as cyclic or periodic, it's best to avoid Rotate.</p>
-<h2 id="reverse">Reverse</h2>
+<h2 id="reverse"><a class="header" href="#reverse">Reverse</a></h2>
<p>There's not too much to say about Reverse. It puts the elements of a list the other way around, or more generally the major cells of an array.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oy9ICJhYmNkZWZnIgoK4oy9ID4iYWIi4oC/ImNkIuKAvyJlZiIKCuKMvSAnYyc=">↗️</a><pre> <span class='Function'>⌽</span> <span class='String'>&quot;abcdefg&quot;</span>
"gfedcba"
@@ -45,7 +45,7 @@
<span class='Function'>∨</span><span class='Modifier'>`</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</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'>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'>0</span>
⟨ 1 1 1 1 1 1 0 ⟩
</pre>
-<h2 id="rotate">Rotate</h2>
+<h2 id="rotate"><a class="header" href="#rotate">Rotate</a></h2>
<p>Rotate moves elements in a list around cyclically. It can also rotate any number of axes of the argument array by different amounts at once. That's discussed in the next section; for now we'll stick to a single number for <code><span class='Value'>𝕨</span></code>. It has to be an integer, and <code><span class='Value'>𝕩</span></code> has to be an array with at least one axis.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MiDijL0gInJvdGF0ZSIKCjIgKOKKoiDiiY3il4s8IOKMvSkgNeKAvzLipYoicm90YXRlQ0VMTCIKCjIg4oy9ICdjJyAgIyBObyBheGVzIHRvIHJvdGF0ZQ==">↗️</a><pre> <span class='Number'>2</span> <span class='Function'>⌽</span> <span class='String'>&quot;rotate&quot;</span>
"tatero"
@@ -73,7 +73,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=wq8yIOKMvSAicm90YXRlIg==">↗️</a><pre> <span class='Number'>¯2</span> <span class='Function'>⌽</span> <span class='String'>&quot;rotate&quot;</span>
"terota"
</pre>
-<h3 id="multiple-axes">Multiple axes</h3>
+<h3 id="multiple-axes"><a class="header" href="#multiple-axes">Multiple axes</a></h3>
<p>The easiest way to rotate a later array axis is usually to use the Cells (<code><span class='Modifier'>˘</span></code>) or Rank (<code><span class='Modifier2'>⎉</span></code>) modifier.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIHRhYiDihpAgM+KAvzTipYoiYWJjZEFCQ0QwMTIzIgoKMSDijL3LmCB0YWIgICMgUm90YXRlIHRoZSBzZWNvbmQgYXhpcw==">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>tab</span> <span class='Gets'>←</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Function'>⥊</span><span class='String'>&quot;abcdABCD0123&quot;</span>
┌─
diff --git a/docs/doc/scan.html b/docs/doc/scan.html
index 4b168b89..9d881cba 100644
--- a/docs/doc/scan.html
+++ b/docs/doc/scan.html
@@ -4,7 +4,7 @@
<title>BQN: Scan</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="scan">Scan</h1>
+<h1 id="scan"><a class="header" href="#scan">Scan</a></h1>
<svg viewBox='-184.8 -12.6 588 285.6'>
<g fill='currentColor' stroke-linecap='round' text-anchor='middle' font-family='BQN,monospace'>
<rect class='code' stroke-width='1.5' rx='12' x='-128.8' y='0' width='476' height='260.4'/>
@@ -61,7 +61,7 @@
<p>The 1-modifier Scan (<code><span class='Modifier'>`</span></code>) moves along the first axis of the array <code><span class='Value'>𝕩</span></code>, building up an array of results by applying <code><span class='Function'>𝔽</span></code> repeatedly beginning with <code><span class='Value'>𝕨</span></code> or <code><span class='Function'>⊏</span><span class='Value'>𝕩</span></code>. It's related to the fold modifiers, and most closely resembles the <a href="fold.html#apl2-reduction">APL2-style reduction</a> <code><span class='Modifier'>¨˝</span></code>, but it traverses the array in forward rather than reverse index order, and includes all intermediate results of <code><span class='Function'>𝔽</span></code> in its output instead of just the final one.</p>
<p>BQN's Scan is ordered differently from Scan in APL. Both include one result for each non-empty prefix of <code><span class='Value'>𝕩</span></code>. In BQN this is a left-to-right fold, so that each new result requires one application of <code><span class='Function'>𝔽</span></code>. APL uses right-to-left folds, which matches with reduction, but requires starting over at the end for each new prefix, except in special cases. If needed, this definition can be obtained with a fold on each <a href="prefixes.html">prefix</a> except the first (which is empty). In the particular case of <code><span class='Function'>-</span><span class='Value'>⍀</span></code>, that nested solution isn't needed: negate odd-indexed elements and then apply <code><span class='Function'>+</span><span class='Modifier'>`</span></code>.</p>
<p>Scan also differs from Fold or Insert in that it never depends on <code><span class='Function'>𝔽</span></code>'s <a href="fold.html#identity-values">identity value</a>, because scanning over an empty array simply returns that array.</p>
-<h2 id="lists">Lists</h2>
+<h2 id="lists"><a class="header" href="#lists">Lists</a></h2>
<p>The best-known use of Scan is the <a href="https://en.wikipedia.org/wiki/Prefix_sum">prefix sum</a> of a list, in which each element of the result is the sum of that element and all the ones before it. With a <a href="shift.html">shift</a> this can be modified to sum the previous elements only.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=K2AgMuKAvzTigL8z4oC/MQoKK2DCuzLigL804oC/M+KAvzEgICMgRXhjbHVzaXZlIHByZWZpeCBzdW0=">↗️</a><pre> <span class='Function'>+</span><span class='Modifier'>`</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span>
⟨ 2 6 9 10 ⟩
@@ -108,7 +108,7 @@
<span class='Brace'>{</span><span class='Function'>¬&lt;</span><span class='Modifier'>`</span><span class='String'>'\'</span><span class='Function'>=</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier2'>⊸</span><span class='Function'>/</span> <span class='String'>&quot;ab\\\rs\\\\&quot;</span>
"ab\rs\\"
</pre>
-<h2 id="reverse-scan">Reverse scan</h2>
+<h2 id="reverse-scan"><a class="header" href="#reverse-scan">Reverse scan</a></h2>
<p>We've discussed how the scan moves forward along <code><span class='Value'>𝕩</span></code>, so that each time <code><span class='Function'>𝔽</span></code> takes an old result as <code><span class='Value'>𝕨</span></code> and a new value as <code><span class='Value'>𝕩</span></code>. This means that results correspond to <a href="prefixes.html">prefixes</a> and go left to right on each one. Since the most important scans have associative, commutative operands, the left-to-right ordering often doesn't make a difference. But sometimes a suffix rather than prefix scan is wanted. For these cases, Scan Under <a href="reverse.html">Reverse</a> (<code><span class='Modifier'>`</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</span></code>) does the trick.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oioYCAgIDDigL8w4oC/MeKAvzDigL8w4oC/MeKAvzAKCuKIqGDijL7ijL0gMOKAvzDigL8x4oC/MOKAvzDigL8x4oC/MA==">↗️</a><pre> <span class='Function'>∨</span><span class='Modifier'>`</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'>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'>0</span>
⟨ 0 0 1 1 1 1 1 ⟩
@@ -124,7 +124,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eyIoIuKIvvCdlajiiL4iKfCdlL0i4oi+8J2VqX3LnGDijL7ijL0gImEi4oC/ImIi4oC/ImMi4oC/ImQi">↗️</a><pre> <span class='Brace'>{</span><span class='String'>&quot;(&quot;</span><span class='Function'>∾</span><span class='Value'>𝕨</span><span class='Function'>∾</span><span class='String'>&quot;)𝔽&quot;</span><span class='Function'>∾</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier'>˜`</span><span class='Modifier2'>⌾</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='Ligature'>‿</span><span class='String'>&quot;c&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;d&quot;</span>
⟨ "(a)𝔽(b)𝔽(c)𝔽d" "(b)𝔽(c)𝔽d" "(c)𝔽d" "d" ⟩
</pre>
-<h2 id="higher-ranks">Higher ranks</h2>
+<h2 id="higher-ranks"><a class="header" href="#higher-ranks">Higher ranks</a></h2>
<p>Scan moves along the <a href="leading.html">leading axis</a> of <code><span class='Value'>𝕩</span></code>: vertically, for a table. To apply a scan to later axes, use <code><span class='Modifier'>˘</span></code> or <code><span class='Modifier2'>⎉</span></code>. Since a scan returns an array with the same shape as its argument, this can't cause an error from differing result cell shapes, unlike Fold or Insert.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGEg4oaQIMKvMuKAvzAuMjXigL8nYSfigL/iiJ4g4oi+IDPigL804qWKwq8x4oC/MOKAvzEKCitgIGE=">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='Number'>¯2</span><span class='Ligature'>‿</span><span class='Number'>0.25</span><span class='Ligature'>‿</span><span class='String'>'a'</span><span class='Ligature'>‿</span><span class='Number'>∞</span> <span class='Function'>∾</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Function'>⥊</span><span class='Number'>¯1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span>
┌─
@@ -152,6 +152,6 @@
</pre>
<p>Results are produced in index order. This means that instead of moving along each column in turn, a scan produces the first result cell one element at a time, then the next, and so on. Something like a breadth-first as opposed to depth-first ordering.</p>
-<h2 id="definition">Definition</h2>
+<h2 id="definition"><a class="header" href="#definition">Definition</a></h2>
<p>Scan admits a simple recursive definition. <code><span class='Value'>𝕩</span></code> is an array of rank one or more and <code><span class='Value'>𝕨</span></code>, if given, is an atom or array with shape <code><span class='Number'>1</span><span class='Function'>↓≢</span><span class='Value'>𝕩</span></code>. The result <code><span class='Value'>z</span><span class='Gets'>←</span><span class='Value'>𝕨</span><span class='Function'>𝔽</span><span class='Modifier'>`</span><span class='Value'>𝕩</span></code> is an array with the same shape as <code><span class='Value'>𝕩</span></code>. If it has length at least one, <code><span class='Function'>⊏</span><span class='Value'>z</span></code> is <code><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> if <code><span class='Value'>𝕨</span></code> isn't given and <code><span class='Value'>𝕨</span><span class='Function'>𝔽</span><span class='Modifier'>¨</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> if it is. For <code><span class='Number'>0</span><span class='Function'>≤</span><span class='Value'>i</span></code>, <code><span class='Paren'>(</span><span class='Value'>i</span><span class='Function'>+</span><span class='Number'>1</span><span class='Paren'>)</span><span class='Function'>⊏</span><span class='Value'>z</span></code> is <code><span class='Paren'>(</span><span class='Value'>i</span><span class='Function'>⊏</span><span class='Value'>z</span><span class='Paren'>)</span><span class='Function'>𝔽</span><span class='Modifier'>¨</span><span class='Paren'>(</span><span class='Value'>i</span><span class='Function'>+</span><span class='Number'>1</span><span class='Paren'>)</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code>.</p>
<p>The ordering of <code><span class='Function'>𝔽</span></code> application is the natural one for this definition: cells are computed in turn, and each instance of <code><span class='Function'>𝔽</span><span class='Modifier'>¨</span></code> goes in index order.</p>
diff --git a/docs/doc/search.html b/docs/doc/search.html
index accd54fa..7834a06d 100644
--- a/docs/doc/search.html
+++ b/docs/doc/search.html
@@ -4,7 +4,7 @@
<title>BQN: Search functions</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="search-functions">Search functions</h1>
+<h1 id="search-functions"><a class="header" href="#search-functions">Search functions</a></h1>
<svg viewBox='-124.8 -46.8 532.8 280.8'>
<defs>
<mask id='m'>
@@ -133,7 +133,7 @@
</table>
<p>The searched-for argument is <code><span class='Value'>𝕩</span></code> in Index-of functions (<code><span class='Function'>⊐⊒</span></code>) and <code><span class='Value'>𝕨</span></code> in Member of (<code><span class='Function'>∊</span></code>). <a href="order.html#bins">Bins</a> Up and Down (<code><span class='Function'>⍋⍒</span></code>) are ordering functions but follow the same pattern as Index-of. It's split into cells, but not necessarily <em>major</em> cells: instead, the cells used match the rank of a major cell of the other (searched-in) argument. In the most common case, when the searched-in argument is a list, 0-cells are used for the search (we might also say elements, as it gives the same result).</p>
<p>The result is always an array containing one number for each searched-for cell. For Index of and Member of, every result is computed independently; for Progressive Index of the result for a cell can depend on earlier cells, in index order.</p>
-<h2 id="member-of">Member of</h2>
+<h2 id="member-of"><a class="header" href="#member-of">Member of</a></h2>
<p>The simplest of the search functions, Member of (<code><span class='Function'>∊</span></code>) returns <code><span class='Number'>1</span></code> if an entry in <code><span class='Value'>𝕨</span></code> matches some entry in <code><span class='Value'>𝕩</span></code>, and <code><span class='Number'>0</span></code> if it doesn't.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ImdyZWVuIuKAvyJicmlja3Mi4oC/ImNvdyLigL8iYmx1ZSIg4oiKICJyZWQi4oC/ImdyZWVuIuKAvyJibHVlIg==">↗️</a><pre> <span class='String'>&quot;green&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;bricks&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;cow&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;blue&quot;</span> <span class='Function'>∊</span> <span class='String'>&quot;red&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;green&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;blue&quot;</span>
⟨ 1 0 0 1 ⟩
@@ -147,7 +147,7 @@
</span>"tal st"
</pre>
<p>These are the APL functions Intersect (<code><span class='Value'>∩</span></code>) and Without (<code><span class='Value'>~</span></code>). Really, only <code><span class='Value'>𝕩</span></code> is treated like a set, while the ordering and multiplicity of elements of <code><span class='Value'>𝕨</span></code> are maintained. I think the explicit implementations show this well, since <code><span class='Value'>𝕩</span></code> is only used as the right argument to <code><span class='Function'>∊</span></code>, and prefer this clarity to the brevity of a single symbol.</p>
-<h2 id="index-of">Index of</h2>
+<h2 id="index-of"><a class="header" href="#index-of">Index of</a></h2>
<p>Index of (<code><span class='Function'>⊐</span></code>) returns the index of the first occurrence of each entry in <code><span class='Value'>𝕨</span></code>, or <code><span class='Function'>≠</span><span class='Value'>𝕨</span></code> if an entry doesn't appear in <code><span class='Value'>𝕨</span></code> at all.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Inplcm8i4oC/Im9uZSLigL8idHdvIuKAvyJ0aHJlZSIg4oqQICJvbmUi4oC/ImVpZ2h0IuKAvyJ0d28i">↗️</a><pre> <span class='String'>&quot;zero&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;one&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;two&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;three&quot;</span> <span class='Function'>⊐</span> <span class='String'>&quot;one&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;eight&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;two&quot;</span>
⟨ 1 4 2 ⟩
@@ -160,7 +160,7 @@
<span class='String'>&quot;letters&quot;</span> <span class='Paren'>(</span><span class='Function'>&lt;</span><span class='Modifier2'>∘</span><span class='Function'>/</span><span class='Modifier'>˘</span><span class='Function'>≡</span><span class='Modifier'>⌜˜</span><span class='Paren'>)</span> <span class='String'>&quot;let&quot;</span> <span class='Comment'># Many to many
</span>⟨ ⟨ 0 ⟩ ⟨ 1 4 ⟩ ⟨ 2 3 ⟩ ⟩
</pre>
-<h2 id="progressive-index-of">Progressive Index of</h2>
+<h2 id="progressive-index-of"><a class="header" href="#progressive-index-of">Progressive Index of</a></h2>
<p>Progressive Index of (<code><span class='Function'>⊒</span></code>), as the name and glyph suggest, is a more sophisticated variant of Index of. Like Index of, it returns either <code><span class='Function'>≠</span><span class='Value'>𝕨</span></code> or an index of a cell from <code><span class='Value'>𝕨</span></code> that matches the given cell of <code><span class='Value'>𝕩</span></code>. Unlike Index of, no index except <code><span class='Function'>≠</span><span class='Value'>𝕨</span></code> can ever be repeated. Progressive Index of returns the index of the first <em>unused</em> match, provided there's still one left.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ImFhYSIg4oqSICJhYWFhYSIKCiJhYWFiYiIg4oqSICJhYmFiYWJhYmFiIg==">↗️</a><pre> <span class='String'>&quot;aaa&quot;</span> <span class='Function'>⊒</span> <span class='String'>&quot;aaaaa&quot;</span>
⟨ 0 1 2 3 3 ⟩
@@ -192,7 +192,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqSy5wgImFueXRoaW5nIGF0IGFsbCI=">↗️</a><pre> <span class='Function'>⊒</span><span class='Modifier'>˜</span> <span class='String'>&quot;anything at all&quot;</span>
⟨ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ⟩
</pre>
-<h2 id="single-search">Single search</h2>
+<h2 id="single-search"><a class="header" href="#single-search">Single search</a></h2>
<p>Search functions are designed to search for multiple elements at once, and return an array of results. This is the array-oriented way to do it, and can allow faster algorithms to be used for the computation.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=c3R1ZmYg4oaQICJ0YWNrcyLigL8icGFwZXIi4oC/InN0cmluZyLigL8idGFwZSIKCnN0dWZmIOKKkCAidGFja3Mi4oC/InN0cmluZyI=">↗️</a><pre> <span class='Value'>stuff</span> <span class='Gets'>←</span> <span class='String'>&quot;tacks&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;paper&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;string&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;tape&quot;</span>
@@ -218,7 +218,7 @@
2
</pre>
<p>For Member of, the equivalent is <code><span class='Function'>∊</span><span class='Modifier2'>⟜</span><span class='Value'>stuff</span><span class='Modifier2'>⌾</span><span class='Function'>&lt;</span></code>.</p>
-<h2 id="higher-ranks">Higher ranks</h2>
+<h2 id="higher-ranks"><a class="header" href="#higher-ranks">Higher ranks</a></h2>
<p>So far we've shown search functions acting on lists. Well, and one example with a unit array slipped into the last section. In fact, if the searched-in array is a list, then the searched-for argument can have any rank.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KCJoaWdoIuKJjSJyYW5rIikg4oiKICJsaXN0IGFyZyI=">↗️</a><pre> <span class='Paren'>(</span><span class='String'>&quot;high&quot;</span><span class='Function'>≍</span><span class='String'>&quot;rank&quot;</span><span class='Paren'>)</span> <span class='Function'>∊</span> <span class='String'>&quot;list arg&quot;</span>
┌─
diff --git a/docs/doc/select.html b/docs/doc/select.html
index 63a55e1e..213731bf 100644
--- a/docs/doc/select.html
+++ b/docs/doc/select.html
@@ -4,7 +4,7 @@
<title>BQN: Select</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="select">Select</h1>
+<h1 id="select"><a class="header" href="#select">Select</a></h1>
<svg viewBox='-148.8 -17.4 480 208.8'>
<g font-family='BQN,monospace' font-size='22px' text-anchor='middle'>
<rect class='code' stroke-width='1.5' rx='12' x='-96' y='0' width='374.4' height='174'/>
@@ -50,7 +50,7 @@
<p>The function Select (<code><span class='Function'>⊏</span></code>) reorganizes the array <code><span class='Value'>𝕩</span></code> along one or more axes based on <a href="indices.html">indices</a> given by <code><span class='Value'>𝕨</span></code>. The result has the same <a href="depth.html">depth</a> as <code><span class='Value'>𝕩</span></code>, since its elements are always elements of <code><span class='Value'>𝕩</span></code>. This means it differs from <a href="pick.html">Pick</a> (<code><span class='Function'>⊑</span></code>), which takes elements from <code><span class='Value'>𝕩</span></code> but can arrange them in any nested structure, including returning an element directly.</p>
<p>The monadic form First Cell (<code><span class='Function'>⊏</span></code>) gets the major cell with index 0, so that <code><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> is identical to <code><span class='Number'>0</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code>.</p>
-<h2 id="single-selection">Single selection</h2>
+<h2 id="single-selection"><a class="header" href="#single-selection">Single selection</a></h2>
<p>Each axis of a BQN array is numbered starting at zero. Major cells are arranged along the first axis; in accordance with the <a href="leading.html">leading axis</a> principle, Select returns a major cell of <code><span class='Value'>𝕩</span></code> when <code><span class='Value'>𝕨</span></code> is an atom.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MiDiio8gImFiY2RlZiIgICMgQW4gZW5jbG9zZWQgZWxlbWVudAoKMiDiipEgImFiY2RlZiIgICMgUGljayBnZXRzIGEgbm9uLWVuY2xvc2VkIGVsZW1lbnQKCjIg4oqPID4ibnVsIuKAvyJvbmUi4oC/InR3byLigL8idHJlIuKAvyJmb3IiCgowIOKKjyA8NSAgIyBObyBmaXJzdCBheGlzIHRvIHNlbGVjdCBmcm9t">↗️</a><pre> <span class='Number'>2</span> <span class='Function'>⊏</span> <span class='String'>&quot;abcdef&quot;</span> <span class='Comment'># An enclosed element
</span>┌·
@@ -91,7 +91,7 @@ ERROR
<span class='Function'>⊏</span> <span class='String'>'a'</span>
ERROR
</pre>
-<h2 id="first-axis-selection">First-axis selection</h2>
+<h2 id="first-axis-selection"><a class="header" href="#first-axis-selection">First-axis selection</a></h2>
<p>If <code><span class='Value'>𝕨</span></code> is an array of numbers (including any empty array), then each number indicates a major cell of <code><span class='Value'>𝕩</span></code>. In the simplest case, a list of numbers gives a result with the same rank as <code><span class='Value'>𝕩</span></code> but maybe not the same length.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MuKAvzPigL8z4oC/MOKAvzTigL8xIOKKjyAiT2xaRXQiCgrin6jin6kg4oqPICJPbFpFdCI=">↗️</a><pre> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>1</span> <span class='Function'>⊏</span> <span class='String'>&quot;OlZEt&quot;</span>
"ZEEOtl"
@@ -161,7 +161,7 @@ ERROR
0123"
</pre>
-<h2 id="multi-axis-selection">Multi-axis selection</h2>
+<h2 id="multi-axis-selection"><a class="header" href="#multi-axis-selection">Multi-axis selection</a></h2>
<p>Select also allows <code><span class='Value'>𝕨</span></code> to apply to multiple axes of <code><span class='Value'>𝕩</span></code> simultaneously. For this case, <code><span class='Value'>𝕨</span></code> must be a non-empty list (or unit array) where every element is an array of indices.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oMuKAvzEsIDPigL8w4oC/MOKfqSDiio8g4oaVM+KAvzQ=">↗️</a><pre> <span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Separator'>,</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Bracket'>⟩</span> <span class='Function'>⊏</span> <span class='Function'>↕</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>4</span>
┌─
diff --git a/docs/doc/selfcmp.html b/docs/doc/selfcmp.html
index 432cd7c4..90438b04 100644
--- a/docs/doc/selfcmp.html
+++ b/docs/doc/selfcmp.html
@@ -4,7 +4,7 @@
<title>BQN: Self-search functions</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="self-search-functions">Self-search functions</h1>
+<h1 id="self-search-functions"><a class="header" href="#self-search-functions">Self-search functions</a></h1>
<svg viewBox='-115.2 -33 676.8 299.2'>
<defs>
<mask id='m'>
@@ -148,7 +148,7 @@
⟨ 1 1 0 1 0 ⟩
</pre>
<p>The result has one number for each major cell, or in other words is a list with the same length as its argument. Three self-search functions follow this pattern, but Deduplicate (<code><span class='Function'>⍷</span></code>) is different: it returns an array of the same rank but possibly a shorter length than the argument.</p>
-<h2 id="classify">Classify</h2>
+<h2 id="classify"><a class="header" href="#classify">Classify</a></h2>
<p>Classify is the universal self-search function, in that it preserves all the self-search information in its argument. It gives each different cell value a natural number, ordered by first appearance.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqQIDXigL824oC/MuKAvzLigL814oC/MQ==">↗️</a><pre> <span class='Function'>⊐</span> <span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>6</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'>5</span><span class='Ligature'>‿</span><span class='Number'>1</span>
⟨ 0 1 2 2 0 3 ⟩
@@ -169,7 +169,7 @@
<span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>𝕏≡𝕏</span><span class='Modifier2'>∘</span><span class='Function'>⊐</span><span class='Paren'>)</span><span class='String'>&quot;dbaedcbcecbcd&quot;</span><span class='Brace'>}</span><span class='Modifier'>¨</span> <span class='Function'>⊐</span><span class='Ligature'>‿</span><span class='Function'>⊒</span><span class='Ligature'>‿</span><span class='Function'>∊</span><span class='Ligature'>‿</span><span class='Function'>⍷</span>
⟨ 1 1 1 0 ⟩
</pre>
-<h3 id="classify-and-deduplicate">Classify and Deduplicate</h3>
+<h3 id="classify-and-deduplicate"><a class="header" href="#classify-and-deduplicate">Classify and Deduplicate</a></h3>
<p>Classify is also related to <a href="#deduplicate">Deduplicate</a>. In a way they are complements: applying both in sequence always gives a completely uninteresting result!</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGMg4oaQID4ieWVsbG93IuKAvyJvcmFuZ2Ui4oC/InllbGxvdyLigL8icHVycGxlIuKAvyJvcmFuZ2Ui4oC/InllbGxvdyIK4o23IOKKkCBjCuKKkCDijbcgYw==">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>c</span> <span class='Gets'>←</span> <span class='Function'>&gt;</span><span class='String'>&quot;yellow&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;orange&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;yellow&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;purple&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;orange&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;yellow&quot;</span>
┌─
@@ -206,7 +206,7 @@
</pre>
<p>One way to view this relationship is to consider an idea from linear algebra, where an idempotent transformation is called a &quot;projection&quot;. That means that the argument might be any value but the result is part of a smaller class of values, and any argument from that smaller class is left the same. What arrays do the two functions project to? The result of Deduplicate is an array with no repeated major cells. The result of Classify is a list of natural numbers, but it also has an additional property: each number in the list is at most one higher than the previous numbers, and the first number is zero. This comes from the way Classify numbers the cells of its argument. When it finds a cell that hasn't appeared before (at a lower index), it always chooses the next higher number for it.</p>
<p>Applying both Classify and Deduplicate gives an array that has both properties (this isn't the case for all pairs of projections—we need to know that Classify maintains the uniqueness property for Deduplicate and vice-versa). It has no duplicate major cells, <em>and</em> it's a list of natural numbers that starts with 0 and never goes up by more than one. Taken together, these are a tight constraint! The first element of the argument has to be 0. The next can't be 0 because it's already appeared, but it can't be more than one higher—it has to be 1. The next can't be 0 or 1, and has to be 2. And so on. So the result is always <code><span class='Function'>↕</span><span class='Value'>n</span></code> for some <code><span class='Value'>n</span></code>. In fact it's possible to determine the length as well, by noting that each function preserves the number of unique major cells in its argument. Classify does this because distinct numbers in the output correspond exactly to distinct major cells in the input; Deduplicate does this because it only removes duplicate cells, not distinct ones. So the final result is <code><span class='Function'>↕</span><span class='Value'>n</span></code>, where <code><span class='Value'>n</span></code> is the number of unique major cells in the argument.</p>
-<h3 id="mark-firsts">Mark Firsts</h3>
+<h3 id="mark-firsts"><a class="header" href="#mark-firsts">Mark Firsts</a></h3>
<p><em>See the <a href="https://aplwiki.com/wiki/Unique_Mask">APL Wiki page</a> on this function as well.</em></p>
<p>Mark Firsts (<code><span class='Function'>∊</span></code>) is the simplest self-search function: it returns <code><span class='Number'>0</span></code> for any major cell of the argument that is a duplicate of an earlier cell and <code><span class='Number'>1</span></code> for a major cell that's the first with its value. To implement <a href="#deduplicate">Deduplicate</a> in terms of Mark Firsts, just <a href="replicate.html">filter</a> out the duplicates with <code><span class='Function'>∊</span><span class='Modifier2'>⊸</span><span class='Function'>/</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oiKICAgM+KAvzHigL804oC/MeKAvzXigL854oC/MuKAvzbigL81CgriiIriirgvIDPigL8x4oC/NOKAvzHigL814oC/OeKAvzLigL824oC/NQ==">↗️</a><pre> <span class='Function'>∊</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>9</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Ligature'>‿</span><span class='Number'>5</span>
@@ -221,7 +221,7 @@
⟨ 0 0 1 0 1 ⟩
</pre>
<p>Remember that you don't have to apply the result of Mark Firsts to the same array you got it from! For example, it might be useful in a database application to find unique values in a particular column but use these to filter the entire table, or one other column.</p>
-<h3 id="occurrence-count">Occurrence Count</h3>
+<h3 id="occurrence-count"><a class="header" href="#occurrence-count">Occurrence Count</a></h3>
<p>Occurrence Count (<code><span class='Function'>⊒</span></code>) is a somewhat more sophisticated take on the idea behind Mark Firsts: instead of just testing whether a cell is a duplicate, it returns a number indicating how many previous cells match it. This means that Mark Firsts can be implemented with <code><span class='Number'>0</span><span class='Function'>=⊒</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqSICAgMuKAvzfigL8x4oC/OOKAvzHigL834oC/MeKAvzjigL8y4oC/OOKAvzQKCuKJjeKfnOKKkiAy4oC/N+KAvzHigL844oC/MeKAvzfigL8x4oC/OOKAvzLigL844oC/NAoKMD3iipIgMuKAvzfigL8x4oC/OOKAvzHigL834oC/MeKAvzjigL8y4oC/OOKAvzQgICMgRmlyc3QgYXBwZWFyYW5jZXMgbWFya2Vk">↗️</a><pre> <span class='Function'>⊒</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>7</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>8</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>7</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>8</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>8</span><span class='Ligature'>‿</span><span class='Number'>4</span>
⟨ 0 0 0 0 1 1 2 1 1 2 0 ⟩
@@ -248,7 +248,7 @@
⟨ 0 1 0 1 2 0 1 2 3 ⟩
</pre>
<p>A more efficient way when <code><span class='Function'>⊒</span></code> doesn't have a fast implementation is <code><span class='Function'>/</span><span class='Paren'>(</span><span class='Number'>¯1</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='Paren'>)</span><span class='Function'>+</span><span class='Modifier'>`</span></code>, but that's clearly quite a bit more complicated.</p>
-<h3 id="deduplicate">Deduplicate</h3>
+<h3 id="deduplicate"><a class="header" href="#deduplicate">Deduplicate</a></h3>
<p><em>There's also an <a href="https://aplwiki.com/wiki/Unique">APL Wiki page</a> on this function.</em></p>
<p>Deduplicate removes every major cell from the argument that matches an earlier cell, resulting in an array with the same rank but possibly a shorter length. It might also be described as returning the unique major cells of the argument, ordered by first occurrence. Deduplicate Under Reverse (<code><span class='Function'>⍷</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</span></code>) orders by last occurrence instead.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4o23ID4idGFrZSLigL8iZHJvcCLigL8iZHJvcCLigL8icGljayLigL8idGFrZSLigL8idGFrZSIKCuKNt+KMvuKMvSA+InRha2Ui4oC/ImRyb3Ai4oC/ImRyb3Ai4oC/InBpY2si4oC/InRha2Ui4oC/InRha2Ui">↗️</a><pre> <span class='Function'>⍷</span> <span class='Function'>&gt;</span><span class='String'>&quot;take&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;drop&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;drop&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;pick&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;take&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;take&quot;</span>
diff --git a/docs/doc/shape.html b/docs/doc/shape.html
index 99a4260e..80cfb45e 100644
--- a/docs/doc/shape.html
+++ b/docs/doc/shape.html
@@ -4,10 +4,10 @@
<title>BQN: Array dimensions</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="array-dimensions">Array dimensions</h1>
+<h1 id="array-dimensions"><a class="header" href="#array-dimensions">Array dimensions</a></h1>
<p>The function Shape (<code><span class='Function'>≢</span></code>) returns an array's shape, and Rank (<code><span class='Function'>=</span></code>) and Length (<code><span class='Function'>≠</span></code>) return properties that can be derived from the shape. BQN's arrays are multidimensional, so that the shape is a list of natural numbers (the length along each axis), while the rank (length of the shape) and length (of the first axis) are numbers. In these functions, an atom is treated as a unit array, which has rank 0 and empty shape. A unit has no first axis, but its length is defined to be 1.</p>
<p>Rank can be defined as <code><span class='Function'>≠</span><span class='Modifier2'>∘</span><span class='Function'>≢</span></code> while Length can be defined with a <a href="fold.html">fold</a> to be <code><span class='Number'>1</span><span class='Function'>⊣</span><span class='Modifier'>´</span><span class='Function'>≢</span></code>.</p>
-<h2 id="examples">Examples</h2>
+<h2 id="examples"><a class="header" href="#examples">Examples</a></h2>
<p>The function <a href="reshape.html">Reshape</a> (<code><span class='Function'>⥊</span></code>) always returns an array of shape <code><span class='Value'>𝕨</span></code>, so we use it to make an array of shape <code><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>6</span></code> in the example below (<a href="take.html">Take</a> (<code><span class='Function'>↑</span></code>) shares this property if <code><span class='Paren'>(</span><span class='Function'>≠</span><span class='Value'>𝕨</span><span class='Paren'>)</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=4oqiIGFyciDihpAgMeKAvzPigL8y4oC/NiDipYogJzAnK+KGlTEwCgriiaIgYXJyICAjIFNoYXBlCgriiaAgYXJyICAjIExlbmd0aAoKPSBhcnIgICMgUmFuaw==">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>arr</span> <span class='Gets'>←</span> <span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>3</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'>'0'</span><span class='Function'>+↕</span><span class='Number'>10</span>
┌─
@@ -44,7 +44,7 @@
<span class='Paren'>(</span><span class='Function'>=</span> <span class='Function'>≍</span> <span class='Function'>≠</span><span class='Paren'>)</span> <span class='Function'>&lt;↕</span><span class='Number'>10</span>
⟨ 0 1 ⟩
</pre>
-<h2 id="units">Units</h2>
+<h2 id="units"><a class="header" href="#units">Units</a></h2>
<p>A unit is an atom, or an array with no axes—rank 0. (See <a href="enclose.html">Enclose</a> for more about unit arrays). Since it doesn't have any axes, its shape should have no elements. It should be the empty list <code><span class='Bracket'>⟨⟩</span></code> (with a fill of <code><span class='Number'>0</span></code>, like all shapes). As there's no first element in the shape, it's not obvious what the length should be, and a stricter language would just give an error. However, there are some good reasons to use a length of <code><span class='Number'>1</span></code>. First, the total number of elements is 1, meaning that if the length divides this number evenly (as it does for non-unit arrays) then the only possible natural number it can be is 1. Second, many functions that take a list for a particular argument also accept a unit, and treat it as a length-1 array. For example, <code><span class='Number'>5</span><span class='Function'>⥊</span><span class='Value'>a</span></code> and <code><span class='Bracket'>⟨</span><span class='Number'>5</span><span class='Bracket'>⟩</span><span class='Function'>⥊</span><span class='Value'>a</span></code> are identical. Defining <code><span class='Function'>≠</span><span class='Number'>5</span></code> to be <code><span class='Number'>1</span></code> means that <code><span class='Function'>=</span><span class='Value'>s</span><span class='Function'>⥊</span><span class='Value'>a</span></code> is always <code><span class='Function'>≠</span><span class='Value'>s</span></code>.</p>
<p>Despite this last point, it's important to remember that a unit isn't the same as a 1-element list. For example, the length-1 string <code><span class='String'>&quot;a&quot;</span></code> doesn't match <code><span class='Function'>&lt;</span><span class='String'>'a'</span></code> but instead <code><span class='Bracket'>⟨</span><span class='String'>'a'</span><span class='Bracket'>⟩</span></code>. And also bear in mind that having an empty <em>shape</em> doesn't make a unit an empty <em>array</em>. That would mean it has no elements, not one!</p>
<table>
diff --git a/docs/doc/shift.html b/docs/doc/shift.html
index 012dfb0d..5b72e865 100644
--- a/docs/doc/shift.html
+++ b/docs/doc/shift.html
@@ -4,7 +4,7 @@
<title>BQN: Shift functions</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="shift-functions">Shift functions</h1>
+<h1 id="shift-functions"><a class="header" href="#shift-functions">Shift functions</a></h1>
<p>The shift functions <code><span class='Function'>«</span></code> and <code><span class='Function'>»</span></code> add major cells to one side an array, displacing cells on the opposite side and moving those in between. Shifts resemble but are more general than the bit-based shift operations used in low-level languages. They replace the APL pattern of a 2-wise reduction after appending or prepending an element (APL's <code><span class='Number'>2</span><span class='Function'>≠/</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Value'>v</span></code> translates to <code><span class='Function'>»</span><span class='Modifier2'>⊸</span><span class='Function'>≠</span><span class='Value'>v</span></code>), one of the more common uses of 2-wise reduction.</p>
<p>The result of a shift function always has the same shape as <code><span class='Value'>𝕩</span></code>. The function adds major cells to the beginning (<code><span class='Function'>»</span></code>) or end (<code><span class='Function'>«</span></code>) of <code><span class='Value'>𝕩</span></code>, moving the cells already in <code><span class='Value'>𝕩</span></code> to accomodate them. Some cells on the opposite side from those added will &quot;fall off&quot; and not be included in the result.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MOKAvzAgwrsgM+KAvzLigL8xICAgICAgICAgICAgICMgU2hpZnQgQmVmb3JlCiJlbmQiIMKrICJhZGQgdG8gdGhlICIgICAjIFNoaWZ0IEFmdGVy">↗️</a><pre> <span class='Number'>0</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> <span class='Comment'># Shift Before
@@ -19,7 +19,7 @@
</span>⟨ 2 3 0 ⟩
</pre>
<p>If <code><span class='Value'>𝕨</span></code> is longer than <code><span class='Value'>𝕩</span></code>, some cells from <code><span class='Value'>𝕨</span></code> will be discarded, as well as all of <code><span class='Value'>𝕩</span></code>. In this case <code><span class='Value'>𝕨</span><span class='Function'>»</span><span class='Value'>𝕩</span></code> is <code><span class='Paren'>(</span><span class='Function'>≠</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Function'>↑</span><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕨</span><span class='Function'>«</span><span class='Value'>𝕩</span></code> is <code><span class='Paren'>(</span><span class='Function'>-≠</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Function'>↑</span><span class='Value'>𝕨</span></code>. For similar reasons, nudging an array of length 0 returns it unchanged.</p>
-<h2 id="sequence-processing-with-shifts">Sequence processing with shifts</h2>
+<h2 id="sequence-processing-with-shifts"><a class="header" href="#sequence-processing-with-shifts">Sequence processing with shifts</a></h2>
<p>When working with a sequence of data such as text, daily measurements, or audio data, shift functions are generally the best way to handle the concept of &quot;next&quot; or &quot;previous&quot;. In the following example <code><span class='Value'>s</span></code> is shown alongside the shifted-right data <code><span class='Function'>»</span><span class='Value'>s</span></code>, and each element is compared to the previous with <code><span class='Function'>-</span><span class='Modifier2'>⟜</span><span class='Function'>»</span></code>, which we see is the <a href="undo.html">inverse</a> of Plus <a href="scan.html">Scan</a> <code><span class='Function'>+</span><span class='Modifier'>`</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=cyDihpAgMeKAvzLigL8y4oC/NOKAvzPigL814oC/NgpzIOKJjSDCu3MKLeKfnMK7IHMKCitgIC3in5zCuyBz">↗️</a><pre> <span class='Value'>s</span> <span class='Gets'>←</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'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>6</span>
<span class='Value'>s</span> <span class='Function'>≍</span> <span class='Function'>»</span><span class='Value'>s</span>
@@ -58,7 +58,7 @@
</span>⟨ ¯0.5 ¯0.5 ¯1 ¯0.5 ¯0.5 ¯1.5 ¯0.5 ⟩
</pre>
<p>A feature these examples all share is that they maintain the length of <code><span class='Value'>s</span></code>. This is a common condition in sequence processing, particularly when the processed sequence needs to be combined or compared with the original in some way. However, it's not always the case. In some instances, for example when searching <code><span class='Value'>s</span></code> to see if there is any value less than the previous, the list should get shorter during processing. In these cases, <a href="windows.html">Windows</a> (<code><span class='Function'>↕</span></code>) is usually a better choice.</p>
-<h2 id="arithmetic-and-logical-shifts">Arithmetic and logical shifts</h2>
+<h2 id="arithmetic-and-logical-shifts"><a class="header" href="#arithmetic-and-logical-shifts">Arithmetic and logical shifts</a></h2>
<p>The glyphs <code><span class='Function'>«</span></code> and <code><span class='Function'>»</span></code>, suggesting movement, were chosen for the same reasons as the digraphs <code><span class='Function'>&lt;&lt;</span></code> and <code><span class='Function'>&gt;&gt;</span></code>, and can be used to implement the same operations on boolean lists.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGkg4oaQICIxMDAxMTAxMSItJzAnCgrCq+KNnzMgaSAgICAgICAgIyBRdWljayBhbmQgZGlydHkgbGVmdCBzaGlmdAoKMyDipYrin5ww4oq4wqsgaSAgICAjIEFsdGVybmF0ZSBsZWZ0IHNoaWZ0">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>i</span> <span class='Gets'>←</span> <span class='String'>&quot;10011011&quot;</span><span class='Function'>-</span><span class='String'>'0'</span>
⟨ 1 0 0 1 1 0 1 1 ⟩
@@ -76,7 +76,7 @@
<span class='Number'>3</span> <span class='Paren'>(</span><span class='Function'>⥊</span><span class='Modifier2'>⟜</span><span class='Function'>⊏»⊢</span><span class='Paren'>)</span> <span class='Value'>i</span> <span class='Comment'># Arithmetic right shift
</span>⟨ 1 1 1 1 0 0 1 1 ⟩
</pre>
-<h2 id="other-examples">Other examples</h2>
+<h2 id="other-examples"><a class="header" href="#other-examples">Other examples</a></h2>
<p>In <a href="take.html">Take</a> (<code><span class='Function'>↑</span></code>), there's no way to specify the fill element when the result is longer than the argument. To take along the first axis with a specified, constant fill value, you can use Shift Before instead, where the right argument is an array of fills with the desired final shape.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ImFiYyIgwrsgNeKliidGJw==">↗️</a><pre> <span class='String'>&quot;abc&quot;</span> <span class='Function'>»</span> <span class='Number'>5</span><span class='Function'>⥊</span><span class='String'>'F'</span>
"abcFF"
@@ -95,7 +95,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KMOXYDHCu+KKoinijL7ijL0gNeKAvzLigL804oC/Mw==">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>`</span><span class='Number'>1</span><span class='Function'>»⊢</span><span class='Paren'>)</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</span> <span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span>
⟨ 24 12 3 1 ⟩
</pre>
-<h2 id="higher-rank">Higher rank</h2>
+<h2 id="higher-rank"><a class="header" href="#higher-rank">Higher rank</a></h2>
<p>Shifting always works on the first axis of <code><span class='Value'>𝕩</span></code> (which must have rank 1 or more), and shifts in major cells. A left argument can have rank equal to <code><span class='Value'>𝕩</span></code>, or one less than it, in which case it becomes a single cell of the result. With no left argument, a cell of fills <code><span class='Number'>1</span><span class='Function'>↑</span><span class='Number'>0</span><span class='Function'>↑</span><span class='Value'>𝕩</span></code> is nudged in.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGEg4oaQIOKliuKfnCjihpXDl8K0KSA04oC/MwoKwrsgYSAgICAgICAgICAgICAgICAjIE51ZGdlIGFkZHMgYSBjZWxsIG9mIGZpbGxzCgoib25lIiDCqyBhICAgICAgICAgICMgU2hpZnQgaW4gYSBjZWxsCgooInR3byLiiY0iY2VsIikgwqsgYSAgIyBTaGlmdCBpbiBtdWx0aXBsZSBjZWxscw==">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>a</span> <span class='Gets'>←</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'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span>
┌─
@@ -129,7 +129,7 @@
'c' 'e' 'l'
</pre>
-<h2 id="definition">Definition</h2>
+<h2 id="definition"><a class="header" href="#definition">Definition</a></h2>
<p>In any instance of <code><span class='Function'>»</span></code> or <code><span class='Function'>«</span></code>, <code><span class='Value'>𝕩</span></code> must have rank at least 1.</p>
<p>For a dyadic shift function, <code><span class='Value'>𝕨</span></code> must be <a href="join.html#join-to">Join</a>-compatible with <code><span class='Value'>𝕩</span></code> (that is, <code><span class='Value'>𝕨</span><span class='Function'>∾</span><span class='Value'>𝕩</span></code> completes without error) and cannot have greater rank than <code><span class='Value'>𝕩</span></code>. Then Shift Before (<code><span class='Function'>»</span></code>) is <code><span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>≠</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Function'>↑</span><span class='Value'>𝕨</span><span class='Function'>∾</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> and Shift After (<code><span class='Function'>«</span></code>) is <code><span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>-≠</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Function'>↑</span><span class='Value'>𝕩</span><span class='Function'>∾</span><span class='Value'>𝕨</span><span class='Brace'>}</span></code></p>
<p>When called monadically, the default argument is a cell of fills <code><span class='Number'>1</span><span class='Function'>↑</span><span class='Number'>0</span><span class='Function'>↑</span><span class='Value'>𝕩</span></code>. That is, Nudge (<code><span class='Function'>»</span></code>) is <code><span class='Paren'>(</span><span class='Number'>1</span><span class='Function'>↑</span><span class='Number'>0</span><span class='Function'>↑⊢</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>»</span></code> and Nudge Back (<code><span class='Function'>«</span></code>) is <code><span class='Paren'>(</span><span class='Number'>1</span><span class='Function'>↑</span><span class='Number'>0</span><span class='Function'>↑⊢</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>«</span></code>. This default argument always satisfies the compatibility requirement above and so the only conditions for nudge are that <code><span class='Value'>𝕩</span></code> has rank at least 1 and has a fill element.</p>
diff --git a/docs/doc/syntax.html b/docs/doc/syntax.html
index 98e09225..54271ab0 100644
--- a/docs/doc/syntax.html
+++ b/docs/doc/syntax.html
@@ -4,9 +4,9 @@
<title>BQN: Syntax overview</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="syntax-overview">Syntax overview</h1>
+<h1 id="syntax-overview"><a class="header" href="#syntax-overview">Syntax overview</a></h1>
<p>BQN syntax consists of expressions where computation is done with a little organizing structure around them like assignment, functions, and list notation. Expressions are where the programmer is in control so the design tries to do as much as possible with them before introducing special syntax.</p>
-<h2 id="special-glyphs">Special glyphs</h2>
+<h2 id="special-glyphs"><a class="header" href="#special-glyphs">Special glyphs</a></h2>
<p>The following glyphs are used for BQN syntax. <a href="primitive.html">Primitives</a> (built-in functions and modifiers) are not listed in this table, and have their own page. Digits, characters, and the underscore <code><span class='Modifier2'>_</span></code> are used for numbers, and identifiers or variable names.</p>
<table>
<thead>
@@ -102,9 +102,9 @@
</tr>
</tbody>
</table>
-<h2 id="comments">Comments</h2>
+<h2 id="comments"><a class="header" href="#comments">Comments</a></h2>
<p>A comment starts with <code><span class='Comment'>#</span></code> that is not part of a string and continues to the end of the line.</p>
-<h2 id="constants">Constants</h2>
+<h2 id="constants"><a class="header" href="#constants">Constants</a></h2>
<p>BQN has single-token notation for numbers, strings, and characters.</p>
<p>Numbers allow the typical decimal notation with <code><span class='Number'>¯</span></code> for the negative sign (because <code><span class='Function'>-</span></code> is a function) and <code><span class='Value'>e</span></code> for scientific notation (or <code><span class='Function'>E</span></code>, as numeric notation is case-insensitive). <code><span class='Number'>∞</span></code> and <code><span class='Number'>π</span></code> may be used as special numeric values. If complex numbers are supported, then they can be written with the components separated by <code><span class='Value'>i</span></code>. However, no BQN to date supports complex numbers.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oIMKvz4Ag4ouEIDAuNSDii4QgNWXCrzEg4ouEIDEuNUUzIOKLhCDiiJ4g4p+pICAgIyBBIGxpc3Qgb2YgbnVtYmVycw==">↗️</a><pre> <span class='Bracket'>⟨</span> <span class='Number'>¯π</span> <span class='Separator'>⋄</span> <span class='Number'>0.5</span> <span class='Separator'>⋄</span> <span class='Number'>5e¯1</span> <span class='Separator'>⋄</span> <span class='Number'>1.5E3</span> <span class='Separator'>⋄</span> <span class='Number'>∞</span> <span class='Bracket'>⟩</span> <span class='Comment'># A list of numbers
@@ -118,7 +118,7 @@
</span>⟨ 1 0 ⟩
</pre>
<p>The null character (code point 0) has a dedicated literal representation <code><span class='String'>@</span></code>. This character can be used to directly convert between characters and numeric code points, which among many other uses allows tricky characters to be entered by code point: for example, a non-breaking space is <code><span class='String'>@</span><span class='Function'>+</span><span class='Number'>160</span></code>. The character can also be entered as a character literal, but this will display differently in various editors and some tools may have trouble with a file directly containing a null, so it is best to use <code><span class='String'>@</span></code> instead.</p>
-<h2 id="expressions">Expressions</h2>
+<h2 id="expressions"><a class="header" href="#expressions">Expressions</a></h2>
<p><em><a href="context.html">More discussion</a></em></p>
<p>Like APL, BQN uses four <em>syntactic roles</em> for values in expressions:</p>
<ul>
@@ -136,7 +136,7 @@
</pre>
<p>BQN's built-in operations also have patterns to indicate the syntactic role: 1-modifiers (<code><span class='Modifier'>˜¨˘⁼⌜´`</span></code>) are all superscript characters, and 2-modifiers (<code><span class='Modifier2'>∘○⊸⟜⌾⊘◶⚇⎉⍟</span></code>) all have an unbroken circle (two functions <code><span class='Function'>⌽⍉</span></code> have broken circles with lines through them). Every other built-in constant is a function, although the special symbols <code><span class='Number'>¯</span></code>, <code><span class='Number'>∞</span></code>, and <code><span class='Number'>π</span></code> are used as part of numeric literal notation.</p>
-<h3 id="assignment">Assignment</h3>
+<h3 id="assignment"><a class="header" href="#assignment">Assignment</a></h3>
<p>Another element that can be included in expressions is assignment, which is written with <code><span class='Gets'>←</span></code> to <em>define</em> (also called &quot;declare&quot; in many other languages) a variable and <code><span class='Gets'>↩</span></code> to <em>change</em> its definition. A variable can only be defined once within a <a href="lexical.html">scope</a>, and can only be changed if it has already been defined. However, it can be shadowed, meaning that it is defined again in an inner scope even though it has a definition in an outer scope already.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eOKGkDEg4ouEIHt44oaQMiDii4QgeOKGqTMg4ouEIHh9Cng=">↗️</a><pre> <span class='Value'>x</span><span class='Gets'>←</span><span class='Number'>1</span> <span class='Separator'>⋄</span> <span class='Brace'>{</span><span class='Value'>x</span><span class='Gets'>←</span><span class='Number'>2</span> <span class='Separator'>⋄</span> <span class='Value'>x</span><span class='Gets'>↩</span><span class='Number'>3</span> <span class='Separator'>⋄</span> <span class='Value'>x</span><span class='Brace'>}</span>
3
@@ -149,7 +149,7 @@
<span class='Value'>a</span>
¯3
</pre>
-<h3 id="exports">Exports</h3>
+<h3 id="exports"><a class="header" href="#exports">Exports</a></h3>
<p>The double arrow <code><span class='Gets'>⇐</span></code> is used to export variables from a block or program, causing the result to be a <a href="namespace.html">namespace</a>. There are two ways to export variables. First, <code><span class='Gets'>←</span></code> in the variable definition can be replaced with <code><span class='Gets'>⇐</span></code> to export the variable as it's defined. Second, an export statement consisting of an assignment target followed by <code><span class='Gets'>⇐</span></code> with nothing to the right exports the variables in the assignment target and does nothing else. Export statements can be placed anywhere in the relevant program or body, including before declaration or on the last line, and a given variable can be exported any number of times.</p>
<pre><span class='Bracket'>⟨</span><span class='Value'>alias</span><span class='Gets'>⇐</span><span class='Value'>a</span><span class='Separator'>,</span> <span class='Value'>b</span><span class='Separator'>,</span> <span class='Value'>c0</span><span class='Ligature'>‿</span><span class='Value'>c1</span><span class='Gets'>⇐</span><span class='Value'>c</span><span class='Separator'>,</span> <span class='Value'>b2</span><span class='Gets'>⇐</span><span class='Value'>b</span><span class='Bracket'>⟩</span><span class='Gets'>←</span><span class='Brace'>{</span>
<span class='Value'>b</span><span class='Ligature'>‿</span><span class='Value'>c</span><span class='Gets'>⇐</span> <span class='Comment'># Non-definition exports can go anywhere
@@ -159,13 +159,13 @@
<span class='Brace'>}</span>
</pre>
<p>Fields of the resulting namespace can be accessed either directly using <code><span class='Value'>namespace.field</span></code> syntax, or with a destructuring assignment as shown above. This assignment's target is a list where each element specifies one of the names exported by the block and what it should be assigned to. The element can be either a single name (such as <code><span class='Value'>b</span></code> above), which gives both, or a combination of the assignment target, then <code><span class='Gets'>⇐</span></code>, then a name. If <code><span class='Gets'>⇐</span></code> is never used, the names can be given as a strand with <code><span class='Ligature'>‿</span></code>. To use <code><span class='Gets'>⇐</span></code> for aliases, bracket syntax <code><span class='Bracket'>⟨⟩</span></code> is needed. Imported names can be repeated and can be spelled with any role (the role is ignored).</p>
-<h2 id="lists-and-blocks">Lists and blocks</h2>
-<h3 id="separators">Separators</h3>
+<h2 id="lists-and-blocks"><a class="header" href="#lists-and-blocks">Lists and blocks</a></h2>
+<h3 id="separators"><a class="header" href="#separators">Separators</a></h3>
<p>The characters <code><span class='Separator'>⋄</span></code> and <code><span class='Separator'>,</span></code> and newline are completely interchangeable and are used to separate expressions. An expression might be an element in a list or a line in a function. Empty sections—those that consist only of whitespace—are ignored. This means that any number of separators can be used between expressions, and that leading and trailing separators are also allowed. The expressions are evaluated in text order: left to right and top to bottom.</p>
-<h3 id="list-notation">List notation</h3>
+<h3 id="list-notation"><a class="header" href="#list-notation">List notation</a></h3>
<p><em><a href="arrayrepr.html#list-literals">Full documentation</a></em></p>
<p>Lists (1-dimensional arrays) are enclosed in angle brackets <code><span class='Bracket'>⟨⟩</span></code>, with the results of the expressions in between being the list's elements. Lists of two elements or more can also be written with the ligature character <code><span class='Ligature'>‿</span></code>. This character has higher binding strength than any part of an expression. If one of the elements is a compound expression, then it will need to be enclosed in parentheses.</p>
-<h3 id="blocks">Blocks</h3>
+<h3 id="blocks"><a class="header" href="#blocks">Blocks</a></h3>
<p><em><a href="block.html">Full documentation</a></em></p>
<p>Blocks are written with curly braces <code><span class='Brace'>{}</span></code> and can be used to group expressions or define functions and modifiers. The contents are simply a sequence of expressions, where each is evaluated and the result of the last is returned in order to evaluate the block. This result can have any value, and its syntactic role in the calling context is determined by the normal rules: functions return subjects and modifiers return functions. Blocks have <a href="lexical.html">lexical scope</a>.</p>
<p>The special names <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code>, which stand for arguments, and <code><span class='Value'>𝕗</span></code> and <code><span class='Value'>𝕘</span></code>, which stand for operands, are available inside curly braces. Like ordinary names, the lowercase forms indicate subjects and the uppercase forms <code><span class='Function'>𝕎𝕏𝔽𝔾</span></code> indicate functions. The type and syntactic role of the block is determined by its contents: a 2-modifier contains <code><span class='Value'>𝕘</span></code>, a 1-modifier contains <code><span class='Value'>𝕗</span></code> but not <code><span class='Value'>𝕘</span></code>, and a function contains neither but does have one of <code><span class='Value'>𝕨𝕩𝕤</span><span class='Function'>𝕎𝕏𝕊</span></code>. If no special names are present the block is an <em>immediate block</em> and is evaluated as soon as it appears, with the result having a subject role.</p>
diff --git a/docs/doc/take.html b/docs/doc/take.html
index 0dcbaa39..1dd895ff 100644
--- a/docs/doc/take.html
+++ b/docs/doc/take.html
@@ -4,7 +4,7 @@
<title>BQN: Take and Drop</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="take-and-drop">Take and Drop</h1>
+<h1 id="take-and-drop"><a class="header" href="#take-and-drop">Take and Drop</a></h1>
<svg viewBox='-156.8 -64 672 204.8'>
<g fill='currentColor' stroke-linecap='round' text-anchor='middle' font-family='BQN,monospace'>
<rect class='code' stroke-width='1.5' rx='12' x='-100.8' y='-40' width='560' height='156.8'/>
@@ -43,7 +43,7 @@
</ul>
<p>These extensions can be combined as well, so there are a lot of possibilities. A good picture to have in mind is cutting out a corner of the array <code><span class='Value'>𝕩</span></code>. This is because the result <code><span class='Value'>𝕨</span><span class='Function'>↑</span><span class='Value'>𝕩</span></code> or <code><span class='Value'>𝕨</span><span class='Function'>↓</span><span class='Value'>𝕩</span></code> always aligns with one side of <code><span class='Value'>𝕩</span></code> along each axis, so it aligns with the corner where those sides meet.</p>
<p>The result <code><span class='Value'>d</span><span class='Function'>↓</span><span class='Value'>𝕩</span></code> is always the same as <code><span class='Value'>t</span><span class='Function'>↑</span><span class='Value'>𝕩</span></code> for some other argument <code><span class='Value'>t</span></code>, but computing <code><span class='Value'>t</span></code> wouldn't be too convenient. The reverse isn't true: only Take can insert fills, so results that include them can't come from Drop.</p>
-<h2 id="one-axis">One axis</h2>
+<h2 id="one-axis"><a class="header" href="#one-axis">One axis</a></h2>
<p>Let's start with a natural number <code><span class='Value'>𝕨</span></code>. Take gives the first <code><span class='Value'>𝕨</span></code> major cells of <code><span class='Value'>𝕩</span></code> (or elements of a list), while Drop gives all but the first <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=NCDihpEgInRha2UgYW5kIGRyb3AiCjQg4oaTICJ0YWtlIGFuZCBkcm9wIgoKMSDihpMgPiJtYWoi4oC/Im9yYyLigL8iZWxsIg==">↗️</a><pre> <span class='Number'>4</span> <span class='Function'>↑</span> <span class='String'>&quot;take and drop&quot;</span>
"take"
@@ -76,7 +76,7 @@
<span class='Number'>3</span> <span class='Function'>↓</span> <span class='Function'>&lt;</span><span class='String'>&quot;element&quot;</span>
⟨⟩
</pre>
-<h3 id="negative-argument">Negative argument</h3>
+<h3 id="negative-argument"><a class="header" href="#negative-argument">Negative argument</a></h3>
<p>If <code><span class='Value'>𝕨</span></code> is negative then wraps around the other side to take or drop from the end of <code><span class='Value'>𝕩</span></code>. It's a lot like negative indices in <a href="select.html">Select</a> (<code><span class='Function'>⊏</span></code>), but while negative indices are asymmetric—<code><span class='Number'>0</span></code> is the first entry but <code><span class='Number'>¯1</span></code> is the last—this case is symmetric. It's because the place to cut is always <em>before</em> the index <code><span class='Value'>𝕨</span></code>, cancelling out the negative index asymmetry.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyDihpEgImFiY2RlRURDQkEiCgrCrzMg4oaRICJhYmNkZUVEQ0JBIiAgIyBMYXN0IHRocmVlCgrCrzMg4oaTICJhYmNkZUVEQ0JBIiAgIyBBbGwgYnV0IHRoZSBsYXN0IHRocmVl">↗️</a><pre> <span class='Number'>3</span> <span class='Function'>↑</span> <span class='String'>&quot;abcdeEDCBA&quot;</span>
"abc"
@@ -98,7 +98,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=wq82IOKGkSAieHki">↗️</a><pre> <span class='Number'>¯6</span> <span class='Function'>↑</span> <span class='String'>&quot;xy&quot;</span>
" xy"
</pre>
-<h2 id="multiple-axes">Multiple axes</h2>
+<h2 id="multiple-axes"><a class="header" href="#multiple-axes">Multiple axes</a></h2>
<p>In the general case <code><span class='Value'>𝕨</span></code> is a list of integers. They're matched with the leading axes of <code><span class='Value'>𝕩</span></code>, so that each affects one axis independently from the others.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIG0g4oaQICgxMMOX4oaVNSkgK+KMnCDihpU3CgrCrzTigL8yIOKGkSBtICAjIExhc3QgZm91ciByb3dzOyBmaXJzdCB0d28gY29sdW1ucwoKwq804oC/MiDihpMgbQ==">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>m</span> <span class='Gets'>←</span> <span class='Paren'>(</span><span class='Number'>10</span><span class='Function'>×↕</span><span class='Number'>5</span><span class='Paren'>)</span> <span class='Function'>+</span><span class='Modifier'>⌜</span> <span class='Function'>↕</span><span class='Number'>7</span>
┌─
diff --git a/docs/doc/train.html b/docs/doc/train.html
index b9c2f398..9675922c 100644
--- a/docs/doc/train.html
+++ b/docs/doc/train.html
@@ -4,10 +4,10 @@
<title>BQN: Function trains</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="function-trains">Function trains</h1>
+<h1 id="function-trains"><a class="header" href="#function-trains">Function trains</a></h1>
<p>Trains are an important aspect of BQN's <a href="tacit.html">tacit</a> programming capabilities. In fact, a crucial one: with trains and the <a href="identity.html">identity functions</a> Left (<code><span class='Function'>⊣</span></code>) and Right (<code><span class='Function'>⊢</span></code>), a fully tacit program can express any explicit function whose body is a statement with <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code> used only as arguments (that is, there are no assignments and <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code> are not used in operands or lists. Functions with assignments may have too many variables active at once to be directly translated but can be emulated by constructing lists. But it's probably a bad idea). Without trains it isn't possible to have two different functions that each use both arguments to a dyadic function. With trains it's perfectly natural.</p>
<p>BQN's trains are the same as those of Dyalog APL, except that Dyalog is missing the minor convenience of BQN's Nothing (<code><span class='Nothing'>·</span></code>). There are many Dyalog-based documents and videos on trains you can view on the <a href="https://aplwiki.com/wiki/Train">APL Wiki</a>.</p>
-<h2 id="2-train-3-train">2-train, 3-train</h2>
+<h2 id="2-train-3-train"><a class="header" href="#2-train-3-train">2-train, 3-train</a></h2>
<p>Trains are an adaptation of the mathematical convention that, for example, two functions <code><span class='Function'>F</span></code> and <code><span class='Function'>G</span></code> can be added to get a new function <code><span class='Function'>F+G</span></code> that applies as <code><span class='Paren'>(</span><span class='Function'>F+G</span><span class='Paren'>)(</span><span class='Value'>x</span><span class='Paren'>)</span> <span class='Function'>=</span> <span class='Function'>F</span><span class='Paren'>(</span><span class='Value'>x</span><span class='Paren'>)</span><span class='Function'>+G</span><span class='Paren'>(</span><span class='Value'>x</span><span class='Paren'>)</span></code>. With a little change to the syntax, we can do exactly this in BQN:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKKoivijL0pIOKGlTU=">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>⊢+⌽</span><span class='Paren'>)</span> <span class='Function'>↕</span><span class='Number'>5</span>
⟨ 4 4 4 4 4 ⟩
@@ -25,7 +25,7 @@
"fcdeab"
</pre>
<p>The three functions <code><span class='Function'>∾⌽</span></code>, <code><span class='Nothing'>·</span><span class='Function'>∾⌽</span></code>, and <code><span class='Function'>∾</span><span class='Modifier2'>∘</span><span class='Function'>⌽</span></code> are completely identical: <a href="join.html#join">Join</a> of <a href="reverse.html">Reverse</a>. Why might we want <strong>three</strong> different ways to write the same thing? If we only want to define a function, there's hardly any difference. However, these three forms have different syntax, and might be easier or harder to use in different contexts. As we'll see, we can use <code><span class='Function'>∾</span><span class='Modifier2'>∘</span><span class='Function'>⌽</span></code> inside a train without parenthesizing it, and string <code><span class='Nothing'>·</span><span class='Function'>∾⌽</span></code> but not <code><span class='Function'>∾⌽</span></code> together with other trains. Let's look at how the train syntax extends to longer expressions.</p>
-<h2 id="longer-trains">Longer trains</h2>
+<h2 id="longer-trains"><a class="header" href="#longer-trains">Longer trains</a></h2>
<p>Function application in trains, as in other contexts, shares the lowest precedence level with assignment. Modifiers and strands (with <code><span class='Ligature'>‿</span></code>) have higher precedence, so they are applied before forming any trains. Once this is done, an expression is a <em>subject expression</em> if it ends with a subject and a <em>function expression</em> if it ends with a function (there are also modifier expressions, which aren't relevant here). A train is any function expression with multiple functions or subjects in it: while we've seen examples with two or three functions, any number are allowed.</p>
<p>Subject expressions are the domain of &quot;old-school&quot; APL, and just apply one function after another to a subject, possibly assigning some of the results (that's the top-level picture—anything can still happen within parentheses). Subjects other than the first appear only as left arguments to functions, which means that two subjects can't appear next to each other because the one on the left would have no corresponding function. Here's an example from the compiler (at one point), with functions and assignments numbered in the order they are applied and their arguments marked with <code><span class='Function'>«»</span></code>, and a fully-parenthesized version shown below.</p>
<pre><span class='Value'>cn</span><span class='Gets'>←</span><span class='Value'>pi</span><span class='Function'>∾</span><span class='Value'>lt</span><span class='Gets'>←</span><span class='Function'>/</span><span class='Value'>𝕩</span><span class='Function'>≥</span><span class='Value'>ci</span><span class='Gets'>←</span><span class='Value'>vi</span><span class='Function'>+</span><span class='Value'>nv</span>
@@ -40,7 +40,7 @@
<span class='Function'>⊢&gt;</span><span class='Paren'>(</span><span class='Number'>¯1</span><span class='Function'>»⌈</span><span class='Modifier'>`</span><span class='Paren'>)</span>
</pre>
<p>In a train, arguments alternate strictly with combining functions between them. Arguments can be either functions or subjects, except for the rightmost one, which has to be a function to indicate that the expression is a train. Trains tend to be shorter than subject expressions partly because to keep track of this alternation in a train of all functions, you need to know where each function is relative to the end of the train (subjects like the <code><span class='Number'>¯1</span></code> above only occur as left arguments, so they can also serve as anchors).</p>
-<h2 id="practice-training">Practice training</h2>
+<h2 id="practice-training"><a class="header" href="#practice-training">Practice training</a></h2>
<p>The train <code><span class='Function'>⊢&gt;</span><span class='Number'>¯1</span><span class='Function'>»⌈</span><span class='Modifier'>`</span></code> is actually a nice trick to get the result of <a href="selfcmp.html#mark-firsts">Mark Firsts</a> <code><span class='Function'>∊</span><span class='Value'>𝕩</span></code> given the result of <a href="selfcmp.html#classify">Classify</a> <code><span class='Function'>⊐</span><span class='Value'>𝕩</span></code>, without doing another search. Let's take a closer look, first by applying it mechanically. To do this, we apply each &quot;argument&quot; to the train's argument, and then combine them with the combining functions.</p>
<pre><span class='Paren'>(</span><span class='Function'>⊢</span> <span class='Function'>&gt;</span> <span class='Number'>¯1</span> <span class='Function'>»</span> <span class='Function'>⌈</span><span class='Modifier'>`</span><span class='Paren'>)</span> <span class='Value'>𝕩</span>
<span class='Paren'>(</span><span class='Function'>⊢</span><span class='Value'>𝕩</span><span class='Paren'>)</span> <span class='Function'>&gt;</span> <span class='Paren'>(</span><span class='Number'>¯1</span><span class='Paren'>)</span> <span class='Function'>»</span> <span class='Paren'>(</span><span class='Function'>⌈</span><span class='Modifier'>`</span><span class='Value'>𝕩</span><span class='Paren'>)</span>
@@ -70,7 +70,7 @@
<span class='Paren'>(</span><span class='Function'>⊢&gt;</span><span class='Number'>¯1</span><span class='Function'>»⌈</span><span class='Modifier'>`</span><span class='Paren'>)</span> <span class='Value'>sc</span>
⟨ 1 1 1 1 0 0 1 0 0 1 1 ⟩
</pre>
-<h2 id="composing-trains">Composing trains</h2>
+<h2 id="composing-trains"><a class="header" href="#composing-trains">Composing trains</a></h2>
<p>The example above uses a train with five functions: an odd number. Trains with an odd length are always composed of length-3 trains, and they themselves are composed the same way as subject expressions: an odd-length train can be placed in the last position of another train without parentheses, but it needs parentheses to go in any other position.</p>
<p>But we also saw the length-2 train <code><span class='Function'>∾⌽</span></code> above. Even-length trains consist of a single function (<code><span class='Function'>∾</span></code>) applied to a function or odd-length train (<code><span class='Function'>⌽</span></code>); another perspective is that an even-length train is an odd-length train where the left argument of the final (leftmost) function is left out, so it's called with only a right argument. An even-length train <em>always</em> needs parentheses if it's used as one of the functions in another train. However, it can also be turned into an odd-length train by placing <code><span class='Nothing'>·</span></code> at the left, making the implicit missing argument explicit. After this it can be used at the end of an odd-length train without parentheses. To get some intuition for even-length trains, let's look at an example of three functions used together: the <a href="selfcmp.html#deduplicate">unique</a> (<code><span class='Function'>⍷</span></code>) <a href="order.html#sort">sorted</a> (<code><span class='Function'>∧</span></code>) <a href="arithmetic.html#additional-arithmetic">absolute values</a> (<code><span class='Function'>|</span></code>) of an argument list.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4o234oinfCAz4oC/NOKAv8KvM+KAv8KvMuKAvzA=">↗️</a><pre> <span class='Function'>⍷∧|</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>¯3</span><span class='Ligature'>‿</span><span class='Number'>¯2</span><span class='Ligature'>‿</span><span class='Number'>0</span>
diff --git a/docs/doc/transpose.html b/docs/doc/transpose.html
index 42d3dd71..b2319106 100644
--- a/docs/doc/transpose.html
+++ b/docs/doc/transpose.html
@@ -4,9 +4,9 @@
<title>BQN: Transpose</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="transpose">Transpose</h1>
+<h1 id="transpose"><a class="header" href="#transpose">Transpose</a></h1>
<p>Transpose (<code><span class='Function'>⍉</span></code>) is a tool for rearranging the axes of an array. BQN's version is tweaked relative to APL to align better with the leading axis model and make common operations easier.</p>
-<h2 id="transpose-basics">Transpose basics</h2>
+<h2 id="transpose-basics"><a class="header" href="#transpose-basics">Transpose basics</a></h2>
<p>The name for the primitive <code><span class='Function'>⍉</span></code> comes from the <a href="https://en.wikipedia.org/wiki/Transpose">Transpose</a> operation on matrices. Given a matrix as an array of rank 2, <code><span class='Function'>⍉</span></code> will transpose it:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIG1hdCDihpAgMuKAvzMg4qWKIOKGlTYK4o2JIG1hdA==">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>mat</span> <span class='Gets'>←</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span> <span class='Function'>⥊</span> <span class='Function'>↕</span><span class='Number'>6</span>
┌─
@@ -27,7 +27,7 @@
3
</pre>
<p>With two axes the only interesting operation of this sort is to swap them (and with one or zero axes there's nothing interesting to do, and <code><span class='Function'>⍉</span></code> just returns the argument array). But a BQN programmer may well want to work with higher-rank arrays—although such a programmer might call them &quot;tensors&quot;—and this means there are many more ways to rearrange the axes. Transpose extends to high-rank arrays to allow some useful special cases as well as completely general axis rearrangement, as described below.</p>
-<h2 id="monadic-transpose">Monadic Transpose</h2>
+<h2 id="monadic-transpose"><a class="header" href="#monadic-transpose">Monadic Transpose</a></h2>
<p>APL extends matrix transposition to any rank by reversing all axes for its monadic <code><span class='Function'>⍉</span></code>, but this generalization isn't very natural and is almost never used. The main reason for it is to maintain the equivalence <code><span class='Value'>a</span> <span class='Function'>MP</span> <span class='Value'>b</span> <span class='Gets'>←→</span> <span class='Value'>b</span> <span class='Function'>MP</span><span class='Modifier2'>⌾</span><span class='Function'>⍉</span> <span class='Value'>a</span></code>, where <code><span class='Function'>MP</span> <span class='Gets'>←</span> <span class='Function'>+</span><span class='Modifier'>˝</span><span class='Modifier2'>∘</span><span class='Function'>×</span><span class='Modifier2'>⎉</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>∞</span></code> is the generalized matrix product. But even here APL's Transpose is suspect. It does much more work than it needs to, as we'll see.</p>
<p>BQN's transpose takes the first axis of <code><span class='Value'>𝕩</span></code> and moves it to the end.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4omiIGEyMzQ1NiDihpAg4oaVMuKAvzPigL804oC/NeKAvzYKCuKJoiDijYkgYTIzNDU2">↗️</a><pre> <span class='Function'>≢</span> <span class='Value'>a23456</span> <span class='Gets'>←</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'>4</span><span class='Ligature'>‿</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>6</span>
@@ -88,7 +88,7 @@
</span>⟨ 3 4 2 5 6 ⟩
</pre>
<p>In a case like this BQN's Dyadic transpose is much easier.</p>
-<h2 id="dyadic-transpose">Dyadic Transpose</h2>
+<h2 id="dyadic-transpose"><a class="header" href="#dyadic-transpose">Dyadic Transpose</a></h2>
<p>Transpose also allows a left argument that specifies a permutation of <code><span class='Value'>𝕩</span></code>'s axes. For each index <code><span class='Value'>p</span><span class='Gets'>←</span><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>𝕨</span></code> in the left argument, axis <code><span class='Value'>i</span></code> of <code><span class='Value'>𝕩</span></code> is used for axis <code><span class='Value'>p</span></code> of the result. Multiple argument axes can be sent to the same result axis, in which case that axis goes along a diagonal of <code><span class='Value'>𝕩</span></code>, and the result will have a lower rank than <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=4omiIDHigL8z4oC/MuKAvzDigL80IOKNiSBhMjM0NTYKCuKJoiAx4oC/MuKAvzLigL8w4oC/MCDijYkgYTIzNDU2ICAjIERvbid0IHdvcnJ5IHRvbyBtdWNoIGFib3V0IHRoaXMgY2FzZSB0aG91Z2g=">↗️</a><pre> <span class='Function'>≢</span> <span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>3</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'>4</span> <span class='Function'>⍉</span> <span class='Value'>a23456</span>
⟨ 5 2 4 3 6 ⟩
@@ -109,7 +109,7 @@
</span>⟨ 3 4 2 5 6 ⟩
</pre>
<p>Finally, it's worth noting that, as monadic Transpose moves the first axis to the end, it's equivalent to dyadic Transpose with a &quot;default&quot; left argument: <code><span class='Paren'>(</span><span class='Function'>=-</span><span class='Number'>1</span><span class='Modifier'>˙</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>⍉</span></code>.</p>
-<h2 id="definitions">Definitions</h2>
+<h2 id="definitions"><a class="header" href="#definitions">Definitions</a></h2>
<p>Here we define the two valences of Transpose more precisely.</p>
<p>An atom right argument to either valence of Transpose is always enclosed to get an array before doing anything else.</p>
<p>Monadic transpose is identical to <code><span class='Paren'>(</span><span class='Function'>=-</span><span class='Number'>1</span><span class='Modifier'>˙</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>⍉</span></code>, except that if <code><span class='Value'>𝕩</span></code> is a unit it is returned unchanged (after enclosing, if it's an atom) rather than giving an error.</p>
diff --git a/docs/doc/types.html b/docs/doc/types.html
index 1fffb7d1..075a0878 100644
--- a/docs/doc/types.html
+++ b/docs/doc/types.html
@@ -4,7 +4,7 @@
<title>BQN: Types</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="types">Types</h1>
+<h1 id="types"><a class="header" href="#types">Types</a></h1>
<p>BQN supports the following fundamental types:</p>
<ul>
<li><a href="#numbers">Number</a></li>
@@ -44,11 +44,11 @@
<p>The reason operations and namespaces are called &quot;mutable&quot; is that the values obtained from them—by calling an operation on particular arguments or reading a field from a namespace—may change over the course of the program. This property is caused by variable modification <code><span class='Gets'>↩</span></code>, which can directly change a namespace field, or change the behavior of an operation that uses the modified variable. This means that a program that doesn't include <code><span class='Gets'>↩</span></code> won't have such changes in behavior. However, there will still be an observable difference between immutable data and the mutable types: code that creates a mutable value (for example, a block function <code><span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code>) creates a different one each time, so that two different instances don't <a href="match.html">match</a> (<code><span class='Function'>≡</span></code>) each other. Data values created at different times may match, but mutable values never will.</p>
<p>An array is considered immutable because its shape, and what elements it contains, cannot change. An array has no identity outside these properties (and possibly its <a href="fill.html">fill element</a>), so an array with a different shape or different elements would simply be a different array. However, any element of an array could be mutable, in which case the behavior of the array would change with respect to the operation of selecting that element and calling it or accessing a field.</p>
-<h2 id="data-types">Data types</h2>
+<h2 id="data-types"><a class="header" href="#data-types">Data types</a></h2>
<p>Data types—numbers, characters, and arrays—are more like &quot;things&quot; than &quot;actions&quot;. If called as a function, a value of one of these types simply returns itself. Data can be uniquely represented, compared for equality, and ordered using BQN's <a href="order.html#array-ordering">array ordering</a>; in contrast, determining whether two functions always return the same result can be undecidable. For arrays, these properties apply only if there are no operations inside. We might say that &quot;data&quot; in BQN refers to numbers, characters, and arrays of data.</p>
-<h3 id="numbers">Numbers</h3>
+<h3 id="numbers"><a class="header" href="#numbers">Numbers</a></h3>
<p>The BQN spec allows for different numeric models to be used, but requires there to be only one numeric type from the programmer's perspective: while programs can often be executed faster by using limited-range integer types, there is no need to expose these details to the programmer. Existing BQN implementations are based on <a href="https://en.wikipedia.org/wiki/IEEE-754">double-precision floats</a>, like Javascript or Lua.</p>
-<h3 id="characters">Characters</h3>
+<h3 id="characters"><a class="header" href="#characters">Characters</a></h3>
<p>A character in BQN is always a <a href="https://en.wikipedia.org/wiki/Unicode">Unicode</a> code point. BQN does not use encodings such as UTF-8 or UTF-16 for characters, although it would be possible to store arrays of integers or characters that correspond to data in these encodings. Because every code point corresponds to a single unit in UTF-32, BQN characters can be thought of as UTF-32 encoded.</p>
<p>Addition and subtraction <a href="arithmetic.html#character-arithmetic">treat</a> characters as an <a href="http://videocortex.io/2018/Affine-Space-Types/">affine space</a> relative to the linear space of numbers. This means that:</p>
<ul>
@@ -56,18 +56,18 @@
<li>Two characters can be subtracted to get the distance between them—a number.</li>
</ul>
<p>Other linear combinations such as adding two characters or negating a character are not allowed. You can check whether an application of <code><span class='Function'>+</span></code> or <code><span class='Function'>-</span></code> on numbers and characters is allowed by applying the same function to the &quot;characterness&quot; of each value: <code><span class='Number'>0</span></code> for a number and <code><span class='Number'>1</span></code> for a character. The result will be a number if this application gives <code><span class='Number'>0</span></code> and a character if this gives <code><span class='Number'>1</span></code>, and otherwise the operation is not allowed.</p>
-<h3 id="arrays">Arrays</h3>
+<h3 id="arrays"><a class="header" href="#arrays">Arrays</a></h3>
<p><em>Full documentation <a href="array.html">here</a>.</em></p>
<p>A BQN array is a multidimensional arrangement of data. This means it has a certain <a href="shape.html"><em>shape</em></a>, which is a finite list of natural numbers giving the length along each axis, and it contains an <em>element</em> for each possible <a href="indices.html"><em>index</em></a>, which is a choice of one natural number that's less than each axis length in the shape. The total number of elements, or <em>bound</em>, is then the product of all the lengths in the shape. The shape may have any length including zero, and this shape is known as the array's <em>rank</em>. An array of rank 0, which always contains exactly one element, is called a <em>unit</em>, while an array of rank 1 is called a <em>list</em> and an array of rank 2 is called a <em>table</em>.</p>
<p>Each array—empty or nonempty—has an inferred property called a <a href="fill.html"><em>fill</em></a>. The fill either indicates what element should be used to pad an array, or that such an element is not known and an error should result. Fills can be used by <a href="take.html">Take</a> (<code><span class='Function'>↑</span></code>), the two <a href="shift.html">Nudge</a> functions (<code><span class='Function'>»«</span></code>), <a href="couple.html">Merge</a> (<code><span class='Function'>&gt;</span></code>), and <a href="reshape.html">Reshape</a> (<code><span class='Function'>⥊</span></code>).</p>
<p>Arrays are value types (or immutable), so that there is no way to &quot;change&quot; the shape or elements of an array. An array with different properties is a different array. As a consequence, arrays are an inductive type, and it's not possible for an array to contain itself, or contain an array that contains itself, and so on. However, it is possible for an array to contain a function or other operation that has access to the array through a variable, and in this sense an array can &quot;know about&quot; itself.</p>
<p>Different elements of an array should not influence each other. While some APLs force numbers placed in the same array to a common representation, which may have different precision properties, BQN values must not change behavior when placed in an array. However, this doesn't preclude changing the storage type of an array for better performance: for example, in a BQN implementation using 64-bit floats, an array whose elements are all integers that fit in 32-bit int range might be represented as an array of 32-bit ints.</p>
-<h2 id="operation-types">Operation types</h2>
+<h2 id="operation-types"><a class="header" href="#operation-types">Operation types</a></h2>
<p>An operation is either a function or modifier, and can be applied to <em>inputs</em>—which are called <em>arguments</em> for functions and <em>operands</em> for modifiers—to obtain a result. During this application an operation might also change variables within its scope and call other operations, or cause an error, in which case it doesn't return a result. There is one type of call for each of the three operation types, and an operation will give an error if it is called in a way that doesn't match its type.</p>
<p>In BQN syntax the result of a function has a subject role and the result of a modifier has a function role. However, the result can be any value at all: roles take place at the syntactic level, which has no bearing on types and values in the semantic level. This distinction is discussed further in <a href="context.html#mixing-roles">Mixing roles</a>.</p>
-<h3 id="functions">Functions</h3>
+<h3 id="functions"><a class="header" href="#functions">Functions</a></h3>
<p>A function is called with one or two arguments. A data value (number, character, or array) can also be called the same way, but only a function takes any action when passed arguments, as data just returns itself. Both the one-argument and two-argument calls are considered function calls, and it's common for a function to allow both. A function that always errors in one case or the other might be called a one-argument or two-argument function, depending on which case is allowed.</p>
-<h3 id="modifiers">Modifiers</h3>
+<h3 id="modifiers"><a class="header" href="#modifiers">Modifiers</a></h3>
<p>A 1-modifier is called with one operand, while a 2-modifier is called with two. In contrast to functions, these are distinct types, and it is impossible to have a value that can be called with either one or two operands. Also in contrast to functions, data values cannot be called as modifiers: they will cause an error if called this way.</p>
-<h2 id="namespaces">Namespaces</h2>
+<h2 id="namespaces"><a class="header" href="#namespaces">Namespaces</a></h2>
<p>Functions and modifiers have internal scopes which they can manipulate (by defining and modifying variables) to save and update information. Namespaces let the programmer to expose this state more directly: identifiers in a namespace may be exported, allowing code outside the namespace to read their values. They are described in detail <a href="namespace.html">here</a>.</p>
diff --git a/docs/doc/undo.html b/docs/doc/undo.html
index dc3f9d37..5e7d6276 100644
--- a/docs/doc/undo.html
+++ b/docs/doc/undo.html
@@ -4,7 +4,7 @@
<title>BQN: Undo</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="undo">Undo</h1>
+<h1 id="undo"><a class="header" href="#undo">Undo</a></h1>
<p>Oh no, you've deleted a function after spending half an hour writing it! Well… hopefully your editor can help with that. But maybe you'll be interested to hear that BQN can reverse the action of some functions—ones that <em>don't</em> lose information. This capability is also used by <a href="repeat.html">Repeat</a> (<code><span class='Modifier2'>⍟</span></code>) to repeat a negative number of times.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MiDijL0gImFiY2RlIgoKMiDijL3igbwgMiDijL0gImFiY2RlIg==">↗️</a><pre> <span class='Number'>2</span> <span class='Function'>⌽</span> <span class='String'>&quot;abcde&quot;</span>
"cdeab"
@@ -20,7 +20,7 @@
"BQN"
</pre>
<p>Here it undoes a function to decrement the last character by incrementing that character. In part this is enabled by the clean design of BQN primitives, because better-behaved functions like those using structural Under are easier to invert.</p>
-<h2 id="the-rules">The rules</h2>
+<h2 id="the-rules"><a class="header" href="#the-rules">The rules</a></h2>
<p>If <code><span class='Function'>𝔽</span></code> can be inverted exactly, then Undo just does that. However, there are also some other functions that BQN inverts. For example, the squaring function <code><span class='Function'>×</span><span class='Modifier'>˜</span></code> has both a positive and a negative inverse, and yet:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=w5fLnCDCrzMKw5fLnOKBvCDDl8ucIMKvMyAgIyBJdCdzIG5vdCB0aGUgc2FtZSE=">↗️</a><pre> <span class='Function'>×</span><span class='Modifier'>˜</span> <span class='Number'>¯3</span>
9
@@ -32,7 +32,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=NiAtIOKImuKBvOKImjY=">↗️</a><pre> <span class='Number'>6</span> <span class='Function'>-</span> <span class='Function'>√</span><span class='Modifier'>⁼</span><span class='Function'>√</span><span class='Number'>6</span>
8.881784197001252e¯16
</pre>
-<h2 id="whats-supported">What's supported?</h2>
+<h2 id="whats-supported"><a class="header" href="#whats-supported">What's supported?</a></h2>
<p>For the full list, see <a href="../spec/inferred.html#undo">the specification</a>. An individual implementation might support a lot more functionality than is required, so if you're not concerned about portability just try out whatever function you're interested in.</p>
<p>Arithmetic and simple combinators are usually invertible. A compound function that refers to its argument just once, like <code><span class='Number'>6</span><span class='Function'>+⌽</span><span class='Modifier2'>∘</span><span class='Function'>⍉</span></code>, can typically be undone, but one that uses the argument in two different ways, such as <code><span class='Function'>⊢+⋆</span></code>, probably can't.</p>
<p>A few notable inverses are the <a href="arithmetic.html#basic-arithmetic">logarithm</a> <code><span class='Function'>⋆</span><span class='Modifier'>⁼</span></code>, <a href="transpose.html">un-Transpose</a> <code><span class='Function'>⍉</span><span class='Modifier'>⁼</span></code>, and <a href="replicate.html#inverse">Indices inverse</a> <code><span class='Function'>/</span><span class='Modifier'>⁼</span></code>. <a href="enclose.html">Enclose</a> inverse, <code><span class='Function'>&lt;</span><span class='Modifier'>⁼</span></code>, is an alternative to <a href="pick.html#first">First</a> that requires its argument to be a unit.</p>
@@ -42,7 +42,7 @@ ERROR
<span class='Number'>3</span> <span class='Function'>⊣</span><span class='Modifier'>⁼</span> <span class='Number'>3</span>
3
</pre>
-<h2 id="undo-headers">Undo headers</h2>
+<h2 id="undo-headers"><a class="header" href="#undo-headers">Undo headers</a></h2>
<p>Undo headers are currently supported only by dzaima/BQN.</p>
<p>Of course BQN will never be able to invert all the functions you could write (if it could you could earn a <em>lot</em> of bitcoins, among other feats). But it does recognize some <a href="block.html#block-headers">header</a> forms that you can use to specify the inverse of a block function. BQN will trust you and won't verify the results your specified inverse gives.</p>
<pre><span class='Brace'>{</span>
diff --git a/docs/doc/windows.html b/docs/doc/windows.html
index bc2aa263..77c40f19 100644
--- a/docs/doc/windows.html
+++ b/docs/doc/windows.html
@@ -4,10 +4,10 @@
<title>BQN: Windows</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
-<h1 id="windows">Windows</h1>
+<h1 id="windows"><a class="header" href="#windows">Windows</a></h1>
<p>In BQN, it's strongly preferred to use functions, and not modifiers, for array manipulation. Functions are simpler as they have fewer moving parts. They are more concrete, since the array results can always be viewed right away. They are easier to implement with reasonable performance as well, since there is no need to recognize many possible function operands as special cases.</p>
<p>The Window function replaces APL's Windowed Reduction, J's more general Infix operator, and Dyalog's Stencil, which is adapted from one case of J's Cut operator.</p>
-<h2 id="definition">Definition</h2>
+<h2 id="definition"><a class="header" href="#definition">Definition</a></h2>
<p>We'll start with the one-axis case. Here Window's left argument is a number between <code><span class='Number'>0</span></code> and <code><span class='Number'>1</span><span class='Function'>+≠</span><span class='Value'>𝕩</span></code>. The result is composed of slices of <code><span class='Value'>𝕩</span></code> (contiguous sections of major cells) with length <code><span class='Value'>𝕨</span></code>, starting at each possible index in order.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=NeKGlSJhYmNkZWZnIg==">↗️</a><pre> <span class='Number'>5</span><span class='Function'>↕</span><span class='String'>&quot;abcdefg&quot;</span>
┌─
@@ -24,7 +24,7 @@
"cdefg"
</pre>
<p>Windows differs from Prefixes and Suffixes in that it doesn't add a layer of nesting (it doesn't enclose each slice). This is possible because the slices have a fixed size.</p>
-<h3 id="multiple-dimensions">Multiple dimensions</h3>
+<h3 id="multiple-dimensions"><a class="header" href="#multiple-dimensions">Multiple dimensions</a></h3>
<p>The above description applies to a higher-rank right argument. As an example, we'll look at two-row slices of a shape <code><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>4</span></code> array. For convenience, we will enclose each slice. Note that slices always have the same rank as the argument array.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=POKOiTIgMuKGlSIwMTIzIuKIviJhYmNkIuKJjSJBQkNEIg==">↗️</a><pre> <span class='Function'>&lt;</span><span class='Modifier2'>⎉</span><span class='Number'>2</span> <span class='Number'>2</span><span class='Function'>↕</span><span class='String'>&quot;0123&quot;</span><span class='Function'>∾</span><span class='String'>&quot;abcd&quot;</span><span class='Function'>≍</span><span class='String'>&quot;ABCD&quot;</span>
┌─
@@ -49,10 +49,10 @@
</pre>
<p>The slices are naturally arranged along multiple dimensions according to their starting index. Once again the equivalence <code><span class='Value'>i</span><span class='Function'>⊏</span><span class='Value'>l</span><span class='Function'>↕</span><span class='Value'>x</span></code> ←→ <code><span class='Value'>l</span><span class='Function'>↑</span><span class='Value'>i</span><span class='Function'>↓</span><span class='Value'>x</span></code> holds, provided <code><span class='Value'>i</span></code> and <code><span class='Value'>l</span></code> have the same length.</p>
<p>If <code><span class='Value'>𝕨</span></code> has length <code><span class='Number'>0</span></code>, then <code><span class='Value'>𝕩</span></code> is not sliced along any dimensions. The only slice that results—the entire argument—is then arranged along an additional zero dimensions. In the end, the result is <code><span class='Value'>𝕩</span></code>, unchanged.</p>
-<h3 id="more-formally">More formally</h3>
+<h3 id="more-formally"><a class="header" href="#more-formally">More formally</a></h3>
<p><code><span class='Value'>𝕩</span></code> is an array. <code><span class='Value'>𝕨</span></code> is a number, or numeric list or unit, with <code><span class='Value'>𝕨</span><span class='Function'>≤</span><span class='Modifier2'>○</span><span class='Function'>≠≢</span><span class='Value'>𝕩</span></code>. The result <code><span class='Value'>z</span></code> has shape <code><span class='Value'>𝕨</span><span class='Function'>∾¬</span><span class='Modifier2'>⟜</span><span class='Value'>𝕨</span><span class='Modifier2'>⌾</span><span class='Paren'>((</span><span class='Function'>≠</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>↑</span><span class='Paren'>)</span><span class='Function'>≢</span><span class='Value'>𝕩</span></code>, and element <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>z</span></code> is <code><span class='Value'>𝕩</span><span class='Function'>⊑</span><span class='Modifier'>˜</span><span class='Paren'>(</span><span class='Function'>≠</span><span class='Value'>𝕨</span><span class='Paren'>)(</span><span class='Function'>↑+</span><span class='Modifier2'>⌾</span><span class='Paren'>((</span><span class='Function'>≠</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>↑</span><span class='Paren'>)</span><span class='Function'>↓</span><span class='Paren'>)</span><span class='Value'>i</span></code>.</p>
<p>Using <a href="group.html">Group</a> we could also write <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>z</span></code> ←→ <code><span class='Value'>𝕩</span><span class='Function'>⊑</span><span class='Modifier'>˜</span><span class='Paren'>(</span><span class='Value'>𝕨</span><span class='Function'>∾</span><span class='Modifier2'>○</span><span class='Paren'>(</span><span class='Function'>↕</span><span class='Modifier2'>∘</span><span class='Function'>≠</span><span class='Paren'>)</span><span class='Function'>≢</span><span class='Value'>𝕩</span><span class='Paren'>)</span> <span class='Function'>+</span><span class='Modifier'>´¨</span><span class='Modifier2'>∘</span><span class='Function'>⊔</span> <span class='Value'>i</span></code>.</p>
-<h2 id="symmetry">Symmetry</h2>
+<h2 id="symmetry"><a class="header" href="#symmetry">Symmetry</a></h2>
<p>Let's look at an earlier example, along with its <a href="transpose.html">Transpose</a> (<code><span class='Function'>⍉</span></code>).</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=e+KfqPCdlaks4o2J8J2VqeKfqX014oaVImFiY2RlZmci">↗️</a><pre> <span class='Brace'>{</span><span class='Bracket'>⟨</span><span class='Value'>𝕩</span><span class='Separator'>,</span><span class='Function'>⍉</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span><span class='Brace'>}</span><span class='Number'>5</span><span class='Function'>↕</span><span class='String'>&quot;abcdefg&quot;</span>
┌─
@@ -77,7 +77,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eygoNeKAvzbCrDLigL8yKeKGlfCdlakpIOKJoSAy4oC/M+KNiSgy4oC/MuKGlfCdlakpfSDihpU14oC/NuKAvzc=">↗️</a><pre> <span class='Brace'>{</span><span class='Paren'>((</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Function'>¬</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Paren'>)</span><span class='Function'>↕</span><span class='Value'>𝕩</span><span class='Paren'>)</span> <span class='Function'>≡</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Function'>⍉</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Function'>↕</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Brace'>}</span> <span class='Function'>↕</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Ligature'>‿</span><span class='Number'>7</span>
1
</pre>
-<h2 id="applications">Applications</h2>
+<h2 id="applications"><a class="header" href="#applications">Applications</a></h2>
<p>Windows can be followed up with a <a href="fold.html#insert">reduction</a> on each slice to give a windowed reduction. Here we take running sums of 3 values.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=K8udy5gz4oaVIOKfqDIsNiwwLDEsNCwz4p+p">↗️</a><pre> <span class='Function'>+</span><span class='Modifier'>˝˘</span><span class='Number'>3</span><span class='Function'>↕</span> <span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Number'>6</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Number'>4</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Bracket'>⟩</span>
⟨ 8 7 5 8 ⟩
diff --git a/docs/editors/index.html b/docs/editors/index.html
index 882525c6..a787eeeb 100644
--- a/docs/editors/index.html
+++ b/docs/editors/index.html
@@ -4,7 +4,7 @@
<title>BQN: Editor support</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a></div>
-<h1 id="editor-support">Editor support</h1>
+<h1 id="editor-support"><a class="header" href="#editor-support">Editor support</a></h1>
<style>.Comment,.Function,.Number,.String { color: inherit; }</style>
<p>Editor plugins and other tools for allowing BQN input are in <a href="https://github.com/mlochbaum/BQN/tree/master/editors">this folder</a>. Input is always performed with a backslash <code><span class='Value'>\</span></code> prefix by default, using the layout shown <a href="https://mlochbaum.github.io/BQN/keymap.html">here</a>. To type an actual backslash, hit the backslash key twice.</p>
<p><a href="https://abrudz.github.io/lb/bqn">This bookmarklet</a> enables BQN input in any webpage in your <strong>browser</strong>.</p>
@@ -12,29 +12,29 @@
<p>For <strong>Android</strong>, <a href="https://github.com/dzaima/hackerskeyboard/releases/latest">this fork</a> adds APL and BQN to Hacker's Keyboard.</p>
<p>The file <a href="https://github.com/mlochbaum/BQN/blob/master/editors/inputrc">inputrc</a> can be copied or appended to <code><span class='Value'>~</span><span class='Function'>/</span><span class='Value'>.inputrc</span></code> to enable backslash input in <strong>bash</strong>, BQN with <strong>rlwrap</strong>, and other software that uses GNU Readline.</p>
<p>If you'd like to contribute files for another editor I'd gladly accept them!</p>
-<h2 id="system-wide">System-wide</h2>
-<h3 id="xkb-unix">XKB (Unix)</h3>
+<h2 id="system-wide"><a class="header" href="#system-wide">System-wide</a></h2>
+<h3 id="xkb-unix"><a class="header" href="#xkb-unix">XKB (Unix)</a></h3>
<p>The file <a href="https://github.com/mlochbaum/BQN/blob/master/editors/bqn">bqn</a> is for configuring XKB on Linux, or other systems using X11. To use, copy it to <code><span class='Function'>/</span><span class='Value'>usr</span><span class='Function'>/</span><span class='Value'>share</span><span class='Function'>/X11/</span><span class='Value'>xkb</span><span class='Function'>/</span><span class='Value'>symbols</span><span class='Function'>/</span></code>, then run</p>
<pre><span class='Value'>$</span> <span class='Value'>setxkbmap</span> <span class='Function'>-</span><span class='Value'>layout</span> <span class='Value'>us</span><span class='Separator'>,</span><span class='Value'>bqn</span> <span class='Function'>-</span><span class='Value'>option</span> <span class='Value'>grp:switch</span>
</pre>
<p>replacing <code><span class='Value'>us</span></code> with your ordinary keyboard layout. <code><span class='Value'>switch</span></code> indicates the right alt key and can be replaced with <code><span class='Value'>lswitch</span></code> for left alt or other codes. The setting will go away on shutdown so you will probably want to configure it to run every time you start up. The way to do this depends on your desktop environment. For further discussion, see <a href="https://en.wikipedia.org/wiki/X_keyboard_extension">Wikipedia</a> or the <a href="https://aplwiki.com/wiki/Typing_glyphs_on_Linux">APL Wiki</a>.</p>
<p>Another XKB option, if you have a compose key enabled, is to place <a href="https://github.com/mlochbaum/BQN/blob/master/editors/XCompose">XCompose</a> (possibly with adjustments) in <code><span class='Value'>~</span><span class='Function'>/</span><span class='Value'>.</span><span class='Function'>XCompose</span></code>.</p>
-<h3 id="windows">Windows</h3>
+<h3 id="windows"><a class="header" href="#windows">Windows</a></h3>
<p>Folder <a href="https://github.com/mlochbaum/BQN/tree/master/editors/autohotkey-win">autohotkey-win</a> contains an <a href="https://en.wikipedia.org/wiki/AutoHotKey">AutoHotKey</a> script and the generated .exe file. It runs as an ordinary program that recognizes BQN key combinations system-wide, using the right alt key (to change this, replace <code><span class='Function'>RAlt</span></code> in the script and rebuild). Move it to the startup folder if you'd like to have it running all the time. You can right-click its icon in the system tray to disable it temporarily.</p>
<p>The <a href="https://github.com/mlochbaum/BQN/blob/master/editors/XCompose">XCompose</a> file, although created for XKB, should also be usable with <a href="https://github.com/samhocevar/wincompose">WinCompose</a> (but as far as I know this hasn't been tested).</p>
-<h2 id="text-editors">Text editors</h2>
-<h3 id="vim">Vim</h3>
+<h2 id="text-editors"><a class="header" href="#text-editors">Text editors</a></h2>
+<h3 id="vim"><a class="header" href="#vim">Vim</a></h3>
<p>Copy or symlink all files into the corresponding directories in <code><span class='Value'>~</span><span class='Function'>/</span><span class='Value'>.vim</span></code>. Add the following two lines to <code><span class='Value'>~</span><span class='Function'>/</span><span class='Value'>.vim</span><span class='Function'>/</span><span class='Value'>filetype.vim</span></code>:</p>
<pre> <span class='Value'>au</span><span class='Function'>!</span> <span class='Function'>BufRead</span><span class='Separator'>,</span><span class='Function'>BufNewFile</span> <span class='Value'>*.bqn</span> <span class='Value'>setf</span> <span class='Value'>bqn</span>
<span class='Value'>au</span><span class='Function'>!</span> <span class='Function'>BufRead</span><span class='Separator'>,</span><span class='Function'>BufNewFile</span> <span class='Value'>*</span> <span class='Value'>if</span> <span class='Value'>getline</span><span class='Paren'>(</span><span class='Number'>1</span><span class='Paren'>)</span> <span class='Function'>=</span><span class='Value'>~</span> <span class='String'>'</span><span class='Value'>^</span><span class='Comment'>#!.*bqn$' | setf bqn | endif
</span></pre>
<p>Include <code><span class='Value'>syntax</span> <span class='Value'>on</span></code> in your .vimrc for syntax highlighting and <code><span class='Value'>filetype</span> <span class='Value'>plugin</span> <span class='Value'>on</span></code> for keyboard input.</p>
-<h3 id="emacs">Emacs</h3>
+<h3 id="emacs"><a class="header" href="#emacs">Emacs</a></h3>
<p>Add the following two lines to <code><span class='Value'>init.el</span></code> (usually <code><span class='Value'>~</span><span class='Function'>/</span><span class='Value'>.emacs.d</span><span class='Function'>/</span><span class='Value'>init.el</span></code>), replacing the path appropriately.</p>
<pre><span class='Paren'>(</span><span class='Value'>add</span><span class='Function'>-</span><span class='Value'>to</span><span class='Function'>-</span><span class='Value'>list</span> <span class='String'>'</span><span class='Value'>load</span><span class='Function'>-</span><span class='Value'>path</span> <span class='String'>&quot;/path/to/BQN/editors/emacs&quot;</span><span class='Paren'>)</span>
<span class='Paren'>(</span><span class='Value'>require</span> <span class='String'>'</span><span class='Value'>gnu</span><span class='Function'>-</span><span class='Value'>apl</span><span class='Function'>-</span><span class='Value'>mode</span><span class='Paren'>)</span>
</pre>
-<h3 id="vs-code">VS Code</h3>
+<h3 id="vs-code"><a class="header" href="#vs-code">VS Code</a></h3>
<p>See <a href="https://github.com/razetime/bqn-vscode">this repository</a>.</p>
-<h3 id="kakoune">Kakoune</h3>
+<h3 id="kakoune"><a class="header" href="#kakoune">Kakoune</a></h3>
<p>Copy or symlink <code><span class='Value'>kak</span><span class='Function'>/</span><span class='Value'>autoload</span><span class='Function'>/</span><span class='Value'>filetype</span><span class='Function'>/</span><span class='Value'>bqn.kak</span></code> into <code><span class='Value'>autoload</span><span class='Function'>/</span><span class='Value'>filetype</span></code> in your Kakoune config directory (probably <code><span class='Value'>.config</span><span class='Function'>/</span><span class='Value'>kak</span><span class='Function'>/</span></code>).</p>
diff --git a/docs/implementation/codfns.html b/docs/implementation/codfns.html
index 57cfa3d5..dcbaae30 100644
--- a/docs/implementation/codfns.html
+++ b/docs/implementation/codfns.html
@@ -4,16 +4,16 @@
<title>Co-dfns versus BQN's implementation</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">implementation</a></div>
-<h1 id="co-dfns-versus-bqns-implementation">Co-dfns versus BQN's implementation</h1>
+<h1 id="co-dfns-versus-bqns-implementation"><a class="header" href="#co-dfns-versus-bqns-implementation">Co-dfns versus BQN's implementation</a></h1>
<p>The BQN self-hosted compiler is directly inspired by the <a href="https://github.com/Co-dfns/Co-dfns">Co-dfns</a> project, a compiler for a subset of <a href="../doc/fromDyalog.html">Dyalog APL</a>. I'm very grateful to Aaron for showing that array-oriented compilation is even possible! In addition to the obvious difference of target language, BQN differs from Co-dfns both in goals and methods.</p>
<p>The shared goals of BQN and Co-dfns are to implement a compiler for an array language with whole-array operations. This provides the theoretical benefit of a short <em>critical path</em>, which in practice means that both compilers can make good use of a GPU or a CPU's vector instructions simply by providing an appropriate runtime (however, only Co-dfns has such a runtime—an ArrayFire program on the GPU and Dyalog APL on the CPU). The two implementations also share a preference for working &quot;close to the metal&quot; by passing around arrays of numbers rather than creating abstract types to work with data. Objects are right out. These choices lead to a compact source code implementation, and may have some benefits in terms of how easy it is to write and understand the compiler.</p>
-<h2 id="compilation-strategy">Compilation strategy</h2>
+<h2 id="compilation-strategy"><a class="header" href="#compilation-strategy">Compilation strategy</a></h2>
<p>Co-dfns development has primarily been focused on the core compiler, and not parsing, code generation, or the runtime. The associated Ph.D. thesis and famous 17 lines figure refer to this section, which transforms the abstract syntax tree (AST) of a program to a lower-level form, and resolves lexical scoping by linking variables to their definitions. While all of Co-dfns is written in APL, other sections aren't necessarily designed to be data-parallel and don't have the same performance guarantees. For example, the parser uses a parsing expression grammar (PEG), a sequential algorithm. In contrast, BQN is entirely written in a data-parallel style. It does not maintain the same clean separation between compiler sections: <a href="../spec/token.html">token formation</a> and literal evaluation is separated into its own function, but parsing, AST manipulation, and code generation overlap.</p>
<p>The core Co-dfns compiler is based on manipulating the syntax tree, which is mostly stored as parent and sibling vectors—that is, lists of indices of other nodes in the tree. BQN is less methodical, but generally treats the source tokens as a simple list. This list is reordered in various ways, allowing operations that behave like tree traversals to be performed with scans under the right ordering. This strategy allows BQN to be much stricter in the kinds of operations it uses. Co-dfns regularly uses <code><span class='Value'>⍣</span><span class='Function'>≡</span></code> (repeat until convergence) for iteration and creates nested arrays with <code><span class='Value'>⌸</span></code> (Key, like <a href="../doc/group.html">Group</a>), but BQN has only a single instance of iteration to resolve quotes and comments, plus one complex but parallelizable scan for numeric literal processing, and only uses Group to extract identifiers and strings. This means that most primitives, if we count simple reductions and scans as single primitives, are executed a fixed number of times during execution, making complexity analysis even easier than in Co-dfns.</p>
-<h2 id="backends-and-optimization">Backends and optimization</h2>
+<h2 id="backends-and-optimization"><a class="header" href="#backends-and-optimization">Backends and optimization</a></h2>
<p>Co-dfns was designed from the beginning to build GPU programs, and outputs code in ArrayFire (a C++ framework), which is then compiled. GPU programming is quite limiting, and as a result Co-dfns has strict limitations in functionality that are slowly being removed. It now has partial support for nested arrays and array ranks higher than 4. BQN is designed with performance in mind, but implementation effort focused on functionality first, so that arbitrary array structures as well as trains and lexical closures have been supported from the beginning. Rather than target a specific language, it outputs object code to be interpreted by a <a href="vm.html">virtual machine</a>. Another goal for BQN was to not only write the compiler in BQN but to use BQN for the runtime as much as possible. The BQN-based runtime uses a small number of basic array operations provided by the VM. The extra abstraction causes this runtime to be very slow, but this can be fixed by overwriting functions from the runtime with natively-implemented ones.</p>
<p>Neither BQN nor Co-dfns significantly optimize their output at the time of writing (it could be said that Co-dfns relies on the ArrayFire backend to optimize). BQN does have one optimization, which is to compute variable lifetimes in functions so that the last access to a variable can clear it. Further optimizations often require finding properties such as reachability in a graph of expressions that probably can't be done efficiently in a strict array style. For this and other reasons it would probably be best to structure compiler optimization as a set of additional modules that can be provided during a given compilation.</p>
-<h2 id="error-reporting">Error reporting</h2>
+<h2 id="error-reporting"><a class="header" href="#error-reporting">Error reporting</a></h2>
<p>Co-dfns doesn't check for compilation errors, while BQN has complete error checking and good error messages, and includes source positions in compiler errors as well as in the compiled code for use in runtime errors. Position tracking and error checking add up to a little more than 20% overhead for the compiler, both in runtime and lines of code. And improving the way errors are reported once found has no cost for working programs, because reporting code only needs to be run if there's a compiler error. This leaves room for potentially very sophisticated error analysis to attempt to track down the root cause of a compilation error, but I haven't yet done any work along these lines.</p>
-<h2 id="comments">Comments</h2>
+<h2 id="comments"><a class="header" href="#comments">Comments</a></h2>
<p>Aaron advocates the almost complete separation of code from comments (thesis) in addition to his very terse style as a general programming methodology. I find that this practice makes it hard to connect the documentation to the code, and is very slow in providing a summary or reminder of functionality that a comment might. One comment on each line makes a better balance of compactness and faster accessibility in my opinion. However, I do plan to write long-form material providing the necessary context and explanations required to understand the compiler.</p>
diff --git a/docs/implementation/compile/dynamic.html b/docs/implementation/compile/dynamic.html
index 1edb73ef..0ffb6c46 100644
--- a/docs/implementation/compile/dynamic.html
+++ b/docs/implementation/compile/dynamic.html
@@ -4,12 +4,12 @@
<title>BQN: Dynamic compilation</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../../index.html">BQN</a> / <a href="../index.html">implementation</a> / <a href="index.html">compile</a></div>
-<h1 id="dynamic-compilation">Dynamic compilation</h1>
+<h1 id="dynamic-compilation"><a class="header" href="#dynamic-compilation">Dynamic compilation</a></h1>
<p>This page discusses at a high level (without covering any specific source transformations) how compilation and interpretation might be structured in order to execute BQN faster. Effective strategies will compile parts of the program with more specialization or higher optimization as it runs and more information about it becomes known.</p>
<p>To avoid confusion, an <strong>interpreter</strong> evaluates code to perform actions or produce a result; a CPU is a machine code interpreter. A <strong>compiler</strong> transforms code in one language or format to another. To run a program that does anything, it must eventually be interpreted; before this the program or parts of it might be compiled any number of times.</p>
<p>The starting point for algorithms described here is bytecode for the BQN <a href="../vm.html">virtual machine</a>. Producing this bytecode mostly amounts to parsing the program, which any implementation would have to do anyway, and it's fast enough that compiling an entire file before starting isn't a big concern. The bytecode can be interpreted directly, but compiler passes can reduce the overhead for each instruction or implement groups of instructions more effectively. Sophisticated compiler passes cost time, so the improvement must be balanced against time spent even though it might not be known in advance.</p>
-<h2 id="considerations">Considerations</h2>
-<h3 id="what-are-we-optimizing">What are we optimizing?</h3>
+<h2 id="considerations"><a class="header" href="#considerations">Considerations</a></h2>
+<h3 id="what-are-we-optimizing"><a class="header" href="#what-are-we-optimizing">What are we optimizing?</a></h3>
<p>How a program can be optimized depends on why it's taking time to run. Here we'll assume it's the core BQN syntax and primitives that are responsible, as things like system interaction are out of scope, and that the source file is not unreasonably large. The total time taken is the sum of the time taken by each action performed, so there are two main possibilities:</p>
<ul>
<li>Primitives take a long time, because of large arrays.</li>
@@ -18,7 +18,7 @@
<p>If many bytecode instructions are evaluated, it must be that blocks are repeated, because each instruction can only be run once by its containing block. A derived function might be run many times by a modifier, which typically involves a large array, but could also be because of Repeat (<code><span class='Modifier2'>⍟</span></code>).</p>
<p>This is an array-based viewpoint, because in a low-level language the large array case would just be considered one of several kinds of repetition. Traditionally APL focused exclusively on speeding up the large array case; BQN's compilation makes better block performance a reachable goal.</p>
<p>The two conditions are routinely mixed in various ways: a program might split its time between manipulating small and large arrays, or it might work with large arrays but sometimes apply a block function to each element or small groups of elements. Array size or number of iterations could even differ between program runs. An evaluation strategy needs to adapt to these changes.</p>
-<h3 id="hardware">Hardware</h3>
+<h3 id="hardware"><a class="header" href="#hardware">Hardware</a></h3>
<p>It's easiest to get BQN running on a single-threaded scalar CPU, but all of the following improvements are commonly available, and can greatly increase speed for some programs:</p>
<ul>
<li>SIMD instructions</li>
@@ -27,30 +27,30 @@
</ul>
<p>Each of the three is a good fit for array programming: any size array with SIMD and large arrays for multi-threading and GPU use. Multi-threading can also be useful for blocks that don't have side effects.</p>
<p>SIMD instructions can be used at the primitive level (<a href="../primitive/index.html">primitive implementation notes</a>), with some improvement by fusing small operations together. Multi-threading is also possible at the primitive level, but no coordination between primitives will lead to cache coherency issues, and wasted time as some cores wait for others. It's probably better to analyze groups of primitives to allocate data and work. GPU execution is the fastest method for suitable programs, but can only handle certain kinds of code well and must use compiled kernels, which need to do a significant amount of work to justify the overhead.</p>
-<h3 id="cached-optimization">Cached optimization</h3>
+<h3 id="cached-optimization"><a class="header" href="#cached-optimization">Cached optimization</a></h3>
<p>Expensive ahead-of-time optimizations can be saved somewhere in the filesystem (presumably the XDG cache directory for Linux). This of course introduces the problem of cache invalidation: cache files need to be versioned so an old cache isn't used by a new BQN, and they need to be thrown out when the file is changed and avoid saving information about user input or external files that could change.</p>
<p>I think the data about a BQN source file that can be saved is generally pretty cheap to compute, and it's also important to make sure completely new code runs quickly. I'm hoping we don't have a reason to resort to caching.</p>
-<h2 id="strategies">Strategies</h2>
-<h3 id="hot-paths">Hot paths</h3>
+<h2 id="strategies"><a class="header" href="#strategies">Strategies</a></h2>
+<h3 id="hot-paths"><a class="header" href="#hot-paths">Hot paths</a></h3>
<p>The basic strategy for JIT compilers like Java and Javascript (hey, they do actually have something in common!) is to track the number of times a block is called and perform more optimization as this number increases. It's also possible to record information about the inputs to do more specialized compilation, usually with a test in the compiled code to abort when the specialization is invalid.</p>
<p>CBQN already includes a count to control native compilation; because this compilation is fast the best value is very low, between 1 and 5. More powerful optimization would generally use higher counts.</p>
<p>Iteration modifiers <code><span class='Modifier'>˘</span><span class='Modifier2'>⎉</span><span class='Modifier'>¨⌜´˝`</span><span class='Modifier2'>⍟</span></code> can compute how many times they will call the operand quickly: it's usually based on the result size or argument length. The slowest case is probably monadic Scan <code><span class='Modifier'>`</span></code>, where it's the size of <code><span class='Value'>𝕩</span></code> minus the cell size, both values that already need to be computed. This number can be added to the existing count to find what level of optimization would be used, or even compared without adding, if false negatives are acceptable. This reduces the number of times the program runs blocks at the wrong optimization level, but slightly increases the overhead of mapping modifiers even on calls where the block to be run is already optimized at a high level. It can be restricted to only modifiers with a block operand because the modifier needs to inspect its operand anyway—the cost of running <code><span class='Function'>=</span><span class='Modifier'>⌜</span></code> or <code><span class='Function'>+</span><span class='Modifier'>´</span></code> without optimization is too high to skip this.</p>
<p>Iteration modifiers on typed arrays often allow the argument types to be known with certainty, so that the operand can be specialized on that type with no testing.</p>
-<h3 id="metadata">Metadata</h3>
+<h3 id="metadata"><a class="header" href="#metadata">Metadata</a></h3>
<p>There's a lot of information about values that can be used to optimize, either in the general case if it's known for sure, or a specialization if it's suspected, or known under specific conditions. Type is the most important, then depth, rank, shape and element metadata for arrays and range or even value for numbers and characters. Other bulk properties like sortedness (to enable faster searches) or sum (for example, to find the shape of <code><span class='Function'>/</span><span class='Value'>𝕩</span></code>) can be useful for arrays.</p>
<p>Proofs that constrain the metadata in all cases are the most valuable, since the properties don't have to be tested or recomputed if they're already known. One way to get this information is to do an initial run of a block that only propagates known information about metadata. For example, if <code><span class='Brace'>{</span><span class='Function'>+</span><span class='Modifier'>´</span><span class='Function'>↕</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> is run on an integer array, <code><span class='Function'>↕</span></code> can return a list of natural numbers with the same type as <code><span class='Value'>𝕩</span></code> or cause an error, and <code><span class='Function'>+</span><span class='Modifier'>´</span></code>, given a list of natural numbers, returns a natural number. This approach can only help if the block will be run multiple times: clearly for a single run computing metadata along with data is the fastest. It runs at interpreted rather than native speed (because it's only run once) and could in fact take many calls to break even. For large array code, where the interpretive overhead is irrelevant, it could also be a step before a compilation pass that fuses and rearranges primitives.</p>
<p>The same procedure can be run on local rather than global constraints, which might produce more specialized code at the cost of running through the block once per specialization.</p>
<p>Saving metadata from the first run is another possibility, with very low overhead. This most naturally provides a guess as to what the metadata usually is, but it may also be possible to keep track of when metadata is &quot;known&quot; with a flag system.</p>
<p>The desire to do metadata computations, or pure data ones once metadata is known suggests a system with a &quot;wrapper&quot; that computes type, shape, and so on, then selects and calls an &quot;kernel&quot; function for the computation. Specialized code could use a particular kernel, or a different wrapper that selects from a subset of the kernels.</p>
-<h3 id="derived-functions">Derived functions</h3>
+<h3 id="derived-functions"><a class="header" href="#derived-functions">Derived functions</a></h3>
<p>Like blocks, it can be valuable to optimize derived functions if they are run many times. Derived functions are often known at the program start by constant folding, but might also be constructed dynamically, particularly to bind an argument to a function.</p>
<p>Compound arithmetic functions like <code><span class='Function'>+</span><span class='Modifier'>´</span></code>, <code><span class='Function'>⌈</span><span class='Modifier'>`</span></code>, or <code><span class='Function'>=</span><span class='Modifier'>⌜</span></code> are essential to array programming, and have fast SIMD implementations, so they need to be recognized wherever they are found.</p>
<p>In addition to these, there are patterns like <code><span class='Function'>≠</span><span class='Modifier'>¨</span><span class='Modifier2'>∘</span><span class='Function'>⊔</span></code> that can be implemented faster than their components, and bindings like <code><span class='Value'>l</span><span class='Modifier2'>⊸</span><span class='Function'>⊐</span></code> where a computation (here, a hash table) on the left argument can be saved. These can be handled by inspecting the function. However, it's more robust to convert it to a canonical form, so this possibility should also be considered.</p>
<p>Tacit code can be converted to <a href="https://en.wikipedia.org/wiki/Static_single_assignment_form">SSA</a> form very easily. To translate it into stack-based bytecode it would need a way to reuse values from the stack in multiple places; instructions to duplicate or extract a value from higher in the stack are an obvious candidate. Either of these forms is a natural step on the way to native compilation, and a bytecode representation would make it easier to optimize mixed tacit and explicit code—but it's easier to do the optimizations on SSA-form rather than stack-based code, so perhaps the right path is to convert both bytecode and derived functions to SSA.</p>
-<h3 id="compile-in-another-thread">Compile in another thread</h3>
+<h3 id="compile-in-another-thread"><a class="header" href="#compile-in-another-thread">Compile in another thread</a></h3>
<p>A simple and widely-used strategy to reduce slowdown due to dynamic compilation is to compile blocks in a separate thread from the one that runs them. The new code needs to be added in a thread-safe manner, which is not hard as the set of optimized implementations is a small lookup table of some sort with only one writer.</p>
<p>If the implementation is able to make use of all available threads (possible when working with large arrays), then it's still important to minimize compilation time as that thread could be put to better use. If there are idle threads then the only costs of compilation overhead are minor: the optimized code can't be put to use as quickly, and there is more power draw and possible downclocking.</p>
-<h3 id="anticipation">Anticipation</h3>
+<h3 id="anticipation"><a class="header" href="#anticipation">Anticipation</a></h3>
<p>The <a href="#hot-paths">hot path</a> strategy depends on targetting code for optimization based on history. Anticipation would identify in advance what code will take longer to run, and allocate a fraction of the time taken for optimizing that code. This is most useful for code that runs a small number of times on large arrays. An example where anticipation would be very important is for a programmer trying experimental one-off queries on a large dataset.</p>
<p>The end result seems similar to that obtained by thunks as discussed at Dyalog '18 (<a href="https://dyalog.tv/Dyalog18/?v=-6no6N3i9Tg">video</a>, <a href="https://www.dyalog.com/user-meetings/uploads/conference/dyalog18/presentations/D15_The_Interpretive_Advantage.zip">slides</a>). A thunk runs as part of a primitive, detecting that computing the result will be slow and outputting a deferred computation instead. Anticipation is more powerful because it can scan ahead in the bytecode instead of deciding as primitives are called whether or not to expand the thunk.</p>
<p>Anticipation attempts to improve program speed while bounding the added overhead. For example, it might be constrained to add no more than 5% to the time to first program output, relative to base-level interpretation. The idea is to exit normal interpretation as soon as a large enough lower bound is established on this time, for example if an operation would create a large array. At this point it begins analysis, which will involve at least some shape propagation and probably increase the lower bound and optimization budget.</p>
diff --git a/docs/implementation/compile/index.html b/docs/implementation/compile/index.html
index 4ec585f0..44424f90 100644
--- a/docs/implementation/compile/index.html
+++ b/docs/implementation/compile/index.html
@@ -4,7 +4,7 @@
<title>BQN: Optimizing compilation notes</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../../index.html">BQN</a> / <a href="../index.html">implementation</a></div>
-<h1 id="optimizing-compilation-notes">Optimizing compilation notes</h1>
+<h1 id="optimizing-compilation-notes"><a class="header" href="#optimizing-compilation-notes">Optimizing compilation notes</a></h1>
<p>Pages here discuss advanced compilation strategies for BQN, that is, steps that might take take place after compiling to bytecode or a similar intermediate representation.</p>
<p>Most content here is currently speculative: C, Java, and Javascript backends are capable of compiling to native (x86, JVM, or Javascript) code in order to lower evaluation overhead but don't perform much if any analysis to improve this code. CBQN is likely to start making such optimizations in the future.</p>
<ul>
diff --git a/docs/implementation/index.html b/docs/implementation/index.html
index d0b73c59..8e46bc35 100644
--- a/docs/implementation/index.html
+++ b/docs/implementation/index.html
@@ -4,7 +4,7 @@
<title>BQN implementation notes</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a></div>
-<h1 id="bqn-implementation-notes">BQN implementation notes</h1>
+<h1 id="bqn-implementation-notes"><a class="header" href="#bqn-implementation-notes">BQN implementation notes</a></h1>
<p>Notes about how BQN is or could be implemented.</p>
<p>This repository's BQN implementation is written mainly in BQN: the bytecode <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../src/c.bqn">compiler</a> is completely self-hosted, and the majority of the runtime (<a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../src/r0.bqn">r0</a>, <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../src/r1.bqn">r1</a>) is written in BQN except that it is allowed to define primitives; some preprocessing (<a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../src/pr.bqn">pr</a>) turns the primitives into identifiers.</p>
<p>The remaining part, a Virtual Machine (VM), can be implemented in any language to obtain a version of BQN running in that language. The VM used for the online REPL is the <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../docs/bqn.js">Javascript implementation</a>, while <a href="https://github.com/dzaima/CBQN">CBQN</a> is a more advanced VM in C. There are platform-specific and generic tests in the <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../test/">test</a> directory.</p>
diff --git a/docs/implementation/kclaims.html b/docs/implementation/kclaims.html
index 4d028e6c..fcc0ddac 100644
--- a/docs/implementation/kclaims.html
+++ b/docs/implementation/kclaims.html
@@ -4,30 +4,30 @@
<title>BQN: Wild claims about K performance</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">implementation</a></div>
-<h1 id="wild-claims-about-k-performance">Wild claims about K performance</h1>
+<h1 id="wild-claims-about-k-performance"><a class="header" href="#wild-claims-about-k-performance">Wild claims about K performance</a></h1>
<p>Sometimes I see unsourced, unclear, vaguely mystical claims about K being the fastest array language. It happens often enough that I'd like to write a long-form rebuttal to these, and a demand that the people who make these do more to justify them.</p>
<p>This isn't meant to put down the K language! K is in fact the only APL-family language other than BQN that I would recommend without reservations. And there's nothing wrong with the K community as a whole. Go to <a href="https://chat.stackexchange.com/rooms/90748/the-k-tree">the k tree</a> and meet them! What I want to fight is the <em>myth</em> of K, which is carried around as much by those who used K once upon a time, and no longer have any connection to it, as by active users.</p>
<p>The points I argue here are narrow. To some extent I'm picking out the craziest things said about K to argue against. Please don't assume whoever you're talking to thinks these crazy things about K just because I wrote them here. Or, if they are wrong about these topics, that they're wrong about everything. Performance is a complicated and often counter-intuitive field and it's easy to be mislead.</p>
<p>On that note, it's possible <em>I've</em> made mistakes, such as incorrectly designing or interpreting benchmarks. If you present me with concrete evidence against something I wrote below, I promise I'll revise this page to include it, even if I just have to quote verbatim because I don't understand a word of it.</p>
-<h2 id="the-fastest-array-language">The fastest array language</h2>
+<h2 id="the-fastest-array-language"><a class="header" href="#the-fastest-array-language">The fastest array language</a></h2>
<p>When you ask what the fastest array language is, chances are someone is there to answer one of k, kdb, or q. I can't offer benchmarks that contradict this, but I will argue that there's little reason to take these people at their word.</p>
<p>The reason I have no measurements is that every contract for a commercial K includes an anti-benchmark clause. For example, Shakti's <a href="https://shakti.com/download/license">license</a> says users cannot &quot;distribute or otherwise make available to any third party any report regarding the performance of the Software benchmarks or any information from such a report&quot;. As I would be unable to share the results, I have not taken benchmarks of any commercial K. Or downloaded one for that matter. Shakti could publish benchmarks; they choose to publish a handful of comparisons with database software and none with array languages or frameworks. I do run tests with <a href="https://codeberg.org/ngn/k">ngn/k</a>, which is developed with goals similar to Whitney's K; the author says it's slower than Shakti but not by too much.</p>
<p>The primary reason I don't give any credence to claims that K is the best is that they are always devoid of specifics. Most importantly, the same assertion is made across decades even though performance in J, Dyalog, and NumPy has improved by leaps and bounds in the meantime—I participated in advances of <a href="https://www.dyalog.com/dyalog/dyalog-versions/170/performance.htm">26%</a> and <a href="https://www.dyalog.com/dyalog-versions/180/performance.htm">10%</a> in overall Dyalog benchmarks in the last two major versions. Has K4 (the engine behind kdb and Q) kept pace? Maybe it's fallen behind since Arthur left but Shakti K is better? Which other array languages has the poster used? Doesn't matter—<em>they</em> are all the same but <em>K</em> is better.</p>
<p>A related theme I find is equivocating between different kinds of performance. I suspect that for interpreting scalar code K is faster than APL and J but slower than Javascript, and certainly any compiled language. For operations on arrays, maybe it beats Javascript and Java but loses to current Dyalog and tensor frameworks. Simple database queries, Shakti says it's faster than Spark and Postgres but is silent about newer in-memory databases. The most extreme K advocates sweep away all this complexity by comparing K to weaker contenders in each category. Just about any language can be &quot;the best&quot; with this approach.</p>
<p>Before getting into array-based versus scalar code, here's a simpler case. It's well known that K works on one list at a time, that is, if you have a matrix—in K, a list of lists—then applying an operation (say sum) to each row works on each one independently. If the rows are short then there's function overhead for each one. In APL, J, and BQN, the matrix is stored as one unit with a stride. The sum can use one metadata computation for all rows, and there's usually special code for many row-wise functions. I measured that Dyalog is 30 times faster than ngn/k to sum rows of a ten-million by three float (double) matrix, for one fairly representative example. It's fine to say—as many K-ers do—that these cases don't matter or can be avoided in practice; it's dishonest (or ignorant) to claim they don't exist.</p>
-<h2 id="scalar-versus-array-code">Scalar versus array code</h2>
+<h2 id="scalar-versus-array-code"><a class="header" href="#scalar-versus-array-code">Scalar versus array code</a></h2>
<p>I have a suspicion that users sometimes think K is faster than APL because they try out a Fibonacci function or other one-number-at-a-time code. Erm, your boat turns faster than a battleship, congratulations? <em>Python</em> beats these languages at interpreted performance. By like a factor of five. The only reason for anyone to think this is relevant is if they have a one-dimensional model where J is &quot;better&quot; than Python, so K is &quot;better&quot; than both.</p>
<p>Popular APL and J implementations interpret source code directly, without even building an AST. This is very slow, and Dyalog has several other pathologies that get in the way as well. Like storing the execution stack in the workspace to prevent stack overflows, and the requirement that a user can save a workspace with paused code and resume it <em>in a later version</em>. But the overhead is per token executed, and a programmer can avoid the cost by working on large arrays where one token does a whole lot of work. If you want to show a language is faster than APL generally, this is the kind of code to look at.</p>
<p>K is designed to be as fast as possible when interpreting scalar code, for example using a <a href="https://k.miraheze.org/wiki/Grammar">grammar</a> that's much simpler than <a href="../spec/grammar.html">BQN's</a> (speed isn't the only benefit of being simpler of course, but it's clearly a consideration). It succeeds at this, and K interpreters are very fast, even without bytecode compilation in advance.</p>
<p>But K still isn't good at scalar code! It's an interpreter (if a good one) for a dynamically-typed language, and will be slower than compiled languages like C and Go, or JIT-compiled ones like Javascript and Java. A compiler generates code to do what you want, while an interpreter is code that reads data (the program) to do what you want. Once the code is compiled, the interpreter has an extra step and <em>has</em> to be slower. This is why BQN uses compiler-based strategies to speed up execution, first compiling to bytecode to make syntax overhead irrelevant and then usually post-processing that bytecode. Compilation is fast enough that it's perfectly fine to compile code every time it's run.</p>
-<h2 id="instruction-cache">Instruction cache</h2>
+<h2 id="instruction-cache"><a class="header" href="#instruction-cache">Instruction cache</a></h2>
<p>A more specific claim about K is that the key to its speed is that the interpreter, or some part of it, fits in L1 cache. I know Arthur Whitney himself has said this; I can't find that now but <a href="https://kx.com/blog/what-makes-time-series-database-kdb-so-fast/">here</a>'s some material from KX about the &quot;L1/2 cache&quot;. Maybe this was a relevant factor in the early days of K around 2000—I'm doubtful. In the 2020s it's ridiculous to say that instruction caching matters.</p>
<p>Let's clarify terms first. The CPU cache is a set of storage areas that are smaller and faster than RAM; memory is copied there when it's used so it will be faster to access it again later. L1 is the smallest and fastest level. On a typical CPU these days it might consist of 64KB of <em>data</em> cache for memory to be read and written, and 64KB of <em>instruction</em> cache for memory to be executed by the CPU. When I've seen it the L1 cache claim is specifically about the K interpreter (and not the data it works with) fitting in the cache, so it clearly refers to the instruction cache.</p>
<p>(Unlike the instruction cache, the data cache is a major factor that makes array languages faster. It's what terms like &quot;cache-friendly&quot; typically refer to. I think the reason KX prefers to talk about the instruction cache is that it allows them to link this well-known consideration to the size of the kdb binary, which is easily measured and clearly different from other products. Anyone can claim to use cache-friendly algorithms.)</p>
<p>A K interpreter will definitely benefit from the instruction cache. Unfortunately, that's where the truth of this claim runs out. Any other interpreter you use will get just about the same benefit, because the most used code will fit in the cache with plenty of room to spare. And the best case you get from a fast core interpreter loop is fast handling of scalar code—exactly the case that array languages typically ignore.</p>
<p>So, 64KB of instruction cache. That would be small even for a K interpreter. Why is it enough? I claim specifically that while running a program might cause a cache miss once in a while, the total cost of these will only ever be a small fraction of execution time. This is because an interpreter is made of loops: a core loop to run the program as a whole and usually smaller loops for some specific instructions. These loops are small, with the core loop being on the larger side. In fact it can be pretty huge if the interpreter has a lot of exotic instructions, but memory is brought to the cache in lines of around 64 bytes, so that unused regions can be ignored. The active portions might take up a kilobyte or two. Furthermore, you've got the L2 and L3 caches as backup, which are many times larger than L1 and not much slower.</p>
<p>So a single loop doesn't overflow the cache. And the meaning of a loop is that it's loaded once but run multiple times—for array operations, it could be a huge number. The body of an interpreter loop isn't likely to be fast either, typically performing some memory accesses or branches or both. An L1 instruction cache miss costs tens of cycles if it's caught by another cache layer and hundreds if it goes to memory. Twenty cycles would be astonishingly fast for a go around the core interpreter loop, and array operation loops are usually five cycles or more, plus a few tens in setup. It doesn't take many loops to overcome a cache miss, and interpreting any program that doesn't finish instantly will take millions of iterations or more, spread across various loops.</p>
-<h3 id="measuring-l1-with-perf">Measuring L1 with perf</h3>
+<h3 id="measuring-l1-with-perf"><a class="header" href="#measuring-l1-with-perf">Measuring L1 with perf</a></h3>
<p>Look, you can measure this stuff. Linux has a nice tool called <a href="https://en.wikipedia.org/wiki/Perf_(Linux)">perf</a> that can track all sorts of hardware events related to your program, including cache misses. You can pass in a list of events with <code><span class='Function'>-</span><span class='Value'>e</span></code> followed by the program to be run. It can even distinguish instruction from data cache misses! I'll be showing the following events:</p>
<pre><span class='Value'>perf</span> <span class='Value'>stat</span> <span class='Function'>-</span><span class='Value'>e</span> <span class='Value'>cycles</span><span class='Separator'>,</span><span class='Value'>icache_16b.ifdata_stall</span><span class='Separator'>,</span><span class='Value'>cache</span><span class='Function'>-</span><span class='Value'>misses</span><span class='Separator'>,</span><span class='Function'>L1-</span><span class='Value'>dcache</span><span class='Function'>-</span><span class='Value'>load</span><span class='Function'>-</span><span class='Value'>misses</span><span class='Separator'>,</span><span class='Function'>L1-</span><span class='Value'>icache</span><span class='Function'>-</span><span class='Value'>load</span><span class='Function'>-</span><span class='Value'>misses</span>
</pre>
diff --git a/docs/implementation/primitive/index.html b/docs/implementation/primitive/index.html
index b5256302..f139e5f4 100644
--- a/docs/implementation/primitive/index.html
+++ b/docs/implementation/primitive/index.html
@@ -4,7 +4,7 @@
<title>BQN: Primitive implementation notes</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../../index.html">BQN</a> / <a href="../index.html">implementation</a></div>
-<h1 id="primitive-implementation-notes">Primitive implementation notes</h1>
+<h1 id="primitive-implementation-notes"><a class="header" href="#primitive-implementation-notes">Primitive implementation notes</a></h1>
<p>Commentary on the best methods I know for implementing various primitives. Often there are many algorithms that are viable in different situations, and in these cases I try to discuss the tradeoffs.</p>
<ul>
<li><a href="replicate.html">Replicate</a></li>
diff --git a/docs/implementation/primitive/random.html b/docs/implementation/primitive/random.html
index 7f660792..c907ee1c 100644
--- a/docs/implementation/primitive/random.html
+++ b/docs/implementation/primitive/random.html
@@ -4,12 +4,12 @@
<title>BQN: Implementation of random stuff</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../../index.html">BQN</a> / <a href="../index.html">implementation</a> / <a href="index.html">primitive</a></div>
-<h1 id="implementation-of-random-stuff">Implementation of random stuff</h1>
+<h1 id="implementation-of-random-stuff"><a class="header" href="#implementation-of-random-stuff">Implementation of random stuff</a></h1>
<p>Not a primitive, but CBQN's <code><span class='Function'>•MakeRand</span></code> initializes a random number generator that has some built-in utilities. For clarity we'll call a result of this initialization <code><span class='Value'>rand</span></code> in the text below.</p>
-<h2 id="random-number-generation">Random number generation</h2>
+<h2 id="random-number-generation"><a class="header" href="#random-number-generation">Random number generation</a></h2>
<p>CBQN is currently using wyrand, part of the <a href="https://github.com/wangyi-fudan/wyhash">wyhash</a> library. It's extremely fast, passes the expected test suites, and no one's raised any concerns about it yet (but it's very new). It uses only 64 bits of state and doesn't have extra features like jump ahead.</p>
<p>Other choices are <a href="https://prng.di.unimi.it/">xoshiro++</a> and <a href="https://www.pcg-random.org/">PCG</a>. The authors of these algorithms (co-author for xoshiro) hate each other very much and have spent quite some time slinging mud at each other. As far as I can tell they both have the normal small bias in favor of their own algorithms but are wildly unfair towards the other side, choosing misleading examples and inflating minor issues. I think both generators are good but find the case for xoshiro a little more convincing, and I think it's done better in third-party benchmarks.</p>
-<h2 id="simple-random-sample">Simple random sample</h2>
+<h2 id="simple-random-sample"><a class="header" href="#simple-random-sample">Simple random sample</a></h2>
<p>A <a href="https://en.wikipedia.org/wiki/Simple_random_sample">simple random sample</a> from a set is a subset with a specified size, chosen so that each subset of that size has equal probability. <code><span class='Value'>rand.</span><span class='Function'>Deal</span></code> gets a sample of size <code><span class='Value'>𝕨</span></code> from the set <code><span class='Function'>↕</span><span class='Value'>𝕩</span></code> with elements in a uniformly random order, and <code><span class='Value'>rand.</span><span class='Function'>Subset</span></code> does the same but sorts the elements.</p>
<p><code><span class='Function'>Deal</span></code> uses a <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Knuth shuffle</a>, stopping after the first <code><span class='Value'>𝕨</span></code> elements have been shuffled, as the algorithm won't touch them again. Usually it creates <code><span class='Function'>↕</span><span class='Value'>𝕩</span></code> explicitly for this purpose, but if <code><span class='Value'>𝕨</span></code> is very small then initializing it is too slow. In this case we initialize <code><span class='Function'>↕</span><span class='Value'>𝕨</span></code>, but use a &quot;hash&quot; table with an identity hash—the numbers are already random—for <code><span class='Value'>𝕨</span><span class='Function'>↓↕</span><span class='Value'>𝕩</span></code>. The default is that every value in the table is equal to its key, so that only entries where a swap has happened need to be stored. The hash table is the same design as for self-search functions, with open addressing and linear probing.</p>
<p><code><span class='Function'>Subset</span></code> uses <a href="https://math.stackexchange.com/questions/178690/whats-the-proof-of-correctness-for-robert-floyds-algorithm-for-selecting-a-sin">Floyd's method</a>, which is sort of a modification of shuffling where only the selected elements need to be stored, not what they were swapped with. This requires a lookup structure that can be updated efficiently and output all elements in sorted order. The choices are a bitset for large <code><span class='Value'>𝕨</span></code> and another not-really-hash table for small <code><span class='Value'>𝕨</span></code>. The table uses a right shift—that is, division by a power of two—as a hash so that hashing preserves the ordering, and inserts like an insertion sort: any larger entries are pushed forward. Really this is an online sorting algorithm, that works because we know the input distribution is well-behaved (it degrades to quadratic performance only in very unlikely cases). When <code><span class='Value'>𝕨</span><span class='Function'>&gt;</span><span class='Value'>𝕩</span><span class='Function'>÷</span><span class='Number'>2</span></code>, we always use a bitset, but select <code><span class='Value'>𝕩</span><span class='Function'>-</span><span class='Value'>𝕨</span></code> elements and invert the selection.</p>
diff --git a/docs/implementation/primitive/replicate.html b/docs/implementation/primitive/replicate.html
index 9d539d40..9e07a754 100644
--- a/docs/implementation/primitive/replicate.html
+++ b/docs/implementation/primitive/replicate.html
@@ -4,23 +4,23 @@
<title>BQN: Implementation of Indices and Replicate</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../../index.html">BQN</a> / <a href="../index.html">implementation</a> / <a href="index.html">primitive</a></div>
-<h1 id="implementation-of-indices-and-replicate">Implementation of Indices and Replicate</h1>
+<h1 id="implementation-of-indices-and-replicate"><a class="header" href="#implementation-of-indices-and-replicate">Implementation of Indices and Replicate</a></h1>
<p>The replicate family of functions contains not just primitives but powerful tools for implementing other functionality. The most important is converting <a href="#booleans-to-indices">bits to indices</a>: AVX-512 extensions implement this natively for various index sizes, and even with no SIMD support at all there are surprisingly fast table-based algorithms for it.</p>
<p><a href="#replicate">General replication</a> is more complex. Branching will slow many useful cases down considerably when using the obvious solution. However, branch-free techniques introduce overhead for larger replication amounts. Hybridizing these seems to be the only way, but it's finicky.</p>
<p>Replicate by a <a href="#constant-replicate">constant amount</a> (so <code><span class='Value'>𝕨</span></code> is a single number) is not too common in itself, but it's notable because it can be the fastest way to implement outer products and scalar dyadics with prefix agreement.</p>
-<h2 id="indices">Indices</h2>
+<h2 id="indices"><a class="header" href="#indices">Indices</a></h2>
<p>Branchless algorithms are fastest, but with unbounded values in <code><span class='Value'>𝕨</span></code> a fully branchless algorithm is impossible because you can't write an arbitrary amount of memory without branching. So the best algorithms depend on bounding <code><span class='Value'>𝕨</span></code>. Fortunately the most useful case is that <code><span class='Value'>𝕨</span></code> is boolean.</p>
-<h3 id="booleans-to-indices">Booleans to indices</h3>
+<h3 id="booleans-to-indices"><a class="header" href="#booleans-to-indices">Booleans to indices</a></h3>
<p>Indices (<code><span class='Function'>/</span></code>) on a boolean <code><span class='Value'>𝕩</span></code> of 256 or fewer bits can be made very fast on generic 64-bit hardware using a lookup table on 8 bits at a time. This algorithm can write past the end by up to 8 bytes (7 if trailing 0s are excluded), but never writes more than 256 bytes total. This means it's suitable for writing to an overallocated result array or a 256-byte buffer.</p>
<p>To generate indices, use a 256×8-byte lookup table that goes from bytes to 8-byte index lists, and either a popcount instruction or another lookup table to get the sum of each byte. For each byte in <code><span class='Value'>𝕨</span></code>, get the corresponding indices, add an increment, and write them to the current index in the output. Then incease the output index by the byte's sum. The next indices will overlap the 8 bytes written, with the actual indices kept and junk values at the end overwritten. The increment added is an 8-byte value where each byte contains the current input index (always a multiple of 8); it can be added or bitwise or-ed with the lookup value.</p>
<p>Some other methods discussed by <a href="https://branchfree.org/2018/05/22/bits-to-indexes-in-bmi2-and-avx-512/">Langdale</a> and <a href="https://lemire.me/blog/2018/03/08/iterating-over-set-bits-quickly-simd-edition/">Lemire</a>. I think very large lookup tables are not good for an interpreter because they cause too much cache pressure if used occasionally on smaller arrays. This rules out many of these strategies.</p>
-<h3 id="non-booleans-to-indices">Non-booleans to indices</h3>
+<h3 id="non-booleans-to-indices"><a class="header" href="#non-booleans-to-indices">Non-booleans to indices</a></h3>
<p>If the maximum value in <code><span class='Value'>𝕩</span></code> is, say, 8, then generating indices is fairly fast: for each element, write 8 indices and then move the output pointer forward by that much. This is much like the lookup table algorithm above, minus the lookup table. If the indices need to be larger than one byte, it's fine to expand them, and possibly add an offset, after generation (probably in chunks).</p>
<p>There are two ways I know to fill in the gaps that this method would leave with elements that are too large. First is to stop after such an element and fill remaining space branchfully (maybe with <code><span class='Value'>memset</span></code>). This is maximally efficient if <code><span class='Value'>𝕩</span></code> is dominated by large elements—particularly for 2-byte indices when it skips index expansion—but not good if there are a lot of elements near the threshold. Second, initialize the buffer with 0 and perform <code><span class='Function'>⌈</span><span class='Modifier'>`</span></code> afterwards, or other variations. This eliminates all but a fixed amount of branching, but it's a lot of overhead and I think unless a more sophisticated strategy arises it's best to stick with the first method.</p>
<p>Indices is half of a counting sort: for sparse values, it's the slower half. Making it fast makes counting sort viable for much larger range-to-length ratios.</p>
-<h2 id="replicate">Replicate</h2>
+<h2 id="replicate"><a class="header" href="#replicate">Replicate</a></h2>
<p>For the most part, understanding Indices is the best way to implement Replicate quickly. But this is not the case if <code><span class='Value'>𝕩</span></code> is boolean because then its elements are smaller than any useful index, and faster methods are available.</p>
-<h3 id="compress">Compress</h3>
+<h3 id="compress"><a class="header" href="#compress">Compress</a></h3>
<p>Most of the methods listed below can be performed in place.</p>
<p>For booleans, use BMI2's PEXT (parallel bits extract) instruction, or an emulation of it. The result can be built recursively alongside the also-required popcount using masked shifts.</p>
<p>The generally best method for small elements seems to be to generate 1-byte indices into a buffer 256 at a time and select with those. There's a branchless method on one bit at a time which is occasionally better, but I don't think the improvement is enough to justify using it.</p>
@@ -28,11 +28,11 @@
<p>Odd-sized cells could be handled with an index buffer like small elements, using oversized writes and either overallocating or handling the last element specially.</p>
<p>For medium-sized cells copying involves partial writes and so is somewhat inefficient. It's better to split <code><span class='Value'>𝕨</span></code> into groups of 1s in order to copy larger chunks from <code><span class='Value'>𝕩</span></code> at once. So the algorithm repeatedly searches <code><span class='Value'>𝕨</span></code> for the next 1, then the next 0, then copies the corresponding value from <code><span class='Value'>𝕩</span></code> to the result. This might be better for small odd-sized cells as well; I haven't implemented the algorithm with oversized writes to compare.</p>
<p>The grouped algorithm, as well as a simpler sparse algorithm that just finds each 1 in <code><span class='Value'>𝕨</span></code>, can also better for small elements. Whether to use these depends on the value of <code><span class='Function'>+</span><span class='Modifier'>´</span><span class='Value'>𝕨</span></code> (sparse) or <code><span class='Function'>+</span><span class='Modifier'>´</span><span class='Function'>»</span><span class='Modifier2'>⊸</span><span class='Function'>&lt;</span><span class='Value'>𝕨</span></code> (clumped). The checking is fast and these cases are common, but the general case is also fast enough that this is not a particularly high priority.</p>
-<h3 id="replicate">Replicate</h3>
+<h3 id="replicate"><a class="header" href="#replicate">Replicate</a></h3>
<p>Like Compress I think the best algorithm is often to generate small indices in a buffer and then select. But this is inefficient when <code><span class='Value'>𝕨</span></code> contains large values, so those need to be detected and handled. Very tricky.</p>
-<h4 id="constant-replicate">Constant replicate</h4>
+<h4 id="constant-replicate"><a class="header" href="#constant-replicate">Constant replicate</a></h4>
<p>Useful for outer products and leading-axis extension. See <a href="https://www.dyalog.com/blog/2018/06/expanding-bits-in-shrinking-time/">Expanding Bits in Shrinking Time</a> for the boolean case. C compilers will generate decent code for constant small numbers and variable large ones, but I think specialized code with shuffle would be better for small numbers.</p>
-<h3 id="higher-ranks">Higher ranks</h3>
+<h3 id="higher-ranks"><a class="header" href="#higher-ranks">Higher ranks</a></h3>
<p>When replicating along the first axis only, additional axes only change the element size (these are the main reason why a large element method is given). Replicating along a later axis offers a few opportunities for improvement relative to replicating each cell individually.</p>
<p>Particularly for boolean <code><span class='Value'>𝕨</span></code>, Select is usually faster than Replicate (a major exception is for a boolean <code><span class='Value'>𝕩</span></code>). Simply replacing <code><span class='Function'>/</span></code> with <code><span class='Function'>/</span><span class='Modifier'>¨</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span></code> (after checking conformability) could be an improvement. It's probably best to compute the result shape first to avoid doing any work if it's empty. Similarly, if early result axes are small then the overhead of separating out Indices might make it worse than just doing the small number of Replicates.</p>
<p>A technique when <code><span class='Value'>𝕨</span></code> processed with one or more bytes at a time, and applies to many rows, is to repeat it up to an even number of bytes and combine rows of <code><span class='Value'>𝕩</span></code> into longer virtual rows (the last one can be short). I think this only ends up being useful when <code><span class='Value'>𝕩</span></code> is boolean.</p>
diff --git a/docs/implementation/primitive/sort.html b/docs/implementation/primitive/sort.html
index 2a417770..5c6c3d70 100644
--- a/docs/implementation/primitive/sort.html
+++ b/docs/implementation/primitive/sort.html
@@ -4,35 +4,35 @@
<title>BQN: Implementation of ordering functions</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../../index.html">BQN</a> / <a href="../index.html">implementation</a> / <a href="index.html">primitive</a></div>
-<h1 id="implementation-of-ordering-functions">Implementation of ordering functions</h1>
+<h1 id="implementation-of-ordering-functions"><a class="header" href="#implementation-of-ordering-functions">Implementation of ordering functions</a></h1>
<p>The <a href="../../doc/order.html">ordering functions</a> are Sort (<code><span class='Function'>∧∨</span></code>), Grade (<code><span class='Function'>⍋⍒</span></code>), and Bins (<code><span class='Function'>⍋⍒</span></code>). Although these are well-studied—particularly sorting, and then binary search or &quot;predecessor search&quot;—there are many recent developments, as well as techniques that I have not found in the literature. The three functions are closely related but have important differences in what algorithms are viable. Sorting is a remarkably deep problem with different algorithms able to do a wide range of amazing things, and sophisticated ways to combine those. It is by no means solved. In comparison, Bins is pretty tame.</p>
<p>There's a large divide between ordering compound data and simple data. For compound data comparisons are expensive, and the best algorithm will generally be the one that uses the fewest comparisons. For simple data they fall somewhere between cheap and extremely cheap, and fancy branchless and vectorized algorithms are the best.</p>
-<h2 id="on-quicksort-versus-merge-sort">On quicksort versus merge sort</h2>
+<h2 id="on-quicksort-versus-merge-sort"><a class="header" href="#on-quicksort-versus-merge-sort">On quicksort versus merge sort</a></h2>
<p>Merge sort is better. It is deterministic, stable, and has optimal worst-case performance. Its pattern handling is better: while merge sort handles &quot;horizontal&quot; patterns and quicksort does &quot;vertical&quot; ones, merge sort gets useful work out of <em>any</em> sequence of runs but in-place quicksort will quickly mangle its analogue until it may as well be random.</p>
<p>But that doesn't mean merge sort is always faster. Quicksort seems to work a little better branchlessly. For sorting, quicksort's partitioning can reduce the range of the data enough to use an extremely quick counting sort. Partitioning is also a natural fit for binary search, where it's mandatory for sensible cache behavior with large enough arguments. So it can be useful. But it doesn't merge, and can't easily be made to merge, and that's a shame.</p>
<p>The same applies to the general categories of partitioning sorts (quicksort, radix sort, samplesort) and merging sorts (mergesort, timsort, multimerges). Radix sorts are definitely the best for some types and lengths, although the scattered accesses make their performance unpredictable and I think overall they're not worth it. A million uniformly random 4-byte integers is nearly the best possible case for radix sort, so the fact that this seems to be the go-to sorting benchmark means radix sorting looks better than it is.</p>
-<h2 id="on-binary-search">On binary search</h2>
+<h2 id="on-binary-search"><a class="header" href="#on-binary-search">On binary search</a></h2>
<p>Binary searches are very easy to get wrong. Do not write <code><span class='Paren'>(</span><span class='Value'>hi</span><span class='Function'>+</span><span class='Value'>lo</span><span class='Paren'>)</span><span class='Function'>/</span><span class='Number'>2</span></code>: it's not safe from overflows. I always follow the pattern given in the first code block <a href="https://pvk.ca/Blog/2015/11/29/retrospective-on-binary-search-and-on-compression-slash-compilation/">here</a>. This code will never access the value <code><span class='Value'>*base</span></code>, so it should be considered a search on the <code><span class='Value'>n</span><span class='Function'>-</span><span class='Number'>1</span></code> values beginning at <code><span class='Value'>base</span><span class='Function'>+</span><span class='Number'>1</span></code> (the perfect case is when the number of values is one less than a power of two, which is in fact how it has to go). It's branchless and always takes the same number of iterations. To get a version that stops when the answer is known, subtract <code><span class='Value'>n%</span><span class='Number'>2</span></code> from <code><span class='Value'>n</span></code> in the case that <code><span class='Value'>*mid</span> <span class='Function'>&lt;</span> <span class='Value'>x</span></code>.</p>
-<h2 id="compound-data">Compound data</h2>
+<h2 id="compound-data"><a class="header" href="#compound-data">Compound data</a></h2>
<p>Array comparisons are expensive. The goal here is almost entirely to minimize the number of comparisons. Which is a much less complex goal than to get the most out of modern hardware, so the algorithms here are simpler.</p>
<p>For <strong>Sort</strong> and <strong>Grade</strong>, use Timsort. It's time-tested and shows no signs of weakness (but do be sure to pick up a fix for the bug discovered in 2015 in formal verification). Hardly different from optimal comparison numbers on random data, and outstanding pattern handling. Grade can be done either by selecting from the original array to order indices or by moving the data around in the same order as the indices. I think the second of these ends up being substantially better for small-ish elements.</p>
<p>For <strong>Bins</strong>, use a branching binary search: see <a href="#on-binary-search">On binary search</a> above. But there are also interesting (although, I expect, rare) cases where only one argument is compound. Elements of this argument should be reduced to fit the type of the other argument, then compared to multiple elements. For the right argument, this just means reducing before doing whatever binary search is appropriate to the left argument. If the left argument is compound, its elements should be used as partitions. Then switch back to binary search only when the partitions get very small—probably one element.</p>
-<h2 id="simple-data">Simple data</h2>
+<h2 id="simple-data"><a class="header" href="#simple-data">Simple data</a></h2>
<p>The name of the game here is &quot;branchless&quot;.</p>
<p>For sorting, the fastest algorithms for generic data and generic hardware are branchless <a href="#quicksort">quicksorts</a>. Fluxsort is new and very exciting because it's a <em>stable</em> algorithm that's substantially faster than runner-up pdqsort on random arrays. However, it's immature and is missing a lot of the specialized strategies pdqsort has. I'm working on adapting these improvements to work for stable sorting and also on hybridizing with counting/bucket sort.</p>
<p>A branchless binary search is adequate for Bins but in many cases—very small or large <code><span class='Value'>𝕨</span></code>, and small range—there are better methods.</p>
-<h3 id="counting-and-bucket-sort">Counting and bucket sort</h3>
+<h3 id="counting-and-bucket-sort"><a class="header" href="#counting-and-bucket-sort">Counting and bucket sort</a></h3>
<p>Both counting and bucket sort are small-range algorithms that begin by counting the number of each possible value. Bucket sort, as used here, means that the counts are then used to place values in the appropriate position in the result in another pass. Counting sort does not read from the initial values again and instead reconstructs them from the counts. It might be written <code><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='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Function'>-</span><span class='Modifier2'>⟜</span><span class='Value'>min</span><span class='Paren'>)</span></code> in BQN, with <code><span class='Function'>≠</span><span class='Modifier'>¨</span><span class='Modifier2'>∘</span><span class='Function'>⊔</span></code> as a single efficient operation.</p>
<p>Bucket sort can be used for Grade or sort-by (<code><span class='Function'>⍋</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span></code>), but counting sort only works for sorting itself. It's not-even-unstable: there's no connection between result values and the input values except that they are constructed to be equal. But with <a href="replicate.html#non-booleans-to-indices">fast Indices</a>, Counting sort is vastly more powerful, and is effective with a range four to eight times the argument length. This is large enough that it might pose a memory usage problem, but the memory use can be made arbitrarily low by partitioning.</p>
-<h3 id="quicksort">Quicksort</h3>
+<h3 id="quicksort"><a class="header" href="#quicksort">Quicksort</a></h3>
<p><a href="https://github.com/scandum/fluxsort">Fluxsort</a> attains high performance with a branchless stable partition that places one half on top of existing data and the other half somewhere else. One half ends up in the appropriate place in the sorted array. The other is in swap memory, and will be shifted back by subsequent partitions and base-case sorting. Aside from the partitioning strategy, Fluxsort makes a number of other decisions differently from pdqsort, including a fairly complicated merge sort (<a href="https://github.com/scandum/quadsort">Quadsort</a>) as the base case. I haven't fully evaluated these.</p>
<p><a href="https://arxiv.org/abs/2106.05123">This paper</a> gives a good description of <a href="https://github.com/orlp/pdqsort">pdqsort</a>. I'd start with the <a href="https://github.com/rust-lang/rust/blob/master/library/core/src/slice/sort.rs">Rust version</a>, which has some advantages but can still be improved further. The subsections below describe improved <a href="#partitioning">partitioning</a> and an <a href="#initial-pass">initial pass</a> with several benefits. I also found that the pivot randomization methods currently used are less effective because they swap elements that won't become pivots soon; the pivot candidates and randomization targets need to be chosen to overlap. The optimistic insertion sort can also be improved: when a pair of elements is swapped the smaller one should be inserted as usual but the larger one can also be pushed forward at little cost, potentially saving many swaps and handling too-large elements as gracefully as too-small ones.</p>
<p>While the stable partitioning for Fluxsort seems to be an overall better choice, pdqsort's unstable partitioning is what I've worked with in the past. The following sections are written from the perspective of pdqsort and will be rewritten for Fluxsort as the methods are adapted.</p>
-<h4 id="partitioning">Partitioning</h4>
+<h4 id="partitioning"><a class="header" href="#partitioning">Partitioning</a></h4>
<p>In-place quicksort relies on a partitioning algorithm that exchanges elements in order to split them into two contiguous groups. The <a href="https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme">Hoare partition scheme</a> does this, and <a href="https://github.com/weissan/BlockQuicksort">BlockQuicksort</a> showed that it can be performed quickly with branchless index generation; this method was then adopted by pdqsort. But the <a href="replicate.html#booleans-to-indices">bit booleans to indices</a> method is faster and fits well with vectorized comparisons.</p>
<p>It's simplest to define an operation <code><span class='Function'>P</span></code> that partitions a list <code><span class='Value'>𝕩</span></code> according to a boolean list <code><span class='Value'>𝕨</span></code>. Partitioning permutes <code><span class='Value'>𝕩</span></code> so that all elements corresponding to 0 in <code><span class='Value'>𝕨</span></code> come before those corresponding to 1. The quicksort partition step, with pivot <code><span class='Value'>t</span></code>, is <code><span class='Paren'>(</span><span class='Value'>t</span><span class='Function'>≤</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Function'>P</span><span class='Value'>𝕩</span></code>, and the comparison can be vectorized. Interleaving comparison and partitioning in chunks would save memory (a fraction of the size of <code><span class='Value'>𝕩</span></code>, which should have 32- or 64-bit elements because plain counting sort is best for smaller ones) but hardly speeds things up: only a few percent, and only for huge lists with hundreds of millions of elements. The single-step <code><span class='Function'>P</span></code> is also good for Bins, where the boolean <code><span class='Value'>𝕨</span></code> will have to be saved.</p>
<p>For binary search <code><span class='Value'>𝕨</span><span class='Function'>⍋</span><span class='Value'>𝕩</span></code>, partitioning allows one pivot element <code><span class='Value'>t</span></code> from <code><span class='Value'>𝕨</span></code> to be compared to all of <code><span class='Value'>𝕩</span></code> at once, instead of the normal strategy of working with one element from <code><span class='Value'>𝕩</span></code> at a time. <code><span class='Value'>𝕩</span></code> is partitioned according to <code><span class='Value'>t</span><span class='Function'>≤</span><span class='Value'>𝕩</span></code>, then result values are found by searching the first half of <code><span class='Value'>𝕨</span></code> for the smaller elements and the second half for the larger ones, and then they are put back in the correct positions by reversing the partitioning. Because Hoare partitioning works by swapping independent pairs of elements, <code><span class='Function'>P</span></code> is a self inverse, identical to <code><span class='Function'>P</span><span class='Modifier'>⁼</span></code>. So the last step is simple, provided the partitioning information <code><span class='Value'>t</span><span class='Function'>≤</span><span class='Value'>𝕩</span></code> is saved.</p>
-<h4 id="initial-pass">Initial pass</h4>
+<h4 id="initial-pass"><a class="header" href="#initial-pass">Initial pass</a></h4>
<p>An initial pass for pdqsort (or another in-place quicksort) provides a few advantages:</p>
<ul>
<li>Recognize sorted and reverse-sorted arrays as fast as possible</li>
@@ -44,15 +44,15 @@
<p>Finding an initial run is fast as well. Compare the first two elements to determine direction, then search for the first pair that have the opposite direction (this can be vectorized because overreading is fine). This run can be used as the first range block, because the maximum and minimum are the two elements at the ends of the run.</p>
<p>At the start of sorting, swap the smallest element to the beginning and the largest to the end, and shrink the size of the array by one in each direction. Now the element before the array is a lower bound and the one after is an upper bound. This property can also be maintained as the array is partitioned, by placing a pivot element between the two halves (swap it to one side of the array before partitioning and to the middle afterwards). As a result, it's always safe to use unguarded insertion sort, and an upper bound for the range of the array can always be found using the difference between the elements before and after it. Now finding the range is fast enough to check for counting sort at every recursion.</p>
<p>This is a very simple initial pass; a more sophisticated one might be beneficial. If the array starts with a large run then there could be more of them. There may also be sampling-based tests to find when merge sort is better, even if the runs aren't perfect (but is this actually common?).</p>
-<h3 id="other-sorting-algorithms">Other sorting algorithms</h3>
+<h3 id="other-sorting-algorithms"><a class="header" href="#other-sorting-algorithms">Other sorting algorithms</a></h3>
<p><a href="https://github.com/ips4o/ips4o">IPS⁴o</a> is a horrifyingly complicated samplesort thing. Unstable, but there's also a stable not-in-place version PS⁴o. For very large arrays it probably has the best memory access patterns, so a few samplesort passes could be useful.</p>
<p><a href="https://github.com/Morwenn/vergesort">Vergesort</a> has another useful first-pass strategy, which spends an asymptotically small amount of time searching for runs before sorting. Since it only detects perfect runs it won't give the full adaptivity of a good merge sort.</p>
<p>Sorting networks compare and swap elements in a fixed pattern, and so can be implemented with branchless or even vectorized code. They're great for sorting many small arrays of the same size, but the limit before insertion sort beats it will be pretty small without hardware specialization.</p>
-<h4 id="simd-sorting">SIMD sorting</h4>
+<h4 id="simd-sorting"><a class="header" href="#simd-sorting">SIMD sorting</a></h4>
<p>A few people have done some work on merge sorting with AVX2 or AVX-512: <a href="https://github.com/sid1607/avx2-merge-sort">two</a> <a href="https://github.com/PatwinchIR/ultra-sort">examples</a>. Pretty complicated, and still mostly in the proof of concept stage, but the benchmarks on uniform random arrays are good. Can these be made adaptive?</p>
<p><a href="https://github.com/nlw0/ChipSort.jl">ChipSort</a> seems further along than those. It uses sorting networks, comb sort, and merging, which all fit nicely with SIMD and should work well together.</p>
<p>Or AVX can <a href="https://github.com/WojciechMula/simd-sort">speed up</a> quicksort. I suspect this is more of a marginal improvement (over BlockQuicksort/pdqsort discussed below) relative to merge sort. If partitioning is fast enough it might make stable quicksort viable.</p>
-<h3 id="binary-search">Binary search</h3>
+<h3 id="binary-search"><a class="header" href="#binary-search">Binary search</a></h3>
<p>Reminder that we're talking about simple, not <a href="#compound-data">compound</a> data. The most important thing is just to have a good branchless binary search (see <a href="#on-binary-search">above</a>), but there are other possible optimizations.</p>
<p>If <code><span class='Value'>𝕨</span></code> is extremely small, use a vector binary search as described in &quot;Sub-nanosecond Searches&quot; (<a href="https://dyalog.tv/Dyalog18/?v=paxIkKBzqBU">video</a>, <a href="https://www.dyalog.com/user-meetings/uploads/conference/dyalog18/presentations/D08_Searches_Using_Vector_Instructions.zip">slides</a>). For 1-byte elements there's also a vectorized method that works whenever <code><span class='Value'>𝕨</span></code> has no duplicates: create two lookup tables that go from multiples of 8 (5-bit values, after shifting) to bytes. One is a bitmask of <code><span class='Value'>𝕨</span></code>, so that a lookup gives 8 bits indicating which possible choices of the remaining 3 bits are in <code><span class='Value'>𝕨</span></code>. The other gives the number of values in <code><span class='Value'>𝕨</span></code> less than the multiple of 8. To find the result of Bins, look up these two bytes. Mask off the bitmask to include only bits for values less than the target, and sum it (each of these steps can be done with another lookup, or other methods depending on instruction set). The result is the sum of these two counts.</p>
<p>It's cheap and sometimes worthwhile to trim <code><span class='Value'>𝕨</span></code> down to the range of <code><span class='Value'>𝕩</span></code>. After finding the range of <code><span class='Value'>𝕩</span></code>, binary cut <code><span class='Value'>𝕨</span></code> to a smaller list that contains the range. Stop when the middle element fits inside the range, and search each half of <code><span class='Value'>𝕨</span></code> for the appropriate endpoint of the range.</p>
diff --git a/docs/implementation/vm.html b/docs/implementation/vm.html
index 1ecac46c..b7dd287f 100644
--- a/docs/implementation/vm.html
+++ b/docs/implementation/vm.html
@@ -4,14 +4,14 @@
<title>The BQN virtual machine and runtime</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">implementation</a></div>
-<h1 id="the-bqn-virtual-machine-and-runtime">The BQN virtual machine and runtime</h1>
+<h1 id="the-bqn-virtual-machine-and-runtime"><a class="header" href="#the-bqn-virtual-machine-and-runtime">The BQN virtual machine and runtime</a></h1>
<p>BQN's self-hosted compiler and runtime mean that only a small amount of native code is needed to run BQN on any given platform. The <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../docs/bqn.js">Javascript environment</a> requires about 500 lines of Javascript code including system functions and performance improvements; probably around 250 would be required just to run the core language. This makes it fairly easy to port BQN to new platforms, allowing BQN to be <a href="../doc/embed.html">embedded</a> within other programming languages and interact with arrays or functions in those languages.</p>
<p>The way data is represented is part of the VM implementation: it can use native arrays or a custom data structure, depending on what the language supports. An initial implementation will be very slow, but can be improved by replacing functions from the BQN-based runtime with native code. As the VM system can be hard to work with if you're not familiar with it, I advise you to contact me to discuss implementing a VM if you are interested.</p>
-<h2 id="bytecode">Bytecode</h2>
+<h2 id="bytecode"><a class="header" href="#bytecode">Bytecode</a></h2>
<p>The BQN implementation here and dzaima/BQN share a stack-based object code format used to represent compiled code. This format is a list of numbers of unspecified precision (small precision will limit the length of list literals and number of locals per block, blocks, and constants). Previously it was encoded as bytes with the <a href="https://en.wikipedia.org/wiki/LEB128">LEB128</a> format; while it no longer has anything to do with bytes it's called a &quot;bytecode&quot; because this is shorter than &quot;object code&quot;.</p>
<p>The self-hosted compiler uses a simpler, and less capable, format for block and variable data than dzaima/BQN. Only this format is described here; <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../dc.bqn">dc.bqn</a> adapts it to be compatible with dzaima/BQN.</p>
<p>dzaima/BQN can interpret bytecode or convert it to <a href="https://en.wikipedia.org/wiki/Java_virtual_machine">JVM</a> bytecode, while the Javascript VM previously interpreted bytecode but now always compiles it. Since interpretation is a simpler strategy, it may be helpful to use the <a href="https://github.com/mlochbaum/BQN/blob/f74d9223ef880f2914030c2375f680dcc7e8c92b/bqn.js#L36">old Javascript bytecode interpreter</a> as a reference (for bytecode execution only) when implementing a BQN virtual machine.</p>
-<h3 id="components">Components</h3>
+<h3 id="components"><a class="header" href="#components">Components</a></h3>
<p>The complete bytecode for a program consists of the following:</p>
<ul>
<li>A bytecode sequence <code><span class='Value'>code</span></code></li>
@@ -21,7 +21,7 @@
<li>Optionally, source locations for each instruction</li>
<li>Optionally, tokenization information</li>
</ul>
-<h4 id="blocks">Blocks</h4>
+<h4 id="blocks"><a class="header" href="#blocks">Blocks</a></h4>
<p>Each entry in <code><span class='Value'>blocks</span></code> is a list of the following properties:</p>
<ul>
<li>Block type: (0) function/immediate, (1) 1-modifier, (2) 2-modifier</li>
@@ -31,7 +31,7 @@
<p>Compilation separates blocks so that they are not nested in bytecode. A block consists of bodies, so that all compiled code is contained in some body of a block. The self-hosted compiler compiles the entire program into an immediate block, and the program is run by evaluating this block. Bodies are terminated with a RETN or RETD instruction.</p>
<p>When the block is evaluated depends on its type and immediateness. An immediate block (0,1) is evaluated as soon as it is pushed; a function (0,0) is evaluated when called on arguments, an immediate modifier (1 or 2, 1) is evaluated when called on operands, and a deferred modifier (1 or 2, 0) creates a derived function when called on operands and is evaluated when this derived function is called on arguments.</p>
<p>The last property can be a single number, or, if it's a deferred block, might be a pair of lists. For a single number the block is always evaluated by evaluating the body with the given index. For a pair, the first element gives the monadic case and the second the dyadic one. A given valence should begin at the first body in the appropriate list, moving to the next one if a header test (SETH instruction) fails.</p>
-<h4 id="bodies">Bodies</h4>
+<h4 id="bodies"><a class="header" href="#bodies">Bodies</a></h4>
<p>Bodies in a block are separated by <code><span class='Value'>;</span></code>. Each entry in <code><span class='Value'>bodies</span></code> is a list containing:</p>
<ul>
<li>Starting index in <code><span class='Value'>code</span></code></li>
@@ -41,7 +41,7 @@
</ul>
<p>The starting index refers to the position in bytecode where execution starts in order to evaluate the block. Different bodies will always have the same set of special names, but the variables they define are unrelated, so of course they can have different counts. The given number of variables includes special names, but list of names and export mask don't.</p>
<p>The program's symbol list is included in the tokenization information <code><span class='Value'>t</span></code>: it is <code><span class='Number'>0</span><span class='Function'>⊑</span><span class='Number'>2</span><span class='Function'>⊑</span><span class='Value'>t</span></code>. Since the entire program (the source code passed in one compiler call) uses this list, namespace field accesses can be performed with indices alone within a program. The symbol list is needed for cross-program access, for example if <code><span class='Function'>•BQN</span></code> returns a namespace.</p>
-<h3 id="instructions">Instructions</h3>
+<h3 id="instructions"><a class="header" href="#instructions">Instructions</a></h3>
<p>The following instructions are defined by dzaima/BQN. The ones emitted by the self-hosted BQN compiler are marked in the &quot;used&quot; column. Instructions marked <code><span class='Function'>NS</span></code> are used only in programs with namespaces, and so are not needed to support the compiler or self-hosted runtime.</p>
<table>
<thead>
@@ -447,23 +447,23 @@
</tbody>
</table>
<p>Many instructions just call functions or modifiers or otherwise have fairly obvious implementations. Instructions to handle variables and blocks are more complicated (although very typical of bytecode representations for lexically-scoped languages) and are described in more detail below.</p>
-<h3 id="local-variables-dfnd-loco-locu-locm-retn">Local variables: DFND LOCO LOCU LOCM RETN</h3>
+<h3 id="local-variables-dfnd-loco-locu-locm-retn"><a class="header" href="#local-variables-dfnd-loco-locu-locm-retn">Local variables: DFND LOCO LOCU LOCM RETN</a></h3>
<p>The bytecode representation is designed with the assumption that variables will be stored in frames, one for each time an instance of a block is run. dzaima/BQN has facilities to give frame slots names, in order to support dynamic execution, but self-hosted BQN doesn't. A new frame is created when the block is evaluated (see <a href="#blocks">#blocks</a>) and in general has to be cleaned up by garbage collection, because a lexical closure might need to refer to the frame even after the corresponding block finishes. Lexical closures can form loops, so simple reference counting can leak memory, but it could be used in addition to less frequent tracing garbage collection or another strategy.</p>
<p>A frame is a mutable list of <em>slots</em> for variable values. It has slots for any special names that are available during the blocks execution followed by the local variables it defines. Special names use the ordering <code><span class='Value'>𝕤𝕩𝕨𝕣𝕗𝕘</span></code>; the first three of these are available in non-immediate blocks while <code><span class='Value'>𝕣</span></code> and <code><span class='Value'>𝕗</span></code> are available in modifiers and <code><span class='Value'>𝕘</span></code> in 2-modifiers specifically.</p>
<p>When a block is pushed with <strong>DFND</strong>, an instance of the block is created, with its <em>parent frame</em> set to be the frame of the currently-executing block. Setting the parent frame when the block is first seen, instead of when it's evaluated, is what distinguishes lexical from dynamic scoping. If it's an immediate block, it's evaluated immediately, and otherwise it's pushed onto the stack. When the block is evaluated, its frame is initialized using any arguments passed to it, the next instruction's index is pushed onto the return stack, and execution moves to the first instruction in the block. When the RETN instruction is encountered, an index is popped from the return stack and execution returns to this location. As an alternative to maintaining an explicit return stack, a block can be implemented as a native function that creates a new execution stack and returns the value in it when the <strong>RETN</strong> instruction is reached. This approach uses the implementation language's call stack for the return stack.</p>
<p>Local variables are manipulated with the <strong>LOCO</strong> (or <strong>LOCU</strong>) and <strong>LOCM</strong> instructions, which load the value of a variable and a reference to it (see the next section) respectively. These instructions reference variables by <em>frame depth</em> and <em>slot index</em>. The frame depth indicates in which frame the variable is found: the current frame has depth 0, its block's parent frame has depth 1, and so on. The slot index is an index within that frame.</p>
<p>Slots should be initialized with some indication they are not yet defined. The variable can be defined with SETN only if it hasn't been defined yet, and can be accessed with LOCO or LOCU or modified with SETU or SETM only if it <em>has</em> been defined.</p>
-<h3 id="variable-references-arrm-locm-setn-setu-setm">Variable references: ARRM LOCM SETN SETU SETM</h3>
+<h3 id="variable-references-arrm-locm-setn-setu-setm"><a class="header" href="#variable-references-arrm-locm-setn-setu-setm">Variable references: ARRM LOCM SETN SETU SETM</a></h3>
<p>A <em>variable reference</em> indicates a particular frame slot in a way that's independent of the execution context. For example, it could be a pointer to the slot, or a reference to the frame along with the index of the slot. <strong>LOCM</strong> pushes a variable reference to the stack.</p>
<p>A <em>reference list</em> is a list of variable references or reference lists. It's created with the <strong>ARRM</strong> instruction. In the Javascript VM there's no difference between a reference list and an ordinary BQN list other than the contents.</p>
<p>The <strong>SETN</strong>, <strong>SETU</strong>, and <strong>SETM</strong> instructions set a value for a reference. If the reference is to a variable, they simply set its value. For a reference list, the value needs to be destructured. It must be a list of the same length, and each reference in the reference list is set to the corresponding element of the value list.</p>
<p><strong>SETM</strong> additionally needs to get the current value of a reference. For a variable reference this is its current value (with an error if it's not defined yet); for a reference list it's a list of the values of each reference in the list.</p>
-<h3 id="namespaces-fldo-fldm-nspm-retd">Namespaces: FLDO FLDM NSPM RETD</h3>
+<h3 id="namespaces-fldo-fldm-nspm-retd"><a class="header" href="#namespaces-fldo-fldm-nspm-retd">Namespaces: FLDO FLDM NSPM RETD</a></h3>
<p>A <em>namespace</em> is the collection of variables in a particular scope, along with an association mapping some exported <em>symbols</em> (case- and underscore-normalized strings) to a subset of these. It can be represented using a frame for the variables, plus the variable name list and mask of exported variables from that block's properties in the bytecode. <strong>RETD</strong> finishes executing the block and returns the namespace for that execution.</p>
<p>The variable name list is split into a program-level list of names and a list of indices into these names: within-program field accesses can be done with the indices only while cross-program ones must use names. One way to check whether an access is cross-program is to compare the accessor's program-level name list with the one for the accessed namespace as references or pointers. Then a lookup should be performed as appropriate. A persistent lookup table is needed to make this efficient.</p>
<p><strong>FLDO</strong> reads a field from a namespace. The parameter <code><span class='Function'>I</span></code> is a program-level identifier index for this field. The VM must ensure that the field is exported, possibly by leaving unexported identifiers out of the namespace's lookup table. <strong>FLDM</strong> does the same but pushes a reference to the field, to be modified by assignment.</p>
<p><strong>NSPM</strong> is used for aliased assignment such as <code><span class='Bracket'>⟨</span><span class='Value'>a</span><span class='Ligature'>‿</span><span class='Value'>b</span><span class='Gets'>⇐</span><span class='Value'>c</span><span class='Bracket'>⟩</span><span class='Gets'>←</span><span class='Value'>ns</span></code>. It tags a reference with a namespace field, identified with a program-level index. A value assigned to the tagged reference must be a namespace. The relevant field is extracted, and then stored in the original reference.</p>
-<h2 id="runtime">Runtime</h2>
+<h2 id="runtime"><a class="header" href="#runtime">Runtime</a></h2>
<p>Primitive functions and modifiers used in a program are stored in its <code><span class='Value'>consts</span></code> array. The compiler needs to be passed a <em>runtime</em> with the value of every primitive so that these functions and modifiers are available.</p>
<p>While it's perfectly possible to implement the runtime from scratch, the pseudo-BQN files <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../src/r0.bqn">r0.bqn</a> and <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../src/r1.bqn">r1.bqn</a> implement the full runtime in terms of a <em>core runtime</em> consisting of a smaller number of much simpler functions. <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../src/pr.bqn">pr.bqn</a> converts this file so that it can be compiled. It changes values in the core runtime to primitives and primitives to generated identifiers, so that the first 22 values in the output's <code><span class='Value'>consts</span></code> array are exactly the core runtime, and no other primitives are required. The result is a list of two elements: first the list of all primitive values, and then a function that can be called to pass in two additional core functions used for inferred properties.</p>
<p>The contents of a core runtime are given below. The names given are those used in r1.bqn; the environment only provides a list of values and therefore doesn't need to use the same names. For named functions a description is given. For primitives, the implementation should match the BQN specification for that primitive on the specified domain, or the entire domain if left empty. They won't be called outside that domain except if there are bugs in the BQN sources.</p>
@@ -600,7 +600,7 @@
</table>
<p>To define the final two functions, call the second returned element as a function, with argument <code><span class='Function'>Decompose</span><span class='Ligature'>‿</span><span class='Function'>PrimInd</span></code>. The function <code><span class='Function'>PrimInd</span></code> gives the index of <code><span class='Value'>𝕩</span></code> in the list of all primitives (defined as <code><span class='Value'>glyphs</span></code> in pr.bqn), or the length of the runtime if <code><span class='Value'>𝕩</span></code> is not a primitive. The two functions are only needed for computing inferred properties, and are defined by default so that every value is assumed to be a primitive, and <code><span class='Function'>PrimInd</span></code> performs a linear search over the returned runtime. If the runtime is used directly, then this means that without setting <code><span class='Function'>Decompose</span><span class='Ligature'>‿</span><span class='Function'>PrimInd</span></code>, function inferred properties will work slowly and for primitives only; if values from the runtime are wrapped then function inferred properties will not work at all.</p>
<p>Remember that <code><span class='Function'>+</span></code> and <code><span class='Function'>-</span></code> can also work on characters in some circumstances, under the rules of affine characters. Other arithmetic functions should only accept numbers. <code><span class='Function'>=</span></code> must work on any atoms including functions and modifiers. <code><span class='Function'>≤</span></code> must work on numbers and characters.</p>
-<h3 id="grouplen-and-groupord">GroupLen and GroupOrd</h3>
+<h3 id="grouplen-and-groupord"><a class="header" href="#grouplen-and-groupord">GroupLen and GroupOrd</a></h3>
<p>GroupLen and GroupOrd, short for Group length and Group order, are used to implement <a href="../doc/group.html">Group</a> (<code><span class='Function'>⊔</span></code>) and also to grade small-range lists and invert permutations (the inverse of a permutation <code><span class='Value'>p</span></code> is <code><span class='Number'>1</span><span class='Modifier'>¨</span><span class='Modifier2'>⊸</span><span class='Function'>GroupOrd</span> <span class='Value'>p</span></code>). Each of these only needs to work on lists of integers. Shown below are efficient implementations using BQN extended with the notation <code><span class='Paren'>(</span><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>l</span><span class='Paren'>)</span> <span class='Function'>Fn</span><span class='Gets'>↩</span> <span class='Value'>x</span></code> meaning <code><span class='Value'>l</span> <span class='Gets'>↩</span> <span class='Function'>Fn</span><span class='Modifier2'>⟜</span><span class='Value'>x</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Value'>i</span><span class='Modifier2'>⊸</span><span class='Function'>⊑</span><span class='Paren'>)</span> <span class='Value'>l</span></code>, where <code><span class='Function'>Fn</span></code> is <code><span class='Function'>⊢</span></code> if omitted. Since these special assignments only change one element of <code><span class='Value'>l</span></code>, each can be a fast constant-time operation.</p>
<pre><span class='Function'>GroupLen</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='Value'>l</span> <span class='Gets'>←</span> <span class='Number'>¯1</span> <span class='Function'>⌈</span><span class='Modifier'>´</span> <span class='Value'>𝕩</span>
@@ -617,10 +617,10 @@
<span class='Value'>r</span>
<span class='Brace'>}</span>
</pre>
-<h2 id="assembly">Assembly</h2>
+<h2 id="assembly"><a class="header" href="#assembly">Assembly</a></h2>
<p>The full BQN implementation is made up of the two components above—virtual machine and core runtime—and the compiled runtime, compiler, and formatter. Since the compiler unlikely to work right away, I suggest initially testing the virtual machine on smaller pieces of code compiled by an existing, working, BQN implementation.</p>
<p>BQN sources are compiled with <a href="https://github.com/mlochbaum/BQN/blob/master/implementation/../src/cjs.bqn">cjs.bqn</a>, which runs under <a href="https://github.com/dzaima/BQN/">dzaima/BQN</a> as a Unix-style script. It has two modes. If given a command-line argument <code><span class='Value'>r</span></code>, <code><span class='Value'>c</span></code>, or <code><span class='Value'>fmt</span></code>, it compiles one of the source files. With any other command-line arguments, it will compile each one, and format it as a single line of output. The output is in a format designed for Javascript, but it can be adjusted to work in other languages either by text replacement on the output or changes to the formatting functions in cjs.bqn.</p>
-<h3 id="structure">Structure</h3>
+<h3 id="structure"><a class="header" href="#structure">Structure</a></h3>
<p>The following steps give a working BQN system, assuming a working VM and core runtime:</p>
<ul>
<li>Evaluate the bytecode <code><span class='Value'>$</span> <span class='Value'>src</span><span class='Function'>/</span><span class='Value'>cjs.bqn</span> <span class='Value'>r</span></code>, passing the core runtime <code><span class='Value'>provide</span></code> in the constants array. The result is a BQN list of a full runtime, and a function <code><span class='Function'>SetPrims</span></code>.</li>
@@ -630,7 +630,7 @@
</ul>
<p>The compiler takes the runtime as <code><span class='Value'>𝕨</span></code> and source code as <code><span class='Value'>𝕩</span></code>. To evaluate BQN source code, convert it into a BQN string (rank-1 array of characters), pass this string and runtime to the compiler, and evaluate the result as bytecode. Results can be formatted with the formatter for use in a REPL, or used from the implementation language.</p>
<p>Two formatter arguments <code><span class='Function'>Glyph</span></code> and <code><span class='Function'>FmtNum</span></code> are not part of the runtime. <code><span class='Function'>Glyph</span></code> assumes <code><span class='Value'>𝕩</span></code> is a primitive and returns the character (not string) that represents it, and <code><span class='Function'>FmtNum</span></code> assumes <code><span class='Value'>𝕩</span></code> is a number and returns a string representing it.</p>
-<h3 id="testing">Testing</h3>
+<h3 id="testing"><a class="header" href="#testing">Testing</a></h3>
<p>I recommend roughly the following sequence of tests to get everything working smoothly. It can be very difficult to figure out where in a VM things went wrong, so it's important to work methodically and make sure each component is all right before moving to the next.</p>
<p>Because the compiler works almost entirely with lists of numbers, a correct fill implementation is not needed to run the compiler. Instead, you can define <code><span class='Function'>Fill</span></code> as <code><span class='Number'>0</span><span class='Modifier2'>⊘</span><span class='Function'>⊢</span></code> and <code><span class='Modifier2'>_fillBy_</span></code> as <code><span class='Brace'>{</span><span class='Function'>𝔽</span><span class='Brace'>}</span></code> to always use a fill element of 0.</p>
<ul>
diff --git a/docs/index.html b/docs/index.html
index 13f8df4b..a801a62e 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -4,7 +4,7 @@
<title>BQN: finally, an APL for your flying saucer</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>)</div>
-<h1 id="bqn-finally-an-apl-for-your-flying-saucer">BQN: finally, an APL for your flying saucer</h1>
+<h1 id="bqn-finally-an-apl-for-your-flying-saucer"><a class="header" href="#bqn-finally-an-apl-for-your-flying-saucer">BQN: finally, an APL for your flying saucer</a></h1>
<center>
<p><a href="doc/index.html">documentation</a> • <a href="spec/index.html">specification</a> • <a href="tutorial/index.html">tutorials</a> • <a href="implementation/index.html">implementation</a></p>
@@ -41,32 +41,32 @@
<li><a href="keymap.html"><strong>New symbols</strong></a> for built-in functionality make the syntactic role of every primitive instantly visible, and aim to be more consistent and intuitive.</li>
<li>No-nonsense <a href="doc/namespace.html"><strong>namespace syntax</strong></a> encapsulates data and even allows for a little <a href="doc/oop.html">object-oriented programming</a>.</li>
</ul>
-<h2 id="what-kind-of-name-is-bqn">What kind of name is &quot;BQN&quot;?</h2>
+<h2 id="what-kind-of-name-is-bqn"><a class="header" href="#what-kind-of-name-is-bqn">What kind of name is &quot;BQN&quot;?</a></h2>
<p>It's three letters, that happen to match the capitals in &quot;Big Questions Notation&quot;. You can pronounce it &quot;bacon&quot;, but are advised to avoid this unless there's puns.</p>
-<h2 id="what-does-bqn-look-like">What does BQN look like?</h2>
+<h2 id="what-does-bqn-look-like"><a class="header" href="#what-does-bqn-look-like">What does BQN look like?</a></h2>
<p>Rather strange, most likely:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqRK2DiiJjijL3ijZ8xMuKGlTIgICMgVGhlIDEydGggRmlib25hY2NpIG51bWJlcg==">↗️</a><pre> <span class='Function'>⊑+</span><span class='Modifier'>`</span><span class='Modifier2'>∘</span><span class='Function'>⌽</span><span class='Modifier2'>⍟</span><span class='Number'>12</span><span class='Function'>↕</span><span class='Number'>2</span> <span class='Comment'># The 12th Fibonacci number
</span>144
</pre>
<p>More snippets are programmed into the live demo at the top of the page: hit the arrow at the right of the code window to see them. For longer samples, you can <a href="https://github.com/mlochbaum/BQN/blob/master/src/c.bqn">gaze into the abyss</a> that is the self-hosted compiler, or the <a href="https://github.com/mlochbaum/BQN/blob/master/src/r1.bqn">shallower but wider abyss</a> of the runtime, or take a look at the friendlier <a href="https://github.com/mlochbaum/BQN/blob/master/md.bqn">markdown processor</a> used to format and highlight documentation files. This repository also has <a href="https://github.com/mlochbaum/BQN/blob/master/examples/fifty.bqn">some translations</a> from <a href="https://www.jsoftware.com/papers/50/">&quot;A History of APL in 50 Functions&quot;</a>.</p>
-<h2 id="how-do-i-work-with-the-character-set">How do I work with the character set?</h2>
+<h2 id="how-do-i-work-with-the-character-set"><a class="header" href="#how-do-i-work-with-the-character-set">How do I work with the character set?</a></h2>
<p>Right at the beginning, you can use the bar above the online REPL to enter BQN code: hover over a character to see a short description, and click to insert it into the editor. But you'll soon want to skip the clicking and use keyboard input. I type the special characters using a backslash escape, so that, for example, typing <code><span class='Value'>\</span></code> then <code><span class='Value'>z</span></code> writes <code><span class='Function'>⥊</span></code> (the backslash character itself is not used by BQN). The online REPL supports this method out of the box, and the <a href="editors/index.html">editor plugins</a> include or link to ways to enable it for editors, browsers, shells, and so on.</p>
<p>The <a href="https://mlochbaum.github.io/BQN/fonts.html">font comparison page</a> shows several fonts that support BQN (including the one used on this site, BQN386). Most other monospace fonts are missing some BQN characters, such as double-struck letters <code><span class='Value'>𝕨</span></code>, <code><span class='Value'>𝕩</span></code> and so on, which will cause these characters to be rendered with a fallback font and possibly have the wrong width or look inconsistent. The double-struck characters also require two bytes in UTF-16, which breaks rendering in many Windows terminals. If you have this problem, VS Code and <a href="https://github.com/mskyaxl/wsl-terminal">wsl-terminal</a> with an appropriate font definitely support them.</p>
-<h2 id="why-would-i-use-it">Why would I use it?</h2>
+<h2 id="why-would-i-use-it"><a class="header" href="#why-would-i-use-it">Why would I use it?</a></h2>
<p>There are plenty of clean, modern languages out there, and a good number of array languages. I don't think any other language fits both descriptions quite so well as BQN, and I find the combination lets me write powerful and reliable programs quickly. What you find in the language will depend on your background.</p>
<p>If you haven't yet used an array language, BQN will present you with new ways of thinking that can streamline the way you work with data and algorithms. There's no denying that array programming has begun to creep into the mainstream, and you might be wondering if BQN has anything to offer when you can hack reduces and filters with the best of them. It does: real array programming is different in character, with more and better array operations on immutable multidimensional arrays, and syntax better suited to them. Performance that resembles a low-level compiled language more than a high-level dynamic one. Primitives flow together and compose better—one aspect that sets BQN apart from other array languages is a set of combinators that's more intuitive than previous attempts. I also happen to think BQN's <a href="tutorial/expression.html#character-arithmetic">character arithmetic</a> system would improve just about any language.</p>
<p>If your favorite language is J, you are missing out even more! Array programmers never seem willing to accept that good ideas can come from people other than Iverson and that legends like John McCarthy and Barbara Liskov advanced human knowledge of how to express computation. They did, and being able to casually pass around first-class functions and mutable closures, with namespaces keeping everything organized, is a huge quality of life improvement. Writing APL again is claustrophobic, the syntax worries and constraints in functionality suddenly rushing back. BQN's mutable objects make methods such as graph algorithms that just don't have a good array implementation (no, your O(n³) matrix method doesn't scale) possible, even natural. With bytecode compilation and NaN-boxing, a natural fit for the based array model, it evaluates that scalar code many times faster than APL or J. The Unix-oriented scripting system stretches seamlessly from quick sketch to multi-file program.</p>
<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="how-do-i-get-started">How do I get started?</h2>
+<h2 id="how-do-i-get-started"><a class="header" href="#how-do-i-get-started">How do I get started?</a></h2>
<p><em>The documentation still has some pages missing (not many now), while the tutorials are probably less than half complete. I don't think this is much of an impediment any more. Ask about anything you find confusing on the forums.</em></p>
<p>BQN's <a href="tutorial/index.html"><strong>tutorials</strong></a> are intended as an introduction to array programming with BQN. They assume only knowledge of elementary mathematics, but will probably be hard to follow if you have <em>no</em> programming experience. BQN has a lot in common with dynamically-typed functional languages like Lisp, Julia, or Javascript, so knowledge of these languages will be particularly helpful. The tutorials end abruptly right now, so you'll have to switch to the documentation, which is less structured.</p>
<p>If you're already an array programmer, you might start with the <a href="doc/index.html"><strong>documentation</strong></a> right away, using the <a href="doc/fromDyalog.html">BQN-Dyalog APL</a> or <a href="doc/fromJ.html">BQN-J</a> dictionary as a quick reference where appropriate. Be aware of two key differences between BQN and existing array languages beyond just the changes of <a href="doc/primitive.html">primitives</a>—if these differences don't seem important to you then you don't understand them! BQN's <a href="doc/based.html">based array model</a> is different from both a flat array model like J and a nested one like APL2, Dyalog, or GNU APL in that it has true non-array values (plain numbers and characters) that are different from depth-0 scalars. BQN also uses <a href="doc/context.html">syntactic roles</a> rather than dynamic type to determine how values interact, that is, what's an argument or operand and so on. This system, along with lexical closures, means BQN fully supports Lisp-style <a href="doc/functional.html">functional programming</a>.</p>
<p>A useful tool for both beginners and experienced users is <a href="https://mlochbaum.github.io/bqncrate/"><strong>BQNcrate</strong></a>, a searchable collection of BQN snippets to solve particular tasks. If you have a question about how you might approach a problem, give it a try by typing in a relevant keyword or two.</p>
-<h2 id="where-can-i-find-bqn-users">Where can I find BQN users?</h2>
+<h2 id="where-can-i-find-bqn-users"><a class="header" href="#where-can-i-find-bqn-users">Where can I find BQN users?</a></h2>
<p>There's a BQN <a href="https://matrix.org/">Matrix</a> channel at #bqn:matrix.org, which you can see in the Element web client with <a href="https://app.element.io/#/room/%23bqn:matrix.org">this link</a>, and one on Discord that you can join with <a href="https://discord.gg/SDTW36EhWF">this invite</a>. The two channels are bridged so that comments in one appear in both. It's among the most active array programming forums, with conversations nearly every day, so you can definitely get your questions answered fast.</p>
<p>BQNBot will run your code from chat! Begin your message with <code><span class='Value'>bqn</span><span class='Paren'>)</span></code> and our friend (designation B-QN) will evaluate the rest and show the output. While putting your code in blocks <code><span class='Modifier'>`</span><span class='Value'>like</span> <span class='Value'>this</span><span class='Modifier'>`</span></code> is easier to read, the bot just operates on plain text and doesn't require it.</p>
<p>In addition to these forums, you can contact me personally via Github issues or with the email address shown in my Github profile.</p>
-<h2 id="can-i-help-out">Can I help out?</h2>
+<h2 id="can-i-help-out"><a class="header" href="#can-i-help-out">Can I help out?</a></h2>
<p>Certainly! There are never enough hours in the day and contributors from beginner to advanced programmers are all welcome. If you're interested I recommend you ask on the forums first to get a feel for what exactly is needed.</p>
<p>You will certainly feel an urge to skip this paragraph and get to the fun stuff, but the most important resource for implementing a language is <strong>testing</strong> and the most valuable one for building a language community is accessible introductions to the language and <strong>learning materials</strong>. These are both very demanding, but if you're willing to put in the work to advance BQN in the most effective way then this is it. One form of documentation that many users would appreciate is short descriptions—a sentence or two with examples—of the primitives for each glyph that can be displayed as help in the REPL. To be honest I'm lousy at making these and would prefer for someone else to do it.</p>
<p>Work on BQN's <strong>implementation</strong> generally requires a high level of programming skill. We are focusing development effort on <a href="https://github.com/dzaima/CBQN">CBQN</a>. It's true that the entire compiler and a (decreasing) portion of the runtime is written in BQN, but it would be hard to do much with these as they are very nearly complete, and work satisfactorily. On the other hand, there is a lot that needs to be written in C, including <a href="spec/system.html">system values</a> and higher-performance <a href="implementation/primitive/index.html">primitives</a>. And there's no need to work on <em>our</em> implementation! BQN's <a href="spec/index.html">specification</a> and <a href="https://github.com/mlochbaum/BQN/blob/master/test/README.txt">tests</a> are there to make sure you can write a conforming implementation, and extend it with your own ideas. It's also possible to take advantage of the self-hosted BQN sources by writing a <a href="implementation/vm.html">virtual machine</a> that allows you to embed BQN in the language of your choice.</p>
diff --git a/docs/keymap.html b/docs/keymap.html
index 5b70ec05..fdb26f6a 100644
--- a/docs/keymap.html
+++ b/docs/keymap.html
@@ -13,7 +13,7 @@
</head>
<body>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="index.html">BQN</a></div>
-<h1 id="keymap">BQN keymap</h1>
+<h1>BQN keymap</h1>
<p>The standard BQN keymap is shown below. Note that characters <code>⍎⍕↙↖⍳</code>, included for historical or speculative reasons, are not used by BQN. And don't miss spacebar for <code class='Ligature'>‿</code> at the bottom!</p>
<div class="center"><pre>┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────────┐
│~ <span class='Function'>¬</span> │<span class='Function'>!</span> <span class='Modifier2'>⎉</span> │<span class='String'>@</span> <span class='Modifier2'>⚇</span> │<span class='Comment'>#</span> <span class='Modifier2'>⍟</span> │$ <span class='Modifier2'>◶</span> │% <span class='Modifier2'>⊘</span> │^ <span class='Modifier2'>⎊</span> │&amp; ⍎ │* ⍕ │<span class='Paren'>(</span> <span class='Bracket'>⟨</span> │<span class='Paren'>)</span> <span class='Bracket'>⟩</span> │_ <span class='Function'>√</span> │<span class='Function'>+</span> <span class='Function'>⋆</span> │Backspace│
diff --git a/docs/running.html b/docs/running.html
index c69ec64d..4d1aac71 100644
--- a/docs/running.html
+++ b/docs/running.html
@@ -4,10 +4,10 @@
<title>How to run BQN</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="index.html">BQN</a></div>
-<h1 id="how-to-run-bqn">How to run BQN</h1>
+<h1 id="how-to-run-bqn"><a class="header" href="#how-to-run-bqn">How to run BQN</a></h1>
<p>We are currently working quickly to make <a href="https://github.com/dzaima/CBQN">CBQN</a> into the definitive offline implementation. Compilation speed (self-hosted) is good, the only significant core language feature missing is block headers and multiple bodies, and the essential system functions are there. Unless you need to start heavy number crunching right away, I recommend that you use CBQN and make system function or performance requests on Github or the BQN forums.</p>
<p>A lot of development to date has been done in dzaima/BQN and uses features (mainly headers) that aren't in CBQN yet. Scripts in this repository use <code><span class='Value'>bqn</span></code> in the <code><span class='Comment'>#!</span></code> line if self-hosted or dzaima/BQN can run them, and <code><span class='Value'>dbqn</span></code> if only dzaima/BQN works.</p>
-<h3 id="self-hosted-bqn">Self-hosted BQN</h3>
+<h3 id="self-hosted-bqn"><a class="header" href="#self-hosted-bqn">Self-hosted BQN</a></h3>
<p>See the subsections below for instructions on specific implementations.</p>
<p>This version of BQN is <a href="implementation/index.html">implemented</a> mainly in BQN itself, but a host language supplies basic functionality and can also replace primitives for better performance. This also allows <a href="doc/embed.html">embedding</a>, where programs in the host language can include BQN code. It fully supports all primitives except a few cases of structural Under (<code><span class='Modifier2'>⌾</span></code>), but is still missing some advanced features: block headers and multiple body syntax, derived 1-modifiers, and block returns.</p>
<p>Support in the following languages has been implemented:</p>
@@ -17,13 +17,13 @@
<li>dzaima/BQN (<a href="https://github.com/mlochbaum/BQN/blob/master/bqn.bqn">bqn.bqn</a>), mainly for testing.</li>
<li><a href="https://github.com/cannadayr/ebqn">Erlang</a>, intended for embedding. Too slow to be practical yet: minutes to compile short programs.</li>
</ul>
-<h4 id="javascript">Javascript</h4>
+<h4 id="javascript"><a class="header" href="#javascript">Javascript</a></h4>
<p>The online REPL is <a href="https://mlochbaum.github.io/BQN/try.html">here</a>. The file <a href="https://github.com/mlochbaum/BQN/blob/master/docs/bqn.js">docs/bqn.js</a> is zero-dependency Javascript, and can be loaded from HTML or Node.js. For command line use, call the Node.js script <a href="https://github.com/mlochbaum/BQN/blob/master/bqn.js">bqn.js</a>, passing a file and <code><span class='Value'>•args</span></code>, or <code><span class='Function'>-</span><span class='Value'>e</span></code> to execute all remaining arguments directly and print the results. <a href="https://observablehq.com/@lsh/bqn">This notebook</a> shows how to run it in an Observable notebook.</p>
-<h4 id="cbqn">CBQN</h4>
+<h4 id="cbqn"><a class="header" href="#cbqn">CBQN</a></h4>
<p>C sources are kept in the <a href="https://github.com/dzaima/CBQN">CBQN</a> repository, but it also depends on bytecode from the BQN sources here. Running <code><span class='Value'>make</span></code> gets a working copy right away with saved bytecode. Then to use the latest bytecode, call <code><span class='Value'>$</span> <span class='Value'>.</span><span class='Function'>/BQN</span> <span class='Value'>genRuntime</span> <span class='Value'>…</span><span class='Function'>/BQN</span></code>, where <code><span class='Value'>…</span><span class='Function'>/BQN</span></code> points to this repository, and run <code><span class='Value'>make</span></code> again.</p>
<p><code><span class='Value'>genRuntime</span></code> can also be run with another BQN implementation (the Node.js one works but takes up to a minute), and plain <code><span class='Value'>.</span><span class='Function'>/</span><span class='Value'>genRuntime</span></code> uses your system's <code><span class='Value'>bqn</span></code> executable. I symlink <code><span class='Value'>…</span><span class='Function'>/CBQN/BQN</span></code> to <code><span class='Value'>~</span><span class='Function'>/</span><span class='Value'>bin</span><span class='Function'>/</span><span class='Value'>bqn</span></code> so I can easily use CBQN for scripting.</p>
<p>CBQN uses the self-hosted runtime to achieve full primitive coverage, and implements specific primitives or parts of primitives natively to speed them up. This means primitives with native support—including everything used by the compiler—are fairly fast while others are much slower.</p>
-<h3 id="dzaimabqn">dzaima/BQN</h3>
+<h3 id="dzaimabqn"><a class="header" href="#dzaimabqn">dzaima/BQN</a></h3>
<p><a href="https://github.com/dzaima/BQN/">dzaima/BQN</a> is an implementation in Java created by modifying the existing dzaima/APL, and should be easy to run on desktop Linux and Android. It may be abandoned as dzaima is now working on CBQN. It has almost complete syntax support but incomplete primitive support: major missing functionality is dyadic Depth (<code><span class='Modifier2'>⚇</span></code>), Windows (<code><span class='Function'>↕</span></code>), and many cases of set functions (<code><span class='Function'>⊐⊒∊⍷</span></code>, mostly with rank &gt;1).</p>
<p>In this repository and elsewhere, dzaima/BQN scripts are called with <code><span class='Comment'>#! /usr/bin/env dbqn</span></code>. This requires an executable file <code><span class='Value'>dbqn</span></code> somewhere in your path with the following contents:</p>
<pre><span class='Comment'>#! /bin/bash
@@ -31,7 +31,7 @@
<span class='Value'>java</span> <span class='Function'>-</span><span class='Value'>jar</span> <span class='Function'>/</span><span class='Value'>path</span><span class='Function'>/</span><span class='Value'>to</span><span class='Function'>/</span><span class='Value'>dzaima</span><span class='Function'>/BQN/BQN</span><span class='Value'>.jar</span> <span class='String'>&quot;$@&quot;</span>
</pre>
<p>If compiled with Native Image, <code><span class='Value'>nBQN</span></code> can be used directly instead.</p>
-<h4 id="dzaimareference-bqn">dzaima+reference BQN</h4>
+<h4 id="dzaimareference-bqn"><a class="header" href="#dzaimareference-bqn">dzaima+reference BQN</a></h4>
<p>This repository contains a dzaima/BQN script <code><span class='Value'>dzref</span></code> that fills in gaps in primitive support with BQN implementations. dzaima/BQN has good enough primitive support that I now almost never use this, but it's still needed for the website generator md.bqn. The command-line arguments are a script to run and followed by the <code><span class='Value'>•args</span></code> to supply to it.</p>
-<h3 id="bqn2ngn">BQN2NGN</h3>
+<h3 id="bqn2ngn"><a class="header" href="#bqn2ngn">BQN2NGN</a></h3>
<p><a href="https://github.com/mlochbaum/BQN2NGN">BQN2NGN</a> is a prototype implementation in Javascript build to experiment with the langauge, which is now abandoned.</p>
diff --git a/docs/spec/evaluate.html b/docs/spec/evaluate.html
index 044f534c..2d1e5ce9 100644
--- a/docs/spec/evaluate.html
+++ b/docs/spec/evaluate.html
@@ -4,22 +4,22 @@
<title>Specification: BQN evaluation</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">spec</a></div>
-<h1 id="specification-bqn-evaluation">Specification: BQN evaluation</h1>
+<h1 id="specification-bqn-evaluation"><a class="header" href="#specification-bqn-evaluation">Specification: BQN evaluation</a></h1>
<p>This page describes the semantics of the code constructs whose grammar is given in <a href="grammar.html">grammar.md</a>. The formation rules there are not named, and here they are identified by either the name of the term or by copying the rule entirely if there are several alternative productions.</p>
<p>Here we assume that the referent of each identifier, or equivalently the connections between identifiers, have been identified according to the <a href="scope.html">scoping rules</a>.</p>
<p>Evaluation is an ordered process, and any actions required to evaluate a node always have a specified order unless performing them in any order would have the same effect. Side effects that are relevant to ordering are setting and getting the value of a variable, causing an error, and returning (with <code><span class='Gets'>→</span></code>) from a block. Errors described in this page are &quot;evaluation errors&quot; and can be caught by the Catch (<code><span class='Modifier2'>⎊</span></code>) modifier. For caught errors and returns, evaluation halts without attempting to complete any in-progress node, and is restarted by Catch (for errors) or at the end of the appropriate block evaluation (for returns).</p>
-<h3 id="programs-and-blocks">Programs and blocks</h3>
+<h3 id="programs-and-blocks"><a class="header" href="#programs-and-blocks">Programs and blocks</a></h3>
<p>The result of parsing a valid BQN program is a <code><span class='Function'>PROGRAM</span></code>, and the program is run by evaluating this term.</p>
<p>A <code><span class='Function'>PROGRAM</span></code> or <code><span class='Function'>BODY</span></code> is a list of <code><span class='Function'>STMT</span></code>s, which are evaluated in program order. A result is always required for <code><span class='Function'>BODY</span></code> nodes, and sometimes for <code><span class='Function'>PROGRAM</span></code> nodes (for example, when loaded with <code><span class='Function'>•Import</span></code>). If any identifiers in the node's scope are exported, or any of its statements is an <code><span class='Function'>EXPORT</span></code>, then the result is the namespace created in order to evaluate the node. If a result is required but the namespace case doesn't apply, then the last <code><span class='Function'>STMT</span></code> node must be an <code><span class='Function'>EXPR</span></code> and its result is used. The statement <code><span class='Function'>EXPR</span></code> evaluates some APL code and possibly assigns the results, while <code><span class='Value'>nothing</span></code> evaluates any <code><span class='Value'>subject</span></code> or <code><span class='Function'>Derv</span></code> terms it contains but discards the results. An <code><span class='Function'>EXPORT</span></code> statement performs no action.</p>
<p>A block consists of several <code><span class='Function'>BODY</span></code> terms, some of which may have an accompanying header describing accepted inputs and how they are processed. An immediate block <code><span class='Value'>brImm</span></code> can only have one <code><span class='Function'>BODY</span></code>, and is evaluated by evaluating the code in it. Other types of blocks do not evaluate any <code><span class='Function'>BODY</span></code> immediately, but instead return a function or modifier that obtains its result by evaluating a particular <code><span class='Function'>BODY</span></code>. The <code><span class='Function'>BODY</span></code> is identified and evaluated once the block has received enough inputs (operands or arguments), which for modifiers can take one or two calls: if two calls are required, then on the first call the operands are simply stored and no code is evaluated yet. Two calls are required if there is more than one <code><span class='Function'>BODY</span></code> term, if the <code><span class='Function'>BODY</span></code> contains the special names <code><span class='Value'>𝕨𝕩𝕤</span><span class='Function'>𝕎𝕏𝕊</span></code>, or if its header specifies arguments (the header-body combination is a <code><span class='Modifier'>_mCase</span></code> or <code><span class='Modifier2'>_cCase_</span></code>). Otherwise only one is required.</p>
<p>To evaluate a block when enough inputs have been received, first the correct case must be identified. To do this, first each special case (<code><span class='Function'>FCase</span></code>, <code><span class='Modifier'>_mCase</span></code>, or <code><span class='Modifier2'>_cCase_</span></code>), excluding <code><span class='Function'>FCase</span></code> nodes containing <code><span class='Function'>UndoHead</span></code>, is checked in order to see if its arguments are strucurally compatible with the given arguments. That is, is <code><span class='Value'>headW</span></code> is a <code><span class='Value'>subject</span></code>, there must be a left argument matching that structure, and if <code><span class='Value'>headX</span></code> is a <code><span class='Value'>subject</span></code>, the right argument must match that structure. This means that <code><span class='Value'>𝕨</span></code> not only matches any left argument but also no argument. The test for compatibility is the same as for multiple assignment described below, except that the header may contain constants, which must match the corresponding part of the given argument. If no special case matches, then an appropriate general case (<code><span class='Function'>FMain</span></code>, <code><span class='Modifier'>_mMain</span></code>, or <code><span class='Modifier2'>_cMain_</span></code>) is used: if there are two, the first is used with no left argument and the second with a left argument; if there are one, it is always used, and if there are none, an error results.</p>
<p>The only remaining step before evaluating the <code><span class='Function'>BODY</span></code> is to bind the inputs and other names. Special names are always bound when applicable: <code><span class='Value'>𝕨𝕩𝕤</span></code> if arguments are used, <code><span class='Value'>𝕨</span></code> if there is a left argument, <code><span class='Value'>𝕗𝕘</span></code> if operands are used, and <code><span class='Modifier'>_𝕣</span></code> and <code><span class='Modifier2'>_𝕣_</span></code> for modifiers and combinators, respectively. Any names in the header are also bound, allowing multiple assignment for arguments.</p>
<p>If there is no left argument, but the <code><span class='Function'>BODY</span></code> contains <code><span class='Value'>𝕨</span></code> or <code><span class='Function'>𝕎</span></code> at the top level, then it is conceptually re-parsed with <code><span class='Value'>𝕨</span></code> replaced by <code><span class='Nothing'>·</span></code> to give a monadic version before application; this modifies the syntax tree by replacing some instances of <code><span class='Value'>subject</span></code>, <code><span class='Value'>arg</span></code>, or <code><span class='Function'>Operand</span></code> with <code><span class='Value'>nothing</span></code>. The token <code><span class='Function'>𝕎</span></code> is not allowed in this case and causes an error. Re-parsing <code><span class='Value'>𝕨</span></code> can also cause an error if it's used as an operand or list element, where <code><span class='Value'>nothing</span></code> is not allowed by the grammar. Note that these errors must not appear if the block is always called with two arguments. True re-parsing is not required, as the same effect can also be achieved dynamically by treating <code><span class='Nothing'>·</span></code> as a value and checking for it during execution. If it's used as a left argument, then the function should instead be called with no left argument (and similarly in trains); if it's used as a right argument, then the function and its left argument are evaluated but rather than calling the function <code><span class='Nothing'>·</span></code> is &quot;returned&quot; immediately; and if it's used in another context then it causes an error.</p>
-<h3 id="assignment">Assignment</h3>
+<h3 id="assignment"><a class="header" href="#assignment">Assignment</a></h3>
<p>An <em>assignment</em> is one of the four rules containing <code><span class='Function'>ASGN</span></code>. It is evaluated by first evaluating the right-hand-side <code><span class='Value'>subExpr</span></code>, <code><span class='Function'>FuncExpr</span></code>, <code><span class='Modifier'>_m1Expr</span></code>, or <code><span class='Modifier2'>_m2Exp_</span></code> expression, and then storing the result in the left-hand-side identifier or identifiers. The result of the assignment expression is the result of its right-hand side. Except for subjects, only a lone identifier is allowed on the left-hand side and storage sets it equal to the result. For subjects, <em>destructuring assignment</em> is performed when an <code><span class='Value'>lhs</span></code> is <code><span class='Value'>lhsList</span></code> or <code><span class='Value'>lhsStr</span></code>. Destructuring assignment is performed recursively by assigning right-hand-side values to the left-hand-side targets, with single-identifier assignment as the base case.</p>
<p>The right-hand-side value, here called <code><span class='Value'>v</span></code>, in destructuring assignment must be a list (rank 1 array) or namespace. If it's a list, then each <code><span class='Function'>LHS_ENTRY</span></code> node must be an <code><span class='Function'>LHS_ELT</span></code>. The left-hand side is treated as a list of <code><span class='Value'>lhs</span></code> targets, and matched to <code><span class='Value'>v</span></code> element-wise, with an error if the two lists differ in length. If <code><span class='Value'>v</span></code> is a namespace, then the left-hand side must be an <code><span class='Value'>lhsStr</span></code> where every <code><span class='Function'>LHS_ATOM</span></code> is an <code><span class='Function'>LHS_NAME</span></code>, or an <code><span class='Value'>lhsList</span></code> where every <code><span class='Function'>LHS_ENTRY</span></code> is an <code><span class='Function'>LHS_NAME</span></code> or <code><span class='Value'>lhs</span> <span class='String'>&quot;⇐&quot;</span> <span class='Function'>LHS_NAME</span></code>, so that it can be considered a list of <code><span class='Function'>LHS_NAME</span></code> nodes some of which are also associated with <code><span class='Value'>lhs</span></code> nodes. To perform the assignment, the value of each name is obtained from the namespace <code><span class='Value'>v</span></code>, giving an error if <code><span class='Value'>v</span></code> does not define that name. The value is assigned to the <code><span class='Value'>lhs</span></code> node if present (which may be a destructuring assignment or simple subject assignment), and otherwise assigned to the same <code><span class='Function'>LHS_NAME</span></code> node used to get it from <code><span class='Value'>v</span></code>.</p>
<p><em>Modified assignment</em> is the subject assignment rule <code><span class='Value'>lhs</span> <span class='Function'>Derv</span> <span class='String'>&quot;↩&quot;</span> <span class='Value'>subExpr</span></code>. In this case, <code><span class='Value'>lhs</span></code> should be evaluated as if it were a <code><span class='Value'>subExpr</span></code> (the syntax is a subset of <code><span class='Value'>subExpr</span></code>), and the result of the function application <code><span class='Value'>lhs</span> <span class='Function'>Derv</span> <span class='Value'>subExpr</span></code> should be assigned to <code><span class='Value'>lhs</span></code>, and is also the result of the modified assignment expression.</p>
-<h3 id="expressions">Expressions</h3>
+<h3 id="expressions"><a class="header" href="#expressions">Expressions</a></h3>
<p>We now give rules for evaluating an <code><span class='Value'>atom</span></code>, <code><span class='Function'>Func</span></code>, <code><span class='Modifier'>_mod1</span></code> or <code><span class='Modifier2'>_mod2_</span></code> expression (the possible options for <code><span class='Function'>ANY</span></code>). A literal or primitive <code><span class='Value'>sl</span></code>, <code><span class='Function'>Fl</span></code>, <code><span class='Modifier'>_ml</span></code>, or <code><span class='Modifier2'>_cl_</span></code> has a fixed value defined by the specification (<a href="literal.html">literals</a> and <a href="primitive.html">built-ins</a>). An identifier <code><span class='Value'>s</span></code>, <code><span class='Function'>F</span></code>, <code><span class='Modifier'>_m</span></code>, or <code><span class='Modifier2'>_c_</span></code>, if not preceded by <code><span class='Value'>atom</span> <span class='String'>&quot;.&quot;</span></code>, must have an associated variable due to the scoping rules, and returns this variable's value, or causes an error if it has not yet been set. If it is preceded by <code><span class='Value'>atom</span> <span class='String'>&quot;.&quot;</span></code>, then the <code><span class='Value'>atom</span></code> node is evaluated first; its value must be a namespace, and the result is the value of the identifier's name in the namespace, or an error if the name is undefined. A parenthesized expression such as <code><span class='String'>&quot;(&quot;</span> <span class='Modifier'>_modExpr</span> <span class='String'>&quot;)&quot;</span></code> simply returns the result of the interior expression. A braced construct such as <code><span class='Function'>BraceFunc</span></code> is defined by the evaluation of the statements it contains after all parameters are accepted. Finally, a list <code><span class='String'>&quot;⟨&quot;</span> <span class='Separator'>⋄</span><span class='Value'>?</span> <span class='Paren'>(</span> <span class='Paren'>(</span> <span class='Function'>EXPR</span> <span class='Separator'>⋄</span> <span class='Paren'>)</span><span class='Value'>*</span> <span class='Function'>EXPR</span> <span class='Separator'>⋄</span><span class='Value'>?</span> <span class='Paren'>)</span><span class='Value'>?</span> <span class='String'>&quot;⟩&quot;</span></code> or <code><span class='Function'>ANY</span> <span class='Paren'>(</span> <span class='String'>&quot;‿&quot;</span> <span class='Function'>ANY</span> <span class='Paren'>)</span><span class='Function'>+</span></code> consists grammatically of a list of expressions. To evaluate it, each expression is evaluated in source order and their results are placed as elements of a rank-1 array. The two forms have identical semantics but different punctuation.</p>
<p>A <code><span class='Function'>Return</span></code> node creates a return function. As <a href="scope.html#returns">discussed</a> in the scoping rules, its identifier indicates a namespace from a particular block evaluation. When called, the function causes an error if that block has finished execution, or if the call includes a left argument <code><span class='Value'>𝕨</span></code>. Otherwise, evaluation stops immediately, and resumes at the end of the block where it returns the right argument <code><span class='Value'>𝕩</span></code> from that block.</p>
<p>Rules in the table below are function and modifier evaluation.</p>
diff --git a/docs/spec/grammar.html b/docs/spec/grammar.html
index 3ad5bd25..da83d87c 100644
--- a/docs/spec/grammar.html
+++ b/docs/spec/grammar.html
@@ -4,7 +4,7 @@
<title>Specification: BQN grammar</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">spec</a></div>
-<h1 id="specification-bqn-grammar">Specification: BQN grammar</h1>
+<h1 id="specification-bqn-grammar"><a class="header" href="#specification-bqn-grammar">Specification: BQN grammar</a></h1>
<p>BQN's grammar is given below. Terms are defined in a <a href="https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form">BNF</a> variant. However, handling special names properly is possible but difficult in BNF, so they are explained in text along with the braced block grammar.</p>
<p>The symbols <code><span class='Value'>s</span></code>, <code><span class='Function'>F</span></code>, <code><span class='Modifier'>_m</span></code>, and <code><span class='Modifier2'>_c_</span></code> are identifier tokens with subject, function, 1-modifier, and 2-modifier classes respectively. Similarly, <code><span class='Value'>sl</span></code>, <code><span class='Function'>Fl</span></code>, <code><span class='Modifier'>_ml</span></code>, and <code><span class='Modifier2'>_cl_</span></code> refer to literals and primitives of those classes. While names in the BNF here follow the identifier naming scheme, this is informative only: syntactic roles are no longer used after parsing and cannot be inspected in a running program.</p>
<p>A program is a list of statements. Almost all statements are expressions. Namespace export statements, and valueless results stemming from <code><span class='Nothing'>·</span></code>, or <code><span class='Value'>𝕨</span></code> in a monadic brace function, can be used as statements but not expressions.</p>
diff --git a/docs/spec/index.html b/docs/spec/index.html
index b8f1d80e..fa8ad8c9 100644
--- a/docs/spec/index.html
+++ b/docs/spec/index.html
@@ -4,7 +4,7 @@
<title>BQN specification</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a></div>
-<h1 id="bqn-specification">BQN specification</h1>
+<h1 id="bqn-specification"><a class="header" href="#bqn-specification">BQN specification</a></h1>
<p>This document, and the others in this directory (linked in the list below) make up the pre-versioning BQN specification. The specification differs from the <a href="../doc/index.html">documentation</a> in that its purpose is only to describe the exact details of BQN's operation in the most quickly accessible way, rather than to explain the central ideas of BQN functionality and how it might be used. The core of BQN, which excludes system-provided values, is now almost completely specified. One planned feature—an extension to allow low-rank elements in the argument to Join—has not yet been added, and the spec will continue to be edited further to improve clarity and cover any edge cases that have been missed.</p>
<p>Under this specification, a language implementation is a <strong>BQN pre-version implementation</strong> if it behaves as specified for all input programs. It is a <strong>BQN pre-version implementation with extensions</strong> if it behaves as specified in all cases where the specification does not require an error, but behaves differently in at least one case where it requires an error. It is a <strong>partial</strong> version of either of these if it doesn't conform to the description but differs from a conforming implementation only by rejecting with an error some programs that the conforming implementation accepts. As the specification is not yet versioned, other instances of the specification define these terms in different ways. An implementation can use one of these terms if it conforms to any instance of the pre-versioning BQN specifications that defines them. When versioning is begun, there will be only one specification for each version.</p>
<p>The following documents are included in the BQN specification. A BQN program is a sequence of <a href="https://en.wikipedia.org/wiki/Unicode">Unicode</a> code points: to evaluate it, it is converted into a sequence of tokens using the token formation rules, then these tokens are arranged in a syntax tree according to the grammar, and then this tree is evaluated according to the evaluation semantics. The program may be evaluated in the presence of additional context such as a filesystem or command-line arguments; this context is presented to the program and manipulated through the system-provided values.</p>
diff --git a/docs/spec/inferred.html b/docs/spec/inferred.html
index c25ad29c..c0deb923 100644
--- a/docs/spec/inferred.html
+++ b/docs/spec/inferred.html
@@ -4,11 +4,11 @@
<title>Specification: BQN inferred properties</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">spec</a></div>
-<h1 id="specification-bqn-inferred-properties">Specification: BQN inferred properties</h1>
+<h1 id="specification-bqn-inferred-properties"><a class="header" href="#specification-bqn-inferred-properties">Specification: BQN inferred properties</a></h1>
<p>BQN includes some simple deductive capabilities: detecting the type of empty array elements, the result of an empty reduction, and the Undo (<code><span class='Modifier'>⁼</span></code>) and Under (<code><span class='Modifier2'>⌾</span></code>) modifiers. These tasks are a kind of proof-based or constraint programming, and can never be solved completely (some instances will be undecidable) but can be solved in more instances by ever-more sophisticated algorithms. To allow implementers to develop more advanced implementations while offering some stability and portability to programmers, two kinds of specification are given here. First, constraints are given on the behavior of inferred properties. These are not exact and require some judgment on the part of the implementer. Second, behavior for common or useful cases is specified more precisely. Non-normative suggestions are also given as a reference for implementers.</p>
<p>For the specified cases, the given functions and modifiers refer to those particular representations. It is not necessary to detect equivalent representations, for example to reduce <code><span class='Paren'>(</span><span class='Function'>+-×</span><span class='Paren'>)</span><span class='Modifier'>⁼</span></code> to <code><span class='Function'>∨</span><span class='Modifier'>⁼</span></code>. However, it is necessary to identify computed functions and modifiers: for example <code><span class='Function'>F</span><span class='Modifier'>⁼</span></code> when the value of <code><span class='Function'>F</span></code> in the expression is <code><span class='Function'>∨</span></code>, or <code><span class='Paren'>(</span><span class='Number'>1</span><span class='Function'>⊑∧</span><span class='Ligature'>‿</span><span class='Function'>∨</span><span class='Paren'>)</span><span class='Modifier'>⁼</span></code>.</p>
<p>Failing to compute an inferred property for a function or array as it's created cannot cause an error. An error can only be caused when the missing inferred property is needed for a computation.</p>
-<h2 id="identities">Identities</h2>
+<h2 id="identities"><a class="header" href="#identities">Identities</a></h2>
<p>When monadic Fold (<code><span class='Modifier'>´</span></code>) or Insert (<code><span class='Modifier'>˝</span></code>) is called on an array of length 0, BQN attempts to infer a right identity value for the function in order to determine the result. A right identity value for a dyadic function <code><span class='Function'>𝔽</span></code> is a value <code><span class='Value'>r</span></code> such that <code><span class='Value'>e</span><span class='Function'>≡</span><span class='Value'>e</span><span class='Function'>𝔽</span><span class='Value'>r</span></code> for any element <code><span class='Value'>e</span></code> in the domain. For such a value <code><span class='Value'>r</span></code>, the fold <code><span class='Value'>r</span> <span class='Function'>𝔽</span><span class='Modifier'>´</span> <span class='Value'>l</span></code> is equivalent to <code><span class='Function'>𝔽</span><span class='Modifier'>´</span> <span class='Value'>l</span></code> for a non-empty list <code><span class='Value'>l</span></code>, because the first application <code><span class='Paren'>(</span><span class='Number'>¯1</span><span class='Function'>⊑</span><span class='Value'>l</span><span class='Paren'>)</span> <span class='Function'>𝔽</span> <span class='Value'>r</span></code> gives <code><span class='Number'>¯1</span><span class='Function'>⊑</span><span class='Value'>l</span></code>, which is the starting point when no initial value is given. It's thus reasonable to define <code><span class='Function'>𝔽</span><span class='Modifier'>´</span> <span class='Value'>l</span></code> to be <code><span class='Value'>r</span> <span class='Function'>𝔽</span><span class='Modifier'>´</span> <span class='Value'>l</span></code> for an empty list <code><span class='Value'>l</span></code> as well, giving a result <code><span class='Value'>r</span></code>.</p>
<p>For Fold, the result of <code><span class='Function'>𝔽</span><span class='Modifier'>´</span></code> on an empty list is defined to be a right identity value for the <em>range</em> of <code><span class='Function'>𝔽</span></code>, if exactly one such value exists. If an identity can't be proven to uniquely exist, then an error results.</p>
<p>For Insert, <code><span class='Function'>𝔽</span><span class='Modifier'>˝</span></code> on an array of length 0 is defined similarly, but also depends on the cell shape <code><span class='Number'>1</span><span class='Function'>↓≢</span><span class='Value'>𝕩</span></code>. The required domain is the arrays of that shape that also lie in the range of <code><span class='Function'>𝔽</span></code> (over arbitrary arguments, not shape-restricted ones). Furthermore, an identity may be unique among all possible arguments as in the case of Fold, or it may be an array with shape <code><span class='Number'>1</span><span class='Function'>↓≢</span><span class='Value'>𝕩</span></code> and be unique among arrays with that shape. For example, with cell shape <code><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span></code>, all of <code><span class='Number'>0</span></code>, <code><span class='Number'>2</span><span class='Function'>⥊</span><span class='Number'>0</span></code>, and <code><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Function'>⥊</span><span class='Number'>0</span></code> are identities for <code><span class='Function'>+</span></code>, but <code><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Function'>⥊</span><span class='Number'>0</span></code> can be used because it is the only indentity with shape <code><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span></code>, while the other identities aren't unique and can't be used.</p>
@@ -68,11 +68,11 @@
</tbody>
</table>
<p>Additionally, the identity of <code><span class='Function'>∾</span><span class='Modifier'>˝</span></code> must be recognized: if <code><span class='Number'>0</span><span class='Function'>=≠</span><span class='Value'>𝕩</span></code> and <code><span class='Number'>1</span><span class='Function'>&lt;=</span><span class='Value'>𝕩</span></code>, then <code><span class='Function'>∾</span><span class='Modifier'>˝</span><span class='Value'>𝕩</span></code> is <code><span class='Paren'>(</span><span class='Number'>0</span><span class='Function'>∾</span><span class='Number'>2</span><span class='Function'>↓≢</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Function'>⥊</span><span class='Value'>𝕩</span></code>. If <code><span class='Number'>1</span><span class='Function'>==</span><span class='Value'>𝕩</span></code>, then there is no identity element, as the result of <code><span class='Function'>∾</span></code> always has rank at least 1, but the cell rank is 0.</p>
-<h2 id="fill-elements">Fill elements</h2>
+<h2 id="fill-elements"><a class="header" href="#fill-elements">Fill elements</a></h2>
<p>Any BQN array can have a <em>fill element</em>, which is a sort of &quot;default&quot; value for the array. The reference implementations use <code><span class='Function'>Fill</span></code> to access this element, and it is used primarily for Take (<code><span class='Function'>↑</span></code>), First (<code><span class='Function'>⊑</span></code>), and Nudge (<code><span class='Function'>«</span></code>, <code><span class='Function'>»</span></code>). One way to extract the fill element of an array <code><span class='Value'>a</span></code> in BQN is <code><span class='Function'>⊑</span><span class='Number'>0</span><span class='Function'>⥊</span><span class='Value'>a</span></code>.</p>
<p>A fill element can be either <code><span class='Number'>0</span></code>, <code><span class='String'>' '</span></code>, or an array of valid fill elements. If the fill element is an array, then it may also have a fill element (since it is an ordinary BQN array). The fill element is meant to describe the shared structure of the elements of an array: for example, the fill element of an array of numbers should be <code><span class='Number'>0</span></code>, while the fill element for an array of variable-length lists should probably be <code><span class='Bracket'>⟨⟩</span></code>. However, the fill element, unlike other inferred properties, does not satisfy any particular constraints that relate it to its array. The fill element of a primitive's result, including functions derived from primitive modifiers, must depend only on its inputs.</p>
<p>In addition to the requirements below, the fill element for the value of a string literal is <code><span class='String'>' '</span></code>.</p>
-<h3 id="required-functions">Required functions</h3>
+<h3 id="required-functions"><a class="header" href="#required-functions">Required functions</a></h3>
<p>Combinators <code><span class='Function'>⊣⊢!</span><span class='Modifier'>˙˜´˝</span><span class='Modifier2'>∘○⊸⟜⊘◶⍟</span></code> do not affect fill element computation: if the combinator calls a function that computes a fill element, then that fill element must be retained if the result is passed to other functions or returned. <code><span class='Modifier2'>⍟</span></code> constructs arrays if its right operand is or contains arrays, and the fill elements of these arrays are not specified; converting <code><span class='Value'>𝕩</span></code> to a fill element is a reasonable choice in some cases but not others.</p>
<p>Arithmetic primitives—all valences of <code><span class='Function'>+-×÷⋆√⌊⌈|¬</span></code> and dyadic <code><span class='Function'>∧∨&lt;&gt;≠=≤≥</span></code>—obtain their fill elements by applying to the fill elements of the arguments. If this is an error, there is no fill element; otherwise, the fill element is the result, with all numbers in it changed to <code><span class='Number'>0</span></code> and all characters changed to <code><span class='String'>' '</span></code>.</p>
<p>Fill elements for many primitives are given in the table below. The &quot;Fill&quot; column indicates the strategy used to compute the result's fill. Fields <code><span class='Number'>0</span></code>, <code><span class='Value'>𝕩</span></code>, <code><span class='Number'>0</span><span class='Function'>↑</span><span class='Value'>𝕩</span></code>, and <code><span class='Number'>0</span><span class='Modifier2'>⚇</span><span class='Number'>0</span><span class='Value'>𝕩</span></code> indicate the fill directly, while <code><span class='Function'>⊢</span></code> and <code><span class='Value'>∩</span></code> indicate that the fill is to be computed from the argument fills (if not all arguments have fills, then the fill element is unspecified). For <code><span class='Function'>⊢</span></code>, the fill element of the result is the fill element of <code><span class='Value'>𝕩</span></code>. For <code><span class='Value'>∩</span></code>, the fill is equal to the fill values for multiple arrays, provided that they are all equal (it's unspecified if they are not all equal). In the two argument case, these arrays are <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code>. In the one-argument case, they are the elements of <code><span class='Value'>𝕩</span></code>; however, if <code><span class='Value'>𝕩</span></code> is empty, then the result's fill is the fill of the fill of <code><span class='Value'>𝕩</span></code>.</p>
@@ -120,11 +120,11 @@
</table>
<p>For Group and Group Indices (<code><span class='Function'>⊔</span></code>), the fill element of the result and its elements are both specified: the fill element of each element of the result is the same as that of <code><span class='Value'>𝕩</span></code> for Group, and is <code><span class='Number'>0</span></code> for Group Indices. The fill element of the result is <code><span class='Paren'>(</span><span class='Number'>0</span><span class='Modifier2'>⚇</span><span class='Number'>1</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>↑</span><span class='Value'>𝕩</span></code> for Group, and <code><span class='Function'>⥊</span><span class='Modifier2'>⟜</span><span class='Function'>&lt;</span><span class='Number'>0</span><span class='Modifier2'>⚇</span><span class='Number'>1</span><span class='Value'>𝕩</span></code> for Group Indices.</p>
<p>Fill elements of iteration modifiers such as <code><span class='Modifier'>¨⌜</span></code> are not specified. It is reasonable to define the fill element of <code><span class='Function'>𝔽</span><span class='Modifier'>⌜</span></code> or <code><span class='Function'>𝔽</span><span class='Modifier'>¨</span></code> to be <code><span class='Function'>𝔽</span></code> applied to the fill elements of the arguments. Regardless of definition, computing the fill element cannot cause side effects or an error.</p>
-<h2 id="undo">Undo</h2>
+<h2 id="undo"><a class="header" href="#undo">Undo</a></h2>
<p>The Undo 1-modifier <code><span class='Modifier'>⁼</span></code>, given an operand <code><span class='Function'>𝔽</span></code> and argument <code><span class='Value'>𝕩</span></code>, and possibly a left argument <code><span class='Value'>𝕨</span></code>, finds a value <code><span class='Value'>y</span></code> such that <code><span class='Value'>𝕩</span><span class='Function'>≡</span><span class='Value'>𝕨</span><span class='Function'>𝔽</span><span class='Value'>y</span></code>, that is, an element of the pre-image of <code><span class='Value'>𝕩</span></code> under <code><span class='Function'>𝔽</span></code> or <code><span class='Value'>𝕨</span><span class='Function'>𝔽⊢</span></code>. Thus it satisfies the constraint <code><span class='Value'>𝕩</span> <span class='Function'>≡</span> <span class='Value'>𝕨</span><span class='Function'>𝔽</span><span class='Value'>𝕨</span><span class='Function'>𝔽</span><span class='Modifier'>⁼</span><span class='Value'>𝕩</span></code> (<code><span class='Value'>𝕨</span><span class='Function'>𝔽</span><span class='Modifier'>⁼</span><span class='Function'>⊢</span></code> is a <em>right inverse</em> of <code><span class='Value'>𝕨</span><span class='Function'>𝔽⊢</span></code>) provided <code><span class='Function'>𝔽</span><span class='Modifier'>⁼</span></code> and <code><span class='Function'>𝔽</span></code> both complete without error. <code><span class='Function'>𝔽</span><span class='Modifier'>⁼</span></code> should of course give an error if no inverse element exists, and can also fail if no inverse can be found. It is also preferred for <code><span class='Function'>𝔽</span><span class='Modifier'>⁼</span></code> to give an error if there are many choices of inverse with no clear way to choose one of them: for example, <code><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Function'>⍉</span><span class='Value'>m</span></code> returns the diagonal of matrix <code><span class='Value'>m</span></code>; <code><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Function'>⍉</span><span class='Modifier'>⁼</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span></code> requires values to be chosen for the off-diagonal elements in its result. It is better to give an error, encouraging the programmer to use a fully-specified approach like <code><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Modifier2'>⊸</span><span class='Function'>⍉</span><span class='Paren'>)</span></code> applied to a matrix of initial elements, than to return a result that could be very different from other implementations.</p>
<p>When working with limited-precision numbers, it may be difficult or impossible to exactly invert the operand function. Instead, it is generally acceptable to perform a computation that, if done with unlimited precision, would exactly invert <code><span class='Function'>𝔽</span></code> computed with unlimited precision. This principle is the basis for the numeric inverses specified below. It is also acceptable to find an inverse by numeric methods, provided that the error in the inverse value found relative to an unlimited-precision inverse can be kept close to the inherent error in the implementation's number format.</p>
<p>Regardless of which cases for Undo are supported, the result of a call, and whether it is an error, must depend only on the values of the inputs <code><span class='Function'>𝔽</span></code>, <code><span class='Value'>𝕩</span></code>, and (if present) <code><span class='Value'>𝕨</span></code>.</p>
-<h3 id="required-functions">Required functions</h3>
+<h3 id="required-functions"><a class="header" href="#required-functions">Required functions</a></h3>
<p>Function inverses are given for one or two arguments, with cases where inverse support is not required left blank.</p>
<p>For arithmetic functions the implementations below may in some cases not give the closest inverse (that is, there may be some other <code><span class='Value'>y</span></code> so that <code><span class='Function'>F</span> <span class='Value'>y</span></code> is closer to <code><span class='Value'>x</span></code> than <code><span class='Function'>F</span> <span class='Function'>F</span><span class='Modifier'>⁼</span><span class='Value'>x</span></code>). Even in these cases the exact functions given below must be used.</p>
<table>
@@ -247,7 +247,7 @@
</tr>
</tbody>
</table>
-<h3 id="optional-functions">Optional functions</h3>
+<h3 id="optional-functions"><a class="header" href="#optional-functions">Optional functions</a></h3>
<p>Several primitives are easily and uniquely undone, but doing so is not important for BQN programming. These primitives are listed below along with suggested algorithms to undo them. Unlike the implementations above, these functions are not valid in all cases, and the inputs must be validated or the results checked in order to use them.</p>
<table>
<thead>
@@ -300,7 +300,7 @@
</tr>
</tbody>
</table>
-<h3 id="required-modifiers">Required modifiers</h3>
+<h3 id="required-modifiers"><a class="header" href="#required-modifiers">Required modifiers</a></h3>
<p>The following cases of Self/Swap must be supported.</p>
<table>
<thead>
@@ -464,9 +464,9 @@
</tr>
</tbody>
</table>
-<h3 id="undo-headers">Undo headers</h3>
+<h3 id="undo-headers"><a class="header" href="#undo-headers">Undo headers</a></h3>
<p>An <code><span class='Function'>UndoHead</span></code> header specifies how a block function acts when undone. Like ordinary headers, undo headers are searched for a match when a block function <code><span class='Function'>F</span></code> is undone, or when <code><span class='Function'>F</span><span class='Modifier'>˜</span></code> is undone with two arguments (including the two modifier cases <code><span class='Function'>𝔽</span><span class='Modifier2'>⟜</span><span class='Value'>k</span></code> and <code><span class='Function'>𝔽𝔾</span><span class='Value'>k</span></code> from the previous section). An <code><span class='Function'>UndoHead</span></code> without <code><span class='String'>&quot;˜&quot;</span></code> matches the <code><span class='Function'>F</span><span class='Modifier'>⁼</span></code> case while one with <code><span class='String'>&quot;˜&quot;</span></code> matches the <code><span class='Function'>F</span><span class='Modifier'>˜⁼</span></code> case. The left and right arguments are matched to <code><span class='Value'>headW</span></code> and <code><span class='Value'>headX</span></code> as with ordinary headers, and the first matching case is evaluated to give the result of the Undo-derived function.</p>
-<h2 id="under">Under</h2>
+<h2 id="under"><a class="header" href="#under">Under</a></h2>
<p>The Under 2-modifier <code><span class='Modifier2'>⌾</span></code> conceptually applies its left operand under the action of its right operand. Setting <code><span class='Value'>z</span><span class='Gets'>←</span><span class='Value'>𝕨</span><span class='Function'>𝔽</span><span class='Modifier2'>⌾</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span></code>, it satisfies <code><span class='Paren'>(</span><span class='Value'>𝕨</span><span class='Function'>𝔽</span><span class='Modifier2'>○</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span><span class='Paren'>)</span> <span class='Function'>≡</span> <span class='Function'>𝔾</span><span class='Value'>z</span></code>. We might say that <code><span class='Function'>𝔾</span></code> transforms values to a new domain, and <code><span class='Modifier2'>⌾</span><span class='Function'>𝔾</span></code> lifts actions <code><span class='Function'>𝔽</span></code> performed in this domain to the original domain of values. For example, addition in the logarithmic domain corresponds to multiplication in the linear domain: <code><span class='Function'>+</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Function'>⋆</span><span class='Modifier'>⁼</span><span class='Paren'>)</span></code> is <code><span class='Function'>×</span></code> (but less precise if computed in floating point).</p>
<p>Let <code><span class='Value'>v</span><span class='Gets'>←</span><span class='Value'>𝕨</span><span class='Function'>𝔽</span><span class='Modifier2'>○</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span></code>, so that <code><span class='Value'>v</span><span class='Function'>≡𝔾</span><span class='Value'>z</span></code>. <code><span class='Value'>v</span></code> is of course well-defined, so the inference step is to find <code><span class='Value'>z</span></code> based on <code><span class='Value'>v</span></code> and possibly the original inputs. We distinguish three cases for Under:</p>
<ul>
@@ -475,7 +475,7 @@
<li><em>Computational</em> Under: If <code><span class='Function'>𝔾</span></code> is provably not a structural function, then the result is <code><span class='Function'>𝔾</span><span class='Modifier'>⁼</span><span class='Value'>v</span></code> if it is defined.</li>
</ul>
<p>When implementing, there is no need to implement invertable Under specially: it can be handled as part of the structural and computation cases.</p>
-<h3 id="mathematical-definition-of-structural-under">Mathematical definition of structural Under</h3>
+<h3 id="mathematical-definition-of-structural-under"><a class="header" href="#mathematical-definition-of-structural-under">Mathematical definition of structural Under</a></h3>
<p>In general, structural Under requires information from the original right argument to be computed. Here we will define the <em>structural inverse of</em> structural function <code><span class='Function'>𝔾</span></code> <em>on</em> <code><span class='Value'>v</span></code> <em>into</em> <code><span class='Value'>𝕩</span></code>, where <code><span class='Value'>𝕩</span></code> gives this information. The value <code><span class='Value'>𝕨</span><span class='Function'>𝔽</span><span class='Modifier2'>⌾</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span></code> is then the structural inverse of <code><span class='Function'>𝔾</span></code> on <code><span class='Value'>𝕨</span><span class='Function'>𝔽</span><span class='Modifier2'>○</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span></code> into <code><span class='Value'>𝕩</span></code>.</p>
<p>We define a <em>structure</em> to be either the value <code><span class='Nothing'>·</span></code> or an array of structures (substitute <code><span class='Number'>0</span></code> or any other specific value for <code><span class='Nothing'>·</span></code> if you'd like structures to be a subset of BQN arrays; the value is irrelevant). A given structure <code><span class='Value'>s</span></code> <em>captures</em> a BQN value or structure <code><span class='Value'>𝕩</span></code> if it is <code><span class='Nothing'>·</span></code>, or if <code><span class='Value'>s</span></code> and <code><span class='Value'>𝕩</span></code> are arrays of the same shape, and each element of <code><span class='Value'>s</span></code> captures the corresponding element of <code><span class='Value'>𝕩</span></code>. Thus a structure shares some or all of the structural information in arrays it captures, but none of the data.</p>
<p>A <em>structure transformation</em> consists of an initial structure <code><span class='Value'>s</span></code> and a result structure <code><span class='Value'>t</span></code>, as well as a relation between the two: each instance of <code><span class='Nothing'>·</span></code> in <code><span class='Value'>t</span></code> is assigned the location of an instance of <code><span class='Nothing'>·</span></code> in <code><span class='Value'>s</span></code>. If <code><span class='Value'>s</span></code> captures a value <code><span class='Value'>𝕩</span></code>, we say that the structural transformation captures <code><span class='Value'>𝕩</span></code> as well. Given such a value <code><span class='Value'>𝕩</span></code>, the transformation is applied to <code><span class='Value'>𝕩</span></code> by replacing each <code><span class='Nothing'>·</span></code> in <code><span class='Value'>t</span></code> with the corresponding value from <code><span class='Value'>𝕩</span></code>, found by taking the same location in <code><span class='Value'>𝕩</span></code> as the one in <code><span class='Value'>s</span></code> given by the transformation.</p>
@@ -488,10 +488,10 @@
<p>Following this analysis, <code><span class='Value'>z</span></code> can be constructed by replacing each instance of <code><span class='Nothing'>·</span></code> in <code><span class='Value'>s</span></code> with the component of <code><span class='Value'>𝕩</span></code> or <code><span class='Value'>v</span></code> indicated, and it follows that <code><span class='Value'>z</span></code> is well-defined if it exists—and it exists if and only if <code><span class='Value'>t</span></code> captures <code><span class='Value'>v</span></code> and values in <code><span class='Value'>v</span></code> that correspond to the same position in <code><span class='Value'>s</span></code> have the same value.</p>
<p>A <em>structural function decomposition</em> is a possibly infinite family of structure transformations such that any possible BQN value is captured by at most one of these transformations. It can be applied to any value: if some transformation captures the value, then apply that transformation, and otherwise give an error. A function is a <em>structural function</em> if there is a structural function decomposition that matches it: that is, for any input either both functions give an error or the results match.</p>
<p>For a structural function <code><span class='Function'>𝔾</span></code>, the <em>structural inverse</em> of <code><span class='Function'>𝔾</span></code> on <code><span class='Value'>v</span></code> into <code><span class='Value'>𝕩</span></code> is the inverse of <code><span class='Function'>G</span></code> on <code><span class='Value'>v</span></code> into <code><span class='Value'>𝕩</span></code>, where <code><span class='Function'>G</span></code> is the structure transformation that captures <code><span class='Value'>𝕩</span></code> from some structural function decomposition <code><span class='Function'>Gd</span></code> matching <code><span class='Function'>𝔾</span></code>. If no decomposition has an initial structural matching <code><span class='Value'>𝕩</span></code> then the structural inverse does not exist.</p>
-<h4 id="well-definedness">Well-definedness</h4>
+<h4 id="well-definedness"><a class="header" href="#well-definedness">Well-definedness</a></h4>
<p>In order to show that the structural inverse of a structural function is well-defined, we must show that it does not depend on the choice of structural function decomposition. That is, for a given <code><span class='Value'>𝕩</span></code>, if <code><span class='Function'>G</span></code> and <code><span class='Function'>H</span></code> are structure transformations from different decompositions of <code><span class='Function'>𝔾</span></code> both capturing <code><span class='Value'>𝕩</span></code>, then the structural inverse of <code><span class='Function'>G</span></code> on <code><span class='Value'>v</span></code> into <code><span class='Value'>𝕩</span></code> matches that of <code><span class='Function'>H</span></code> on <code><span class='Value'>v</span></code> into <code><span class='Value'>𝕩</span></code>. Call these inverses <code><span class='Value'>y</span></code> and <code><span class='Value'>z</span></code>. Now begin by supposing that <code><span class='Function'>H</span></code> captures <code><span class='Value'>y</span></code> and <code><span class='Function'>G</span></code> captures <code><span class='Value'>z</span></code>; we will show this later. From the definition of a structural inverse, <code><span class='Value'>v</span><span class='Function'>≡G</span> <span class='Value'>y</span></code>, so that <code><span class='Value'>v</span><span class='Function'>≡𝔾</span> <span class='Value'>y</span></code>, and because <code><span class='Function'>H</span></code> captures <code><span class='Value'>y</span></code> we know that <code><span class='Function'>𝔾</span> <span class='Value'>y</span></code> is <code><span class='Function'>H</span> <span class='Value'>y</span></code>, so we have <code><span class='Value'>v</span><span class='Function'>≡H</span> <span class='Value'>y</span></code> as well. Let <code><span class='Function'>S</span> <span class='Value'>w</span></code> indicate the set of all structure transformations <code><span class='Function'>F</span></code> such that <code><span class='Value'>w</span> <span class='Function'>≡</span><span class='Modifier2'>○</span><span class='Function'>F</span> <span class='Value'>𝕩</span></code> (this is not a BQN value, both because it is a set and because it's usually infinite): from the definition of <code><span class='Value'>z</span></code> we know that <code><span class='Function'>S</span> <span class='Value'>z</span></code> is a strict superset of <code><span class='Function'>S</span> <span class='Value'>w</span></code> for any <code><span class='Value'>w</span></code> other than <code><span class='Value'>z</span></code> with <code><span class='Value'>v</span><span class='Function'>≡H</span> <span class='Value'>w</span></code>. It follows that either <code><span class='Value'>y</span><span class='Function'>≡</span><span class='Value'>z</span></code> or <code><span class='Function'>S</span> <span class='Value'>y</span></code> is a strict subset of <code><span class='Function'>S</span> <span class='Value'>z</span></code>. By symmetry the same relation holds exchanging <code><span class='Value'>y</span></code> and <code><span class='Value'>z</span></code>, but it's not possible for <code><span class='Function'>S</span> <span class='Value'>y</span></code> to be a strict subset of <code><span class='Function'>S</span> <span class='Value'>z</span></code> and vice-versa. The only remaining possibility is that <code><span class='Value'>y</span><span class='Function'>≡</span><span class='Value'>z</span></code>.</p>
<p>We now need to show that <code><span class='Function'>H</span></code> captures <code><span class='Value'>y</span></code> (the proof that <code><span class='Function'>G</span></code> captures <code><span class='Value'>z</span></code> is of course the same as <code><span class='Function'>H</span></code> and <code><span class='Function'>G</span></code> are symmetric). To do this we must show that any array in the initial structure of <code><span class='Function'>H</span></code> corresponds to a matching array in <code><span class='Value'>y</span></code>. For convenience, we will call the initial structures of the two transformations <code><span class='Value'>iG</span></code> and <code><span class='Value'>iH</span></code>, and the final structures <code><span class='Value'>fG</span></code> and <code><span class='Value'>fH</span></code>, and use the notation <code><span class='Value'>p</span><span class='Function'>⊑</span><span class='Value'>a</span></code> to indicate the value of array <code><span class='Value'>a</span></code> at position <code><span class='Value'>p</span></code>. Choose the position of an array in <code><span class='Function'>H</span></code>, and assume by induction that each array containing it already has the desired property; this implies that this position exists in <code><span class='Value'>y</span></code> as well although we know nothing about its contents. <code><span class='Function'>G</span></code> captures <code><span class='Value'>y</span></code>, so <code><span class='Value'>iG</span></code> is <code><span class='Nothing'>·</span></code> at this position or some parent position; call this position in <code><span class='Value'>iG</span></code> <code><span class='Value'>p</span></code>. There are now two cases: either <code><span class='Function'>G</span></code> makes use of this <code><span class='Value'>p</span></code>—at least one position in <code><span class='Value'>fG</span></code> corresponds to it—or it doesn't. If it doesn't, then the contents of <code><span class='Value'>y</span></code> at <code><span class='Value'>p</span></code> are the same as those of <code><span class='Value'>𝕩</span></code>. Since <code><span class='Function'>H</span></code> captures <code><span class='Value'>𝕩</span></code>, <code><span class='Value'>iH</span></code> matches <code><span class='Value'>𝕩</span></code> and hence <code><span class='Value'>y</span></code> as well at <code><span class='Value'>p</span></code>. If it does, then let <code><span class='Value'>s</span></code> be a position in <code><span class='Value'>fG</span></code> that corresponds to <code><span class='Value'>p</span></code> (if there are multiple possibilities, choose one). From <code><span class='Value'>v</span><span class='Function'>≡G</span> <span class='Value'>y</span></code>, we know that <code><span class='Value'>s</span><span class='Function'>⊑</span><span class='Value'>v</span></code> matches <code><span class='Value'>p</span><span class='Function'>⊑</span><span class='Value'>y</span></code>. We know that <code><span class='Value'>fH</span></code> captures <code><span class='Value'>v</span></code>, so that <code><span class='Value'>s</span><span class='Function'>⊑</span><span class='Value'>fH</span></code> captures <code><span class='Value'>s</span><span class='Function'>⊑</span><span class='Value'>v</span></code>, or <code><span class='Value'>p</span><span class='Function'>⊑</span><span class='Value'>y</span></code>. But we can show that the value of <code><span class='Value'>s</span><span class='Function'>⊑</span><span class='Value'>fH</span></code> is the same as <code><span class='Value'>p</span><span class='Function'>⊑</span><span class='Value'>iH</span></code>, which would prove that <code><span class='Function'>H</span></code> captures <code><span class='Value'>y</span></code> at <code><span class='Value'>p</span></code>. To show this, construct an array <code><span class='Value'>xp</span></code> by replacing the value of <code><span class='Value'>𝕩</span></code> at <code><span class='Value'>p</span></code> with <code><span class='Value'>p</span><span class='Function'>⊑</span><span class='Value'>iH</span></code> (to be more careful in our handling of types, we might replace every <code><span class='Nothing'>·</span></code> with some value that never appears in <code><span class='Value'>𝕩</span></code>). Both <code><span class='Function'>H</span></code> and <code><span class='Function'>G</span></code> capture <code><span class='Value'>xp</span></code>: clearly they capture it outside <code><span class='Value'>p</span></code>, while at <code><span class='Value'>p</span></code> itself, <code><span class='Value'>iG</span></code> is <code><span class='Nothing'>·</span></code> and <code><span class='Value'>iH</span></code> is equal to <code><span class='Value'>p</span><span class='Function'>⊑</span><span class='Value'>xp</span></code>. Now <code><span class='Paren'>(</span><span class='Function'>H</span> <span class='Value'>xp</span><span class='Paren'>)</span><span class='Function'>≡</span><span class='Paren'>(</span><span class='Function'>G</span> <span class='Value'>xp</span><span class='Paren'>)</span></code> because both functions match <code><span class='Function'>𝔾</span></code> on their domains. Therefore <code><span class='Value'>s</span><span class='Function'>⊑H</span> <span class='Value'>xp</span></code> matches <code><span class='Value'>s</span><span class='Function'>⊑G</span> <span class='Value'>xp</span></code>, which by the definition of <code><span class='Value'>s</span></code> matches <code><span class='Value'>p</span><span class='Function'>⊑</span><span class='Value'>xp</span></code>, which matches <code><span class='Value'>p</span><span class='Function'>⊑</span><span class='Value'>iH</span></code>. But <code><span class='Value'>s</span><span class='Function'>⊑H</span> <span class='Value'>xp</span></code> comes from replacing each atom in <code><span class='Value'>s</span><span class='Function'>⊑</span><span class='Value'>fH</span></code> with an atom in <code><span class='Value'>xp</span></code> that's captured by a <code><span class='Nothing'>·</span></code> in <code><span class='Value'>iH</span></code>. Because it matches <code><span class='Value'>p</span><span class='Function'>⊑</span><span class='Value'>iH</span></code>, every atom in <code><span class='Value'>s</span><span class='Function'>⊑H</span> <span class='Value'>xp</span></code> is <code><span class='Nothing'>·</span></code>, but the only instances of <code><span class='Nothing'>·</span></code> in <code><span class='Value'>xp</span></code> come from our inserted copy of <code><span class='Value'>p</span><span class='Function'>⊑</span><span class='Value'>iH</span></code> and each is immediately captured by the corresponding <code><span class='Nothing'>·</span></code> in <code><span class='Value'>iH</span></code>. It follows that <code><span class='Value'>s</span><span class='Function'>⊑H</span> <span class='Value'>xp</span></code>, and consequently <code><span class='Value'>s</span><span class='Function'>⊑</span><span class='Value'>fH</span></code>, is exactly <code><span class='Value'>p</span><span class='Function'>⊑</span><span class='Value'>iH</span></code>, completing the proof.</p>
-<h3 id="required-structural-inverses">Required structural inverses</h3>
+<h3 id="required-structural-inverses"><a class="header" href="#required-structural-inverses">Required structural inverses</a></h3>
<p>The following primitive functions be fully supported by structural Under. Each manipulates its right argument structurally.</p>
<table>
<thead>
@@ -570,7 +570,7 @@
</tr>
</tbody>
</table>
-<h3 id="a-structural-under-algorithm">A structural Under algorithm</h3>
+<h3 id="a-structural-under-algorithm"><a class="header" href="#a-structural-under-algorithm">A structural Under algorithm</a></h3>
<p>This section offers the outline for a procedure that computes most structural inverses that a programmer would typically use. The concept is to build a special result array whose elements are not BQN values but instead indicate positions within the initial argument. This structural array is applied to the initial argument by replacing its elements with the values at those positions, and inverted by placing elements back in the original array at these indices, checking for any conflicts. If operations like dyadic <code><span class='Function'>∾</span></code> are allowed, then a structural array might have some indices that are prefixes or parents of others, making it slightly different from a structural transformation as defined above (although it could be represented as a structural transformation by expanding some of these). This requires additional checking to ensure that elements of previously inserted elements can't be modified.</p>
<p>Structural functions can be applied to structural arrays directly, after ensuring that they have the necessary depth as given below. An array's depth can be increased by expanding each position in it into an array of child positions, or, if that position contains an atom and the structural function in question would tolerate an atom, enclosing it.</p>
<table>
@@ -610,7 +610,7 @@
</tbody>
</table>
<p>Not all primitives in the table above are required. Of note are <code><span class='Function'>=≠≢</span></code>, which accept a structural array but return an ordinary value; this might be used as a left argument later. If the final result is not structural, then the function in question can't be structural, and the attempt to find a structural inverse can be aborted.</p>
-<h3 id="non-structural-case">Non-structural case</h3>
+<h3 id="non-structural-case"><a class="header" href="#non-structural-case">Non-structural case</a></h3>
<p>The behavior of invertible and computational Under is fully dependent on that of <a href="#undo">Undo</a>, and does not need to be repeated here. However, it is important to discuss when this definition can be applied: specifically, either</p>
<ul>
<li>When <code><span class='Function'>𝔾</span></code> is exactly invertible, or</li>
diff --git a/docs/spec/literal.html b/docs/spec/literal.html
index 3b2b248a..35a280cc 100644
--- a/docs/spec/literal.html
+++ b/docs/spec/literal.html
@@ -4,7 +4,7 @@
<title>Specification: BQN literal notation</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">spec</a></div>
-<h1 id="specification-bqn-literal-notation">Specification: BQN literal notation</h1>
+<h1 id="specification-bqn-literal-notation"><a class="header" href="#specification-bqn-literal-notation">Specification: BQN literal notation</a></h1>
<p>A <em>literal</em> is a single <a href="token.html">token</a> that indicates a fixed character, number, or array. While literals indicate values of a data type, <a href="primitive.html">primitives</a> indicate values of an operation type: function, 1-modifier, or 2-modifier.</p>
<p>Two types of literal deal with text. As the source code is considered to be a sequence of unicode code points (&quot;characters&quot;), and these code points are also used for BQN's character <a href="types.html">data type</a>, the representation of a text literal is very similar to its value. In a text literal, the newline character is always represented using the ASCII line feed character, code point 10. A <em>character literal</em> is enclosed with single quotes <code><span class='String'>'</span></code> and its value is identical to the single character between them. A <em>string literal</em> is enclosed in double quotes <code><span class='String'>&quot;</span></code>, and any double quotes between them must come in pairs, as a lone double quote marks the end of the literal. The value of a string literal is a rank-1 array whose elements are the characters in between the enclosing quotes, after replacing each pair of double quotes with only one such quote. The <em>null literal</em> is the token <code><span class='String'>@</span></code> and represents the null character, code point 0.</p>
<p>The format of a <em>numeric literal</em> is more complicated. From the <a href="token.html">tokenization rules</a>, a numeric literal consists of a numeric character (one of <code><span class='Number'>¯∞π.0123456789</span></code>) followed by any number of numeric or alphabetic characters. Some numeric literals are <em>valid</em> and indicate a number, while others are invalid and cause an error. The grammar for valid numbers is given below in a <a href="https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form">BNF</a> variant. Only four alphabetic characters are allowed: &quot;i&quot;, which separates the real and imaginary components of a complex number, &quot;e&quot;, which functions as in scientific notation, and the uppercase versions of these letters. Not included in this grammar are underscores—they can be placed anywhere in a number, including after the last non-underscore character, and are ignored entirely.</p>
diff --git a/docs/spec/primitive.html b/docs/spec/primitive.html
index c3f4ab2f..128fd24f 100644
--- a/docs/spec/primitive.html
+++ b/docs/spec/primitive.html
@@ -4,11 +4,11 @@
<title>Specification: BQN primitives</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">spec</a></div>
-<h1 id="specification-bqn-primitives">Specification: BQN primitives</h1>
+<h1 id="specification-bqn-primitives"><a class="header" href="#specification-bqn-primitives">Specification: BQN primitives</a></h1>
<p>Most primitives are specified by the BQN-based implementation in <a href="https://github.com/mlochbaum/BQN/blob/master/spec/reference.bqn">reference.bqn</a>. This document specifies the basic functionality required by those definitions. Descriptions of other primitives are for informational purposes only.</p>
-<h2 id="pervasive-primitives">Pervasive primitives</h2>
+<h2 id="pervasive-primitives"><a class="header" href="#pervasive-primitives">Pervasive primitives</a></h2>
<p>Functions in this section are defined for atoms only; the reference implementations extend them to arrays.</p>
-<h3 id="arithmetic">Arithmetic</h3>
+<h3 id="arithmetic"><a class="header" href="#arithmetic">Arithmetic</a></h3>
<p>BQN uses five arithmetic functions that are standard in mathematics. The precision of these operations should be specified by the number <a href="types.html">type</a>.</p>
<ul>
<li><strong>Add</strong> <code><span class='Function'>+</span></code></li>
@@ -25,7 +25,7 @@
</ul>
<p>In the first two cases, if the result would not be a valid Unicode code point, then an error results. The remaining cases of <code><span class='Function'>+</span></code> and <code><span class='Function'>-</span></code> (adding two characters; negating a character or subtracting it from a number) are not allowed.</p>
<p>Additionally, the <strong>Floor</strong> function <code><span class='Function'>⌊</span></code> returns the largest integer smaller than or equal to the argument, or the argument itself if it is <code><span class='Number'>¯∞</span></code> or <code><span class='Number'>∞</span></code>. It's needed because the arithmetic operations give no fixed-time way to determine if a value is an integer. Floor gives an error if the argument is an atom other than a number.</p>
-<h3 id="comparison">Comparison</h3>
+<h3 id="comparison"><a class="header" href="#comparison">Comparison</a></h3>
<p>Two kinds of comparison are needed to define BQN's primitives: <em>equality</em> comparison and <em>ordered</em> comparison.</p>
<p>Ordered comparison is simpler and is provided by the dyadic Less than or Equal to (<code><span class='Function'>≤</span></code>) function. This function gives an error if either argument is an operation, so it needs to be defined only for numbers and characters. For numbers it is defined by the number system, and for characters it returns <code><span class='Number'>1</span></code> if the left argument's code point is less than that of the right argument. Characters are considered greater than numbers, so that <code><span class='Value'>n</span><span class='Function'>≤</span><span class='Value'>c</span></code> is <code><span class='Number'>1</span></code> and <code><span class='Value'>c</span><span class='Function'>≤</span><span class='Value'>n</span></code> is <code><span class='Number'>0</span></code> if <code><span class='Value'>c</span></code> is a character and <code><span class='Value'>n</span></code> is a number.</p>
<p>The dyadic function <code><span class='Function'>=</span></code>, representing equality comparison, can be applied to any two atoms without an error. Roughly speaking, it returns <code><span class='Number'>1</span></code> if they are indistinguishable within the language and <code><span class='Number'>0</span></code> otherwise. If the two arguments have different types, the result is <code><span class='Number'>0</span></code>; if they have the same type, the comparison depends on type:</p>
@@ -40,7 +40,7 @@
<li>Block instances are equal if they are the same instance.</li>
</ul>
<p>This means that block instance equality indicates identity in the context of mutability: two block instances are equal if any change of state in one would be reflected in the other as well. The concept of identity holds even if the blocks in question have no way of changing or accessing state. For example, <code><span class='Function'>=</span><span class='Modifier2'>○</span><span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Separator'>⋄</span><span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Brace'>}}</span><span class='Modifier'>˜</span><span class='String'>@</span></code> is <code><span class='Number'>0</span></code> while <code><span class='Function'>=</span><span class='Modifier'>˜</span><span class='Modifier2'>○</span><span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Separator'>⋄</span><span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Brace'>}}</span><span class='String'>@</span></code> is <code><span class='Number'>1</span></code>.</p>
-<h2 id="array-functionality">Array functionality</h2>
+<h2 id="array-functionality"><a class="header" href="#array-functionality">Array functionality</a></h2>
<p>Several subsets of primitives, or dedicated operations, are used to manipulate arrays in the reference implementation.</p>
<ul>
<li><code><span class='Function'>IsArray</span></code> returns <code><span class='Number'>1</span></code> if the argument is an array and <code><span class='Number'>0</span></code> if it's an atom.</li>
@@ -57,23 +57,23 @@
<li><strong>Pick</strong> (<code><span class='Function'>⊑</span></code>) selects the element at index <code><span class='Value'>𝕨</span></code> from list <code><span class='Value'>𝕩</span></code>.</li>
<li><code><span class='Modifier'>_amend</span></code> returns an array identical to list <code><span class='Value'>𝕩</span></code> except that the element at index <code><span class='Value'>𝕗</span></code> is changed to <code><span class='Value'>𝕨</span></code>.</li>
</ul>
-<h2 id="inferred-functionality">Inferred functionality</h2>
+<h2 id="inferred-functionality"><a class="header" href="#inferred-functionality">Inferred functionality</a></h2>
<p>Inferred properties are specified in <a href="inferred.html">their own document</a>, not in the reference implementation.</p>
<ul>
<li><code><span class='Function'>Identity</span></code> gives the identity value for reduction by function <code><span class='Function'>𝕏</span></code>.</li>
<li><strong>Undo</strong> (<code><span class='Modifier'>⁼</span></code>) gives a partial right inverse for function <code><span class='Function'>𝔽</span></code>.</li>
<li><code><span class='Function'>Fill</span></code> gives the enclose of the fill value for array <code><span class='Value'>𝕩</span></code>.</li>
</ul>
-<h2 id="other-provided-functionality">Other provided functionality</h2>
+<h2 id="other-provided-functionality"><a class="header" href="#other-provided-functionality">Other provided functionality</a></h2>
<ul>
<li><strong>Assert</strong> (<code><span class='Function'>!</span></code>) causes an error if the argument is not <code><span class='Number'>1</span></code>. If <code><span class='Value'>𝕨</span></code> is provided, it gives a message to be associated with this error (which can be any value, not necessarily a string).</li>
</ul>
<ul>
<li><strong>Catch</strong> (<code><span class='Modifier2'>⎊</span></code>) evaluates <code><span class='Function'>𝔽</span></code> on the arguments <code><span class='Value'>𝕨</span></code> (if present) and <code><span class='Value'>𝕩</span></code>. If <code><span class='Function'>𝔽</span></code> completes without error it returns the result, but if evaluation of <code><span class='Function'>𝔽</span></code> results in an error then the error is suppressed, and Catch evaluates <code><span class='Function'>𝔾</span></code> on the arguments and returns the result. Errors in <code><span class='Function'>𝔾</span></code> are not caught. Catch only prevents evaluation errors, and not syntax errors: these are considered errors in the program as a whole rather than any particular part of it.</li>
</ul>
-<h2 id="commentary-on-other-primitives">Commentary on other primitives</h2>
+<h2 id="commentary-on-other-primitives"><a class="header" href="#commentary-on-other-primitives">Commentary on other primitives</a></h2>
<p>As noted above, see <a href="https://github.com/mlochbaum/BQN/blob/master/spec/reference.bqn">reference.bqn</a> for the authoritative definitions. Commentary here gives an overall description and highlights implementation subtleties and edge cases.</p>
-<h3 id="combinators">Combinators</h3>
+<h3 id="combinators"><a class="header" href="#combinators">Combinators</a></h3>
<p>There's little to say about BQN's true combinators, since each is simply a pattern of function application. All primitive combinators use their operands as functions, and thus treat a data operand as a constant function.</p>
<ul>
<li><strong>Choose</strong> (<code><span class='Modifier2'>◶</span></code>) is later redefined to use the complete <code><span class='Function'>⊑</span></code> rather than the simple version assumed (using this primitive means it's not a true combinator).</li>
@@ -88,7 +88,7 @@
<li><strong>After</strong>/<strong>Bind</strong> (<code><span class='Modifier2'>⟜</span></code>)</li>
</ul>
<p>The somewhat complicated definition of Valences could be replaced with <code><span class='Brace'>{</span><span class='Function'>𝔽</span><span class='Value'>𝕩;𝕨</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> using headers. However, reference.bqn uses a simple subset of BQN's syntax that doesn't include headers. Instead, the definition relies on the fact that <code><span class='Value'>𝕨</span></code> works like <code><span class='Nothing'>·</span></code> if no left argument is given: <code><span class='Paren'>(</span><span class='Number'>1</span><span class='Modifier'>˙</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>-</span><span class='Number'>0</span></code> is <code><span class='Number'>1</span><span class='Function'>-</span><span class='Number'>0</span></code> or <code><span class='Number'>1</span></code> if <code><span class='Value'>𝕨</span></code> is present and <code><span class='Paren'>(</span><span class='Number'>1</span><span class='Modifier'>˙</span><span class='Nothing'>·</span><span class='Paren'>)</span><span class='Function'>-</span><span class='Number'>0</span></code> otherwise: this reduces to <code><span class='Nothing'>·</span><span class='Function'>-</span><span class='Number'>0</span></code> or <code><span class='Number'>0</span></code>.</p>
-<h3 id="array-properties">Array properties</h3>
+<h3 id="array-properties"><a class="header" href="#array-properties">Array properties</a></h3>
<p>The reference implementations extend Shape (<code><span class='Function'>≢</span></code>) to atoms as well as arrays, in addition to implementing other properties. In all cases, an atom behaves as if it has shape <code><span class='Bracket'>⟨⟩</span></code>. The functions in this section never cause an error.</p>
<ul>
<li><strong>Shape</strong> (<code><span class='Function'>≢</span></code>) gives the shape of an array or atom.</li>
@@ -96,7 +96,7 @@
<li><strong>Length</strong> (<code><span class='Function'>≠</span></code>) gives the number of major cells, or <code><span class='Number'>1</span></code> for an argument of rank <code><span class='Number'>0</span></code>.</li>
<li><strong>Depth</strong> (<code><span class='Function'>≡</span></code>) gives the nesting depth. It ignores the shapes of arrays, and considering only the depths of their elements.</li>
</ul>
-<h3 id="arithmetic">Arithmetic</h3>
+<h3 id="arithmetic"><a class="header" href="#arithmetic">Arithmetic</a></h3>
<p>Arithmetic functions not already provided are defined in layer 1. These definitions, like the provided functions, apply to atoms only; they should be extended to arrays using the <code><span class='Modifier'>_perv</span></code> modifier from layer 2.</p>
<ul>
<li><strong>Sign</strong> (<code><span class='Function'>×</span></code>) </li>
@@ -109,7 +109,7 @@
<li><strong>Modulus</strong> (<code><span class='Function'>|</span></code>) is an extension of modular division to real numbers. As it uses floor instead of truncation, it's not the same as the <code><span class='Value'>%</span></code> operator from C or other languages when <code><span class='Value'>𝕨</span><span class='Function'>&lt;</span><span class='Number'>0</span></code>.</li>
<li>Comparisons <strong>Less Than</strong> (<code><span class='Function'>&lt;</span></code>), <strong>Greater Than</strong> (<code><span class='Function'>&gt;</span></code>), <strong>Greater Than or Equal to</strong> (<code><span class='Function'>≥</span></code>), and <strong>Not Equals</strong> (<code><span class='Function'>≠</span></code>) are defined in terms of the two provided comparisons.</li>
</ul>
-<h3 id="iteration-modifiers">Iteration modifiers</h3>
+<h3 id="iteration-modifiers"><a class="header" href="#iteration-modifiers">Iteration modifiers</a></h3>
<p>Modifiers for iteration are defined in layers 1, 2, and 4. Two 2-modifiers, <code><span class='Modifier2'>⚇</span></code> and <code><span class='Modifier2'>⎉</span></code>, use a list of numbers obtained by applying the right operand to the arguments in order to control application. This list has one to three elements: if all three are given then they correspond to the monadic, left, and right arguments; if one is given then it controls all three; and if two are given then they control the left argument, and the right and monadic arguments.</p>
<p>The iteration modifiers <code><span class='Modifier'>⌜¨</span><span class='Modifier2'>⚇</span><span class='Modifier'>˘</span><span class='Modifier2'>⎉</span></code> process elements or cells in index order, that is, according to lexicographic ordering of indices or according to simple numeric ordering of the indices in the Deshaped (<code><span class='Function'>⥊</span></code>) arguments. When both arguments are mapped over independently, the left argument is mapped over &quot;first&quot;, or as an outer loop: one part of the left argument is paired with each part of the right in turn, then the next part of the left argument, and so on.</p>
<p><strong>Table</strong> (<code><span class='Modifier'>⌜</span></code>) and <strong>Each</strong> (<code><span class='Modifier'>¨</span></code>) map over the elements of arrays to produce result elements. They convert atom arguments to unit arrays. With one argument, the two modifiers are the same; with two, they differ in how they pair elements. Table pairs every element of the left argument with every element of the right, giving a result shape <code><span class='Value'>𝕨</span><span class='Function'>∾</span><span class='Modifier2'>○</span><span class='Function'>≢</span><span class='Value'>𝕩</span></code>. Each uses leading axis agreement: it requires one argument's shape to be a prefix of the other's (if the arguments have the same rank, then the shapes must match and therefore be mutual prefixes). This causes each element of the lower-rank argument to correspond to a cell of the higher-rank one; it's repeated to pair it with each element of that cell. The result shape is the shape of the higher-rank argument.</p>
@@ -118,13 +118,13 @@
<p><strong>Fold</strong> (<code><span class='Modifier'>´</span></code>), <strong>Insert</strong> (<code><span class='Modifier'>˝</span></code>), and <strong>Scan</strong> (<code><span class='Modifier'>`</span></code>) repeatedly apply a function between parts of an array. Fold requires the argument to have rank 1 and applies the operand between its elements, while Insert requires it to have rank 1 or more and applies it between the cells. For each of these two functions, the operand is applied beginning at the end of the array, and an <a href="inferred.html#identities">identity</a> value is returned if the array is empty. While these functions reduce multiple values to a single result, Scan returns many results and preserves the shape of its argument. It requires the argument to have rank at least 1, and applies the function between elements along columns—that is, from one element in a major cell to the one in the same position of the next major cell. This application begins at the first major cell of the array. Scan never uses the identity element of its operand because if the argument is empty then the result, which has the same shape, will be empty as well.</p>
<p>A left argument for any of the three reduction-based modifiers indicates an initial value to be used, so that the first application of the operand function applies not to two values from <code><span class='Value'>𝕩</span></code> but instead to a value from <code><span class='Value'>𝕨</span></code> and a value from <code><span class='Value'>𝕩</span></code>. In Fold and Insert, the entire value <code><span class='Value'>𝕨</span></code> is the initial value, while in Scan, <code><span class='Value'>𝕨</span></code> is an array of initial values, which must have shape <code><span class='Number'>1</span><span class='Function'>↓≢</span><span class='Value'>𝕩</span></code>.</p>
<p><strong>Repeat</strong> (<code><span class='Modifier2'>⍟</span></code>) applies the operand function, or its <a href="inferred.html#undo">inverse</a>, several times in sequence. The right operand must consist only of integer atoms (arranged in arrays of any depth), and each number there is replaced with the application of the left operand that many times to the arguments. If a left argument is present, then it's reused each time, as if it were bound to the operand function. For a negative number <code><span class='Function'>-</span><span class='Value'>n</span></code>, the function is &quot;applied&quot; <code><span class='Function'>-</span><span class='Value'>n</span></code> times by undoing it <code><span class='Value'>n</span></code> times. In both directions, the total number of times the function is applied is the maximum of all numbers present: results must be saved if intermediate values are needed.</p>
-<h3 id="restructuring">Restructuring</h3>
+<h3 id="restructuring"><a class="header" href="#restructuring">Restructuring</a></h3>
<p><strong>Enclose</strong> (<code><span class='Function'>&lt;</span></code>) forms a unit array that contains its argument.</p>
<p><strong>Merge</strong> (<code><span class='Function'>&gt;</span></code>) combines the outer axes of an array of arrays with inner axes: it requires that all elements of its argument have the same shape, and creates an array such that <code><span class='Paren'>(</span><span class='Value'>i</span><span class='Function'>∾</span><span class='Value'>j</span><span class='Paren'>)</span><span class='Function'>⊑&gt;</span><span class='Value'>𝕩</span></code> is <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>j</span><span class='Function'>⊑</span><span class='Value'>𝕩</span></code>. It also accepts atom elements of <code><span class='Value'>𝕩</span></code>, converting them to unit arrays, or an atom argument, which is returned unchanged. <strong>Solo</strong> and <strong>Couple</strong> (<code><span class='Function'>≍</span></code>) turn one or two arguments into major cells of the result and can be defined easily in terms of Merge.</p>
<p><strong>Join To</strong> (<code><span class='Function'>∾</span></code>) combines its two arguments along an existing initial axis, unless both arguments are units, in which case it creates an axis and is identical to Couple (<code><span class='Function'>≍</span></code>). The arguments must differ in rank by at most 1, and the result rank is equal to the maximum of 1 and the higher argument rank. Each argument with rank less than the result, and each major cell of an argument with rank equal to it, becomes a major cell of the result, with cells from the left argument placed before those from the right. <strong>Join</strong> (<code><span class='Function'>∾</span></code>) generalizes the equal-rank subset of this behavior to an array of values instead of just two. The argument must be an array (unlike Merge), and its elements must all the same rank, which is at least the argument rank. Atom elements are treated as unit arrays. Then &quot;outer&quot; argument axes are matched up with leading &quot;inner&quot; element axes, and elements are joined along these axes. In order to allow this, the length of an element along a particular axis must depend only on the position along the corresponding axis in the argument. An empty argument to Join is return unchanged, as though the element rank is equal to the argument rank.</p>
<p><strong>Deshape</strong> (<code><span class='Function'>⥊</span></code>) differs from the provided function (which returns the element list of an array) only in that it accepts an atom, returning a one-element list containing it. <strong>Reshape</strong> (<code><span class='Function'>⥊</span></code>) is extended in numerous ways. It accepts any list of natural numbers (including as a unit array or atom) for the left argument and any right argument; <code><span class='Value'>𝕩</span></code> is deshaped first so that it is treated as a list of elements. These elements are repeated cyclically to fill the result array in ravel order. If <code><span class='Value'>𝕩</span></code> is empty then a non-empty requested result shape causes an error. Furthermore, at most one element of <code><span class='Value'>𝕨</span></code> can be a &quot;length code&quot;: one of the primitives <code><span class='Modifier2'>∘</span><span class='Function'>⌊⌽↑</span></code>. In this case, a target length is computed from the number of elements in <code><span class='Value'>𝕩</span></code> divided by the product of the other elements of <code><span class='Value'>𝕨</span></code> (which must not be zero). If the target length is an integer then it is used directly for the length code. Otherwise, an error is given if the length code is <code><span class='Modifier2'>∘</span></code>, and the target length is rounded down if the code is <code><span class='Function'>⌊</span></code> and up if it's <code><span class='Function'>⌽</span></code> or <code><span class='Function'>↑</span></code>. With code <code><span class='Function'>⌽</span></code>, elements are repeated cyclically as usual, but with code <code><span class='Function'>↑</span></code>, the extra elements after each argument element is used are fill values for <code><span class='Value'>𝕩</span></code>.</p>
<p><strong>Transpose</strong> (<code><span class='Function'>⍉</span></code>) reorders axes of its argument to place the first axis last; if the argument has one or fewer axes then it's enclosed if it's an atom and otherwise returned unchanged. <strong>Reorder Axes</strong> (<code><span class='Function'>⍉</span></code>) requires the left argument to be a list or unit of natural numbers, with length at most the rank of the right argument. This list is extended to match the right argument rank exactly by repeatedly appending the least unused natural number (for example, given <code><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span></code>, <code><span class='Number'>2</span></code> is appended). After extension, it specifies a result axis for each axis of the right argument. There must be no gaps in the list: that is, with the result rank equal to one plus the greatest value present, every result axis must appear at least once. Now each argument axis is &quot;sent to&quot; the specified result axis: in terms of indices, <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'>𝕨</span><span class='Function'>⊏</span><span class='Value'>i</span><span class='Paren'>)</span><span class='Function'>⊑</span><span class='Value'>𝕩</span></code> if <code><span class='Value'>𝕨</span></code> is complete. If multiple argument axes correspond to the same result axis, then a diagonal is taken, and it's as long as the shortest of those argument axes. Like Transpose, Reorder Axes encloses <code><span class='Value'>𝕩</span></code> if it's an atom, so that its result is always an array.</p>
-<h3 id="indices-and-selection">Indices and selection</h3>
+<h3 id="indices-and-selection"><a class="header" href="#indices-and-selection">Indices and selection</a></h3>
<p>Each element in an array <code><span class='Value'>s</span><span class='Function'>⥊</span><span class='Value'>e</span></code> is associated with an <em>index</em>, which is a list of natural numbers <code><span class='Value'>i</span></code> such that <code><span class='Function'>∧</span><span class='Modifier'>´</span><span class='Value'>i</span><span class='Function'>&lt;</span><span class='Value'>s</span></code>. The list of all indices, which corresponds to the element list <code><span class='Value'>e</span></code>, contains all such lists <code><span class='Value'>i</span></code> in lexicographic order. That is, index <code><span class='Value'>i</span></code> comes before <code><span class='Value'>j</span></code> exactly when the two indices are not the same, and <code><span class='Value'>i</span></code> has the smaller value at the first position where they are unequal. The index of an element along a particular axis <code><span class='Value'>a</span></code> is the value <code><span class='Value'>a</span><span class='Function'>⊑</span><span class='Value'>i</span></code>.</p>
<p><strong>Range</strong> (<code><span class='Function'>↕</span></code>) is extended to apply to a list of natural numbers, in addition to the provided case of a single natural number (an enclosed natural number <code><span class='Value'>𝕩</span></code> should still result in an error). For a list <code><span class='Value'>𝕩</span></code>, the result is an array of shape <code><span class='Value'>𝕩</span></code> in which the value at a given index is that index, as a list of natural numbers. That is, <code><span class='Value'>i</span><span class='Function'>≡</span><span class='Value'>i</span><span class='Function'>⊑↕</span><span class='Value'>𝕩</span></code> for any list of natural numbers <code><span class='Value'>i</span></code> with <code><span class='Function'>∧</span><span class='Modifier'>´</span><span class='Value'>i</span><span class='Function'>&lt;</span><span class='Value'>𝕩</span></code>.</p>
<p><strong>Pick</strong> (<code><span class='Function'>⊑</span></code>) is extended to array left arguments. In this case, it requires every depth-1 array in the nested structure of <code><span class='Value'>𝕨</span></code> to be a valid index list for <code><span class='Value'>𝕩</span></code>, and every atom to be contained in one of these lists. The result is <code><span class='Value'>𝕨</span></code> with each index list replaced by the element of <code><span class='Value'>𝕩</span></code> at that index. In the simple case where <code><span class='Value'>𝕨</span></code> itself is an index list, the result is the element of <code><span class='Value'>𝕩</span></code> at index <code><span class='Value'>𝕨</span></code>.</p>
@@ -133,14 +133,14 @@
<p><strong>First Cell</strong> (<code><span class='Function'>⊏</span></code>) selects the initial major cell of <code><span class='Value'>𝕩</span></code>, giving an error if <code><span class='Value'>𝕩</span></code> has rank 0 or length 0.</p>
<p><strong>Group</strong> (<code><span class='Function'>⊔</span></code>) performs an opposite operation to Select, so that <code><span class='Value'>𝕨</span></code> specifies not the argument index that result values come from, but the result index that argument values go to. The general case is that <code><span class='Value'>𝕨</span></code> is a list of arrays of numbers; if it has depth less than 2 it's converted to this form by first enclosing it if it's an atom, then placing it in a length-1 list. After this transformation, the result rank is <code><span class='Function'>≠</span><span class='Value'>𝕨</span></code>, and each result element has rank <code><span class='Paren'>(</span><span class='Function'>≠</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>+</span><span class='Paren'>(</span><span class='Function'>=</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Function'>-+</span><span class='Modifier'>´</span><span class='Function'>=</span><span class='Modifier'>¨</span><span class='Value'>𝕨</span></code>, with the initial <code><span class='Function'>≠</span><span class='Value'>𝕨</span></code> axes corresponding to elements of <code><span class='Value'>𝕨</span></code> and the remainder to trailing axes of <code><span class='Value'>𝕩</span></code>. Each atom in <code><span class='Value'>𝕨</span></code> can be either a natural number or <code><span class='Number'>¯1</span></code> (which indicates the corresponding position in <code><span class='Value'>𝕩</span></code> will be omitted). If <code><span class='Number'>¯1</span></code> doesn't appear, the result has the property that each cell of <code><span class='Value'>𝕩</span></code> appears in the corresponding element of <code><span class='Value'>𝕨</span><span class='Function'>⊏</span><span class='Value'>𝕨</span><span class='Function'>⊔</span><span class='Value'>𝕩</span></code>. More concretely, the length of the result along axis <code><span class='Value'>a</span></code> is the maximum value in <code><span class='Value'>a</span><span class='Function'>⊑</span><span class='Value'>𝕨</span></code> plus one, or zero if <code><span class='Value'>a</span><span class='Function'>⊑</span><span class='Value'>𝕨</span></code> is empty. Axis <code><span class='Value'>a</span></code> corresponds to <code><span class='Function'>=</span><span class='Value'>a</span><span class='Function'>⊑</span><span class='Value'>𝕨</span></code> axes in <code><span class='Value'>𝕩</span></code>, and an element of the result at position <code><span class='Value'>i</span></code> along this axis contains all positions in <code><span class='Value'>𝕩</span></code> where <code><span class='Value'>i</span><span class='Function'>=</span><span class='Value'>a</span><span class='Function'>⊑</span><span class='Value'>𝕨</span></code>. There may be multiple such positions, and they're arranged along axis <code><span class='Value'>a</span></code> of that result element according to their index order in <code><span class='Value'>𝕩</span></code>. The shapes of components of <code><span class='Value'>𝕨</span></code> must match the corresponding axes of <code><span class='Value'>𝕩</span></code>, except for rank-1 components of <code><span class='Value'>𝕨</span></code>, which can match or have an extra element. This element, which like the others is either a natural number or <code><span class='Number'>¯1</span></code>, gives the minimum length of the result axis corresponding to the component of <code><span class='Value'>𝕨</span></code> in question, but otherwise does not affect the result. <strong>Group Indices</strong> treats its argument <code><span class='Value'>𝕩</span></code> as a left argument for Group and uses a right argument made up of indices, which is <code><span class='Function'>↕≠</span><span class='Value'>𝕩</span></code> if <code><span class='Value'>𝕩</span></code> has depth 1 and <code><span class='Function'>↕∾≢</span><span class='Modifier'>¨</span><span class='Value'>𝕩</span></code> if it has depth 2. Because the depth-1 case uses atomic indices, <code><span class='Value'>𝕩</span></code> is required to be a list (and it can't be an atom). Much like Range, the result has depth one higher than the argument.</p>
<p><strong>Indices</strong> (<code><span class='Function'>/</span></code>) applies to a list of natural numbers, and returns a list of natural numbers. The result contains <code><span class='Value'>i</span><span class='Function'>⊑</span><span class='Value'>𝕩</span></code> copies of each natural number index <code><span class='Value'>i</span></code> for <code><span class='Value'>𝕩</span></code>, in increasing order.</p>
-<h3 id="structural-manipulation">Structural manipulation</h3>
+<h3 id="structural-manipulation"><a class="header" href="#structural-manipulation">Structural manipulation</a></h3>
<p>Monadic structural functions work on the first axis of the argument, so they require it to have rank at least 1. <strong>Reverse</strong> (<code><span class='Function'>⌽</span></code>) reverses the ordering of the major cells of <code><span class='Value'>𝕩</span></code>. <strong>Nudge</strong> (<code><span class='Function'>»</span></code>) shifts them forward, removing the last and placing a major cell made up of fill elements at the beginning, while <strong>Nudge Back</strong> (<code><span class='Function'>«</span></code>) does the same in the reverse direction, so it removes the first cell and places fills at the end. <strong>Prefixes</strong> (<code><span class='Function'>↑</span></code>) and <strong>Suffixes</strong> (<code><span class='Function'>↓</span></code>) each return lists with length one higher than <code><span class='Value'>𝕩</span></code>, whose elements are arrays with the same rank as <code><span class='Value'>𝕩</span></code>. For Prefixes, the element of the result at index <code><span class='Value'>i</span></code> contains the first <code><span class='Value'>i</span></code> major cells of <code><span class='Value'>𝕩</span></code> in order, and for Suffixes, it contains all but these major cells.</p>
<p>The remainder of the functions discussed in this section are dyadic. For all of these, an atom value for <code><span class='Value'>𝕩</span></code> is treated as an array by enclosing it before acting, so that the result is never an atom. There are four functions for which <code><span class='Value'>𝕨</span></code> is a list of whole numbers—but an atomic number or enclosed number is also permitted, and treated as a 1-element list—and its elements are matched with leading axes of <code><span class='Value'>𝕩</span></code>. These functions independently manipulate each axis: one way to define such a process is to consider lists running along the axis, where every element of the index is fixed except one. A change to this axis retains the fixed indices, but can move elements from one location to another along the variable index, add fill elements, or split the axis into two axes. A change to a different axis can rearrange these lists along the original axis, but can't affect the placement of elements within them. In the reference implementations, working on leading axes is accomplished using the Cells (<code><span class='Modifier'>˘</span></code>) modifier recursively, so that action on the first axes doesn't use Cells, on the next is affected by Cells once, then twice, and so on.</p>
<p><strong>Rotate</strong> (<code><span class='Function'>⌽</span></code>) is the simplest of these four functions: each element of <code><span class='Value'>𝕨</span></code> gives an amount to rotate the corresponding axis, where a rotation of <code><span class='Value'>r</span></code> moves the element at index <code><span class='Value'>i</span><span class='Function'>+</span><span class='Value'>r</span></code> to <code><span class='Value'>i</span></code> when all indices are taken modulo the length of the axis. <strong>Windows</strong> (<code><span class='Function'>↕</span></code>) splits each axis of <code><span class='Value'>𝕩</span></code> that corresponds to an element of <code><span class='Value'>𝕨</span></code> in two, so that the result has one set of axes corresponding to elements of <code><span class='Value'>𝕨</span></code>, then another, then the unchanged trailing axes. The second set of axes has lengths given by <code><span class='Value'>𝕨</span></code> (which must consist of natural numbers), while the first has lengths <code><span class='Value'>s</span><span class='Function'>¬</span><span class='Value'>𝕨</span></code>, where <code><span class='Value'>s</span></code> contains the lengths of leading axes of <code><span class='Value'>𝕩</span></code>. Position <code><span class='Value'>i</span></code> in the first set of axes and <code><span class='Value'>j</span></code> in the second corresponds to <code><span class='Value'>i</span><span class='Function'>+</span><span class='Value'>j</span></code> in the argument, so that fixing one of these positions and varying the other gives a slice of the argument. In both Rotate and Windows, the length of <code><span class='Value'>𝕨</span></code> is at most the rank of <code><span class='Value'>𝕩</span></code>.</p>
<p><strong>Take</strong> (<code><span class='Function'>↑</span></code>) offers several possibilities. The absolute value of <code><span class='Value'>𝕨</span></code> gives the final lengths of the axes in the result. It may be positive to indicate that the axis aligns with <code><span class='Value'>𝕩</span></code> at the beginning, or negative to indicate it aligns at the end. A zero value gives no result elements, so there is no need to consider alignment. If the absolute value of an element of <code><span class='Value'>𝕨</span></code> is smaller than or equal to the corresponding length in <code><span class='Value'>𝕩</span></code>, then the first or last few elements are taken along that axis. If it is larger, then instead fill elements are added to the end (if positive) or beginning (if negative) to make up the difference in length. <strong>Drop</strong> (<code><span class='Function'>↓</span></code>) gives <code><span class='Value'>𝕨</span></code> a similar meaning, but excludes all elements that Take includes (maintaining the order of the retained ones). The result of Drop never uses fill elements. In a case where Take would use fill elements, it would include all positions from <code><span class='Value'>𝕩</span></code>, so Drop should include none of them, and the result will have length <code><span class='Number'>0</span></code> for that axis. Take and Drop are extended to allow an argument with length greater than the rank of <code><span class='Value'>𝕩</span></code>. In this case leading length-1 axes are added to <code><span class='Value'>𝕩</span></code> so that its rank matches <code><span class='Value'>𝕨</span></code> before taking or dropping.</p>
<p><strong>Replicate</strong> (<code><span class='Function'>/</span></code>) is similar to the four dyadic structural functions above, but <code><span class='Value'>𝕨</span></code> gives a list of containing <em>lists</em> of natural numbers, or plain or enclosed natural numbers, instead of a simple list. If <code><span class='Value'>𝕨</span></code> has depth less than <code><span class='Number'>2</span></code>, it's considered to be a single value corresponding to one axis of <code><span class='Value'>𝕩</span></code>, while if it has depth <code><span class='Number'>2</span></code> then it's a list of values. If <code><span class='Value'>𝕨</span></code> is the empty list <code><span class='Bracket'>⟨⟩</span></code> then it is defined to be in the second case despite having a depth of <code><span class='Number'>1</span></code>. On a single axis of <code><span class='Value'>𝕩</span></code> the corresponding value <code><span class='Value'>r</span></code> from <code><span class='Value'>𝕨</span></code> is either a list or a unit: if it's a unit then it is repeated to match the length of that axis of <code><span class='Value'>𝕩</span></code>, and if it's a list it must already have the same length as that axis. Each number in <code><span class='Value'>r</span></code> now specifies the number of times to repeat the corresponding position in <code><span class='Value'>𝕩</span></code>. This is equivalent to calling Indices on <code><span class='Value'>r</span></code> and using the result for selection.</p>
<p><strong>Shift Before</strong> (<code><span class='Function'>»</span></code>) and <strong>Shift After</strong> (<code><span class='Function'>«</span></code>) are derived from Join To and share most of its behavior. The difference is that only a portion of the result of Join To is returned, matching the length of <code><span class='Value'>𝕩</span></code>. This portion comes from the beginning for Shift Before and the end for Shift After. The only difference in conditions between the shift functions and Join To is that Join To allows the result to have higher rank than <code><span class='Value'>𝕩</span></code>. Shifts do not, so the rank of <code><span class='Value'>𝕩</span></code> be at least 1 and at least as high as <code><span class='Value'>𝕨</span></code>.</p>
-<h3 id="searching">Searching</h3>
+<h3 id="searching"><a class="header" href="#searching">Searching</a></h3>
<p><strong>Match</strong> (<code><span class='Function'>≡</span></code>) indicates whether two values are considered equivalent. It always returns 0 or 1, and never causes an error. If both arguments are atoms then it is identical to <code><span class='Function'>=</span></code>, and if one is an atom and the other an array then it returns 0. If both arguments are arrays then it returns 1 only if they have the same shape and all pairs of corresponding elements match. Fill elements aren't taken into account, so that arrays that match might still differ in behavior. <strong>Not Match</strong> simply returns the complement of Match, <code><span class='Function'>¬≡</span></code>.</p>
<p>Monadic search functions compare the major cells of <code><span class='Value'>𝕩</span></code> to each other. <code><span class='Value'>𝕩</span></code> must have rank at least 1. Except for Deduplicate (<code><span class='Function'>⍷</span></code>), the result is a list of numbers with the same length as <code><span class='Value'>𝕩</span></code>.</p>
<ul>
@@ -156,7 +156,7 @@
<li><strong>Progressive Index of</strong> (<code><span class='Function'>⊒</span></code>) processes non-principal cells in ravel order, and gives the smallest index of a principal argument cell that matches the cell that hasn't already been included in the result. Again <code><span class='Function'>≠</span><span class='Value'>𝕨</span></code> is returned for a given cell if there is no valid cell.</li>
</ul>
<p><strong>Find</strong> (<code><span class='Function'>⍷</span></code>) indicates positions where <code><span class='Value'>𝕨</span></code> appears as a contiguous subarray of a <code><span class='Function'>=</span><span class='Value'>𝕨</span></code>-cell of <code><span class='Value'>𝕩</span></code>. It has one result element for each such subarray of <code><span class='Value'>𝕩</span></code>, whose value is 1 if that subarray matches <code><span class='Value'>𝕩</span></code> and 0 otherwise. Find cannot result in an error unless the rank of <code><span class='Value'>𝕨</span></code> is higher than that of <code><span class='Value'>𝕩</span></code>. If <code><span class='Value'>𝕨</span></code> is longer along one axis than the corresponding trailing axis of <code><span class='Value'>𝕩</span></code>, then the result has length 0 along that axis. Any atom argument to Find is automatically enclosed.</p>
-<h3 id="sorting">Sorting</h3>
+<h3 id="sorting"><a class="header" href="#sorting">Sorting</a></h3>
<p>Sorting functions are those that depend on BQN's array ordering. There are three kinds of sorting function, with two functions of each kind: one with an upward-pointing glyph that uses an ascending ordering (these function names are suffixed with &quot;Up&quot;), and one with a downward-pointing glyph and the reverse, descending, ordering (&quot;Down&quot;). Below, these three kinds of function are described, then the ordering rules. Except for the right argument of Bins, all arguments must have rank at least 1.</p>
<p><strong>Sort</strong> (<code><span class='Function'>∧∨</span></code>) reorders the major cells of its argument so that a major cell with a lower index comes earlier in the ordering than a major cell with a higher index, or matches it. If it's possible for matching arrays to differ in behavior because of different (including undefined versus defined) fill elements, then these arrays must maintain their ordering (a stable sort is required).</p>
<p><strong>Grade</strong> (<code><span class='Function'>⍋⍒</span></code>) returns a permutation describing the way the argument array would be sorted. For this reason the reference implementations simply define Sort to be selection by the grade. One way to define Grade is as a sorted version of the index list <code><span class='Function'>↕≠</span><span class='Value'>𝕩</span></code>. An index <code><span class='Value'>i</span></code> is ordered according to the corresponding major cell <code><span class='Value'>i</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code>. However, ties in the ordering are broken by ordering the index values themselves, so that no two indices are ever considered equal, and the result of sorting is well-defined (for Sort this is not an issue—matching cells are truly interchangeable). This property means that a stable sorting algorithm must be used to implement Grade functions. While cells might be ordered ascending or descending, indices are always ordered ascending, so that for example index <code><span class='Value'>i</span></code> is placed before index <code><span class='Value'>j</span></code> if either <code><span class='Value'>i</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> comes earlier in the ordering than <code><span class='Value'>j</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code>, or if they match and <code><span class='Value'>i</span><span class='Function'>&lt;</span><span class='Value'>j</span></code>.</p>
diff --git a/docs/spec/scope.html b/docs/spec/scope.html
index be592157..5576f6c8 100644
--- a/docs/spec/scope.html
+++ b/docs/spec/scope.html
@@ -4,10 +4,10 @@
<title>Specification: BQN variable scoping</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">spec</a></div>
-<h1 id="specification-bqn-variable-scoping">Specification: BQN variable scoping</h1>
+<h1 id="specification-bqn-variable-scoping"><a class="header" href="#specification-bqn-variable-scoping">Specification: BQN variable scoping</a></h1>
<p>BQN uses lexical scoping for variables, where scopes correspond roughly to blocks, or pairs of curly braces separated by semicolons. At the top level in a scope, new variables are visible only after they are defined, but in the scopes it contains, all variables defined in that scope are visible. This system is specified more precisely below.</p>
<p>A running BQN program manipulates variables during its <a href="evaluate.html">execution</a>, but it is important to distinguish these variables from the identifiers that refer to them. As defined in the <a href="token.html">tokenization rules</a>, an identifier is a particular kind of token found in a program's source code. The lexical scoping rules in this page define which identifiers are considered the same; these identifiers will refer to the same variables when the program is run. While each variable has only one identifier, an identifier can refer to any number of variables because a new variable is created for that identifier each time its containing scope is instantiated (that is, each time the contents of the block are evaluated).</p>
-<h2 id="identifier-equivalence-with-lexical-scoping">Identifier equivalence with lexical scoping</h2>
+<h2 id="identifier-equivalence-with-lexical-scoping"><a class="header" href="#identifier-equivalence-with-lexical-scoping">Identifier equivalence with lexical scoping</a></h2>
<p>In this section the concept of an identifier's definition, a possibly different instance of that identifier, is specified. The definition determines when identifiers refer to the &quot;same thing&quot;. In concrete terms, identifiers with the same definition all manipulate the same variable in a particular instance of the definition's containing scope.</p>
<p>A <em>scope</em> is a <code><span class='Function'>PROGRAM</span></code>, <code><span class='Value'>brSub</span></code>, <code><span class='Function'>FCase</span></code>, <code><span class='Function'>FMain</span></code>, <code><span class='Modifier'>_mCase</span></code>, <code><span class='Modifier'>_mMain</span></code>, <code><span class='Modifier2'>_cCase_</span></code>, <code><span class='Modifier2'>_cMain_</span></code>, or <code><span class='Value'>brNS</span></code> node as defined by the BQN <a href="grammar.html">grammar</a>. An <em>identifier instance</em> is an <code><span class='Value'>s</span></code>, <code><span class='Function'>F</span></code>, <code><span class='Modifier'>_m</span></code>, or <code><span class='Modifier2'>_c_</span></code> node; its <em>containing scope</em> is the &quot;smallest&quot; scope that contains it—the scope that contains the identifier but not any other scopes containing the identifier. An identifier instance is <em>defined</em> when it is contained in the left hand side of an <code><span class='Gets'>←</span></code> assignment expression, that is, the leftmost component of one of the five grammatical rules with <code><span class='Function'>ASGN</span></code>, provided that the <code><span class='Function'>ASGN</span></code> node is <code><span class='String'>&quot;←&quot;</span></code> or <code><span class='String'>&quot;⇐&quot;</span></code>, or in a scope header, that is, a component immediately preceding <code><span class='String'>&quot;:&quot;</span></code>. Each identifier instance in a valid BQN program corresponds to exactly one such defined identifier, called its <em>definition</em>, and two instances are considered to refer to the same identifier if they have the same definition.</p>
<p>Two identifier instances have the <em>same name</em> if their tokens, as strings, match after removing all underscores <code><span class='Modifier2'>_</span></code> and ignoring case (so that the letters a to z are equal to their uppercase equivalents A to Z for this comparison). However, instances with the same name are not necessarily the same identifier, as they must also have the same definition. A defined identifier is a <em>potential definition</em> of another identifier instance if the two have the same name, and either:</p>
@@ -19,16 +19,16 @@
<p>The definition for an identifier is chosen from the potential definitions based on their containing scopes: it is the one whose containing scope does not contain or match the containing scope of any other potential definition. If for any identifier there is no definition, then the program is not valid and results in an error. This can occur if the identifier has no potential definition, and also if two potential definitions appear in the same scope. In fact, under this scheme it is never valid to make two definitions with the same name at the top level of a single scope, because both definitions would be potential definitions for the one that comes second in program order. Both definitions have the same containing scope, and any potential definition must contain or match this scope, so no potential definition can be selected.</p>
<p>The definition of <em>program order</em> for identifier tokens follows the order of BQN <a href="evaluate.html">execution</a>. It corresponds to the order of a particular traversal of the abstract syntax tree for a program. To find the relative ordering of two identifiers in a program, we consider the highest-depth node that they both belong to; in this node they must occur in different components, or that component would be a higher-depth node containing both of them. In most nodes, the program order goes from right to left: components further to the right come earlier in program order. The exceptions are <code><span class='Function'>PROGRAM</span></code>, <code><span class='Function'>BODY</span></code>, <code><span class='Function'>NS_BODY</span></code>, <code><span class='Value'>list</span></code>, <code><span class='Value'>subject</span></code> (for stranding), and body case (<code><span class='Function'>FCase</span></code>, <code><span class='Modifier'>_mCase</span></code>, <code><span class='Modifier2'>_cCase_</span></code>, <code><span class='Function'>FMain</span></code>, <code><span class='Modifier'>_mMain</span></code>, <code><span class='Modifier2'>_cMain_</span></code>, <code><span class='Value'>brSub</span></code>, <code><span class='Function'>BrFunc</span></code>, <code><span class='Modifier'>_brMod1</span></code>, and <code><span class='Modifier2'>_brMod2_</span></code>) nodes, in which program order goes in the opposite order, from left to right (some assignment target nodes also contain lists or strands, but their ordering is irrelevant because if two identifiers with the same name appear in such a list, then it can't be a definition).</p>
<p>A subject label is the <code><span class='Value'>s</span></code> term in a <code><span class='Value'>brSub</span></code> node. As part of a header, it can serve as the definition for an identifier. However, it's defined to be a syntax error if another instance of this identifier appears, except in a <code><span class='Function'>Return</span></code> node (which cannot access its value).</p>
-<h3 id="special-names">Special names</h3>
+<h3 id="special-names"><a class="header" href="#special-names">Special names</a></h3>
<p>Special names such as <code><span class='Value'>𝕩</span></code> or <code><span class='Value'>𝕣</span></code> refer to variables, but have no definition and do not use scoping. Instead, they always refer to the immediately enclosing scope, and are defined automatically when the block is evaluated.</p>
<p>The six special names are <code><span class='Value'>𝕨𝕩𝕗𝕘𝕤𝕣</span></code>, and the tokens <code><span class='Function'>𝕎𝕏𝔽𝔾𝕊</span></code>, <code><span class='Modifier'>_𝕣</span></code>, and <code><span class='Modifier2'>_𝕣_</span></code> are alternate spellings of these names as described in the <a href="token.html">tokenization rules</a>. Special names may be modified with <code><span class='Gets'>↩</span></code> assignment but cannot appear as the target of other kinds of assignment. Two special names represent the same identifier if they are the same name and appear in the same body. The initial value these names have is defined by the <a href="evaluate.html">evaluation rules</a>; the grammar for blocks ensures that all special names used in a block will be defined (possibly as the special value <code><span class='Nothing'>·</span></code> in the case of <code><span class='Value'>𝕨</span></code>).</p>
-<h3 id="imports-and-exports">Imports and exports</h3>
+<h3 id="imports-and-exports"><a class="header" href="#imports-and-exports">Imports and exports</a></h3>
<p>Names that are preceded by an <code><span class='Value'>atom</span> <span class='String'>&quot;.&quot;</span></code> term, or that appear as <code><span class='Function'>LHS_NAME</span></code> terms in an <code><span class='Function'>NS_VAR</span></code> or <code><span class='Value'>lhsNs</span></code>, are variable references in a namespace: in the first case, the result of the <code><span class='Value'>atom</span></code> node, and in the second, of the overall assignments <code><span class='Value'>subExpr</span></code> right hand side. These names do not follow lexical scoping; in general they must be stored in order to perform a name lookup when the namespace is available. Such a name in <code><span class='Value'>lhsNs</span></code>, or in <code><span class='Function'>NS_VAR</span></code> with no accompanying <code><span class='Value'>lhs</span> <span class='String'>&quot;⇐&quot;</span></code> term, additionally serves as an identifier within the actual enclosing scope, which works like any other assignment.</p>
<p>An identifier is <em>exported</em> if the <code><span class='Function'>ASGN</span></code> node in its definition is <code><span class='String'>&quot;⇐&quot;</span></code>, or if it appears anywhere in an <code><span class='Function'>EXPORT</span></code> term. An identifier can only be exported in the scope where it is defined, and not in a containing scope. An <code><span class='Function'>EXPORT</span></code> term that includes an identifier from such a scope causes an error.</p>
-<h2 id="variables">Variables</h2>
+<h2 id="variables"><a class="header" href="#variables">Variables</a></h2>
<p>A <em>variable</em> is an entity that permits two operations: it can be <em>set</em> to a particular value, and its <em>value</em> can be obtained, resulting in the last value it was set to. When either operation is performed it is referred to as <em>accessing</em> the variable.</p>
<p>When a body in a block is evaluated, it creates a <em>namespace</em>, which contains a variable for each definition (that is, defined identifier instance) the body contains. Whenever another block—the block itself, not its contents—is evaluated during the execution of the block, it is linked to the currently-evaluating block, so that it will use the variables defined in this instance. By following these links repeatedly, an instance of a block is always linked to exactly one instance of each block that contains it. These links form a tree that is not necessarily related to the call stack of functions and modifiers. Using the links, the variable an identifier refers to is the one corresponding to that variable's definition in the linked instance of the containing scope for the definition.</p>
<p>The first access to a variable must be made by its definition (this also means it sets the variable). If a different instance of its identifier accesses it first, then an error results. This can happen because every scope contained in a particular scope sees all the definitions it uses, and such a scope could be called before the definition is run. Because of conditional execution, this property must be checked at run time in general; however, in cases where it is possible to statically determine that a program will always violate it, a BQN instance can give an error at compile time rather than run time.</p>
<p>A namespace defines a mapping from names to variables: if the given name is shared by an exported identifier in the body used to create that namespace, then that name maps to the variable corresponding to that identifier. The mapping is undefined for other names.</p>
-<h2 id="returns">Returns</h2>
+<h2 id="returns"><a class="header" href="#returns">Returns</a></h2>
<p>The name <code><span class='Function'>NAME</span> <span class='Function'>|</span> <span class='String'>&quot;𝕊&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;𝕣&quot;</span></code> in a <code><span class='Function'>Return</span></code> node is resolved exactly like any other identifier. Following resolution, the block that defines the identifier must not be a namespace block (export variables or contain an <code><span class='Function'>EXPORT</span></code> statement). Furthermore, if it is a <code><span class='Function'>NAME</span></code>, then its definition must be an internal name for a containing block: <code><span class='Value'>s</span></code> in <code><span class='Value'>brSub</span></code>, <code><span class='Function'>F</span></code> in <code><span class='Function'>FuncHead</span></code> or <code><span class='Function'>FMain</span></code>, <code><span class='Modifier'>_m</span></code> in <code><span class='Function'>Mod1H1</span></code> or <code><span class='Modifier'>_mMain</span></code>, or <code><span class='Modifier2'>_c_</span></code> in <code><span class='Function'>Mod2H1</span></code> or <code><span class='Modifier2'>_cMain_</span></code>. When reached, the <code><span class='Function'>Return</span></code> node's identifier is not accessed; instead, it is used to indicate the namespace that contains it, and through this the block evaluation that created that namespace.</p>
diff --git a/docs/spec/system.html b/docs/spec/system.html
index 53cde76c..76d36a2f 100644
--- a/docs/spec/system.html
+++ b/docs/spec/system.html
@@ -4,11 +4,11 @@
<title>Specification: BQN system-provided values</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">spec</a></div>
-<h1 id="specification-bqn-system-provided-values">Specification: BQN system-provided values</h1>
+<h1 id="specification-bqn-system-provided-values"><a class="header" href="#specification-bqn-system-provided-values">Specification: BQN system-provided values</a></h1>
<p>This portion of the spec is still potentially subject to major changes.</p>
<p>The <code><span class='Value'>•</span></code> symbol is used to access values other than primitives provided by BQN.</p>
<p>All system values described in the BQN specification are optional: an implementation does not have to include any of them. However, if a system value with one of the names given below is included, then it must have the specified behavior. For namespaces this rule applies to individual fields as well: a namespace may be provided with only some of the fields, but a field with one of the given names must behave as specified.</p>
-<h2 id="execution-and-scope-manipulation">Execution and scope manipulation</h2>
+<h2 id="execution-and-scope-manipulation"><a class="header" href="#execution-and-scope-manipulation">Execution and scope manipulation</a></h2>
<table>
<thead>
<tr>
@@ -37,7 +37,7 @@
</table>
<p>The effect of <code><span class='Function'>•Eval</span></code> should be the same as if its argument were written as source code in the scope where <code><span class='Function'>•Eval</span></code> appears. It can define variables, and modify those in the current scope or a parent.</p>
<p><code><span class='Function'>•ScopedEval</span></code> creates as new scope for evaluation as it is loaded. Other than its syntactic role, it is effectively equivalent to <code><span class='Brace'>{</span><span class='Function'>•Eval</span><span class='Brace'>}</span></code>. Parent scopes are visible from the created scope; to make a scope without this property use <code><span class='Function'>•BQN</span><span class='String'>&quot;•Eval&quot;</span></code> or <code><span class='Function'>•BQN</span><span class='String'>&quot;•ScopedEval&quot;</span></code>.</p>
-<h2 id="scripts">Scripts</h2>
+<h2 id="scripts"><a class="header" href="#scripts">Scripts</a></h2>
<table>
<thead>
<tr>
@@ -74,11 +74,11 @@
<p><code><span class='Value'>•path</span></code> simply gives the path of the file in which it appears. It includes a trailing slash but not the name of the file itself.</p>
<p><code><span class='Value'>•name</span></code> gives the name, including the extension, of the file in which it appears. It doesn't include the path.</p>
<p><code><span class='Function'>•Exit</span></code> immediately terminates the running BQN process. If the argument is a valid return code (on Unix, an integer), it is returned; otherwise, the default return code (the one returned when the end of the program is reached) is used.</p>
-<h2 id="files">Files</h2>
+<h2 id="files"><a class="header" href="#files">Files</a></h2>
<p>The system namespace value <code><span class='Value'>•file</span></code> deals with file operations. For the purposes of <code><span class='Value'>•file</span></code>, paths in the filesystem are always strings. As with <code><span class='Function'>•Import</span></code>, file paths may be relative or absolute, and relative paths are relative to <code><span class='Value'>•path</span></code>, except in <code><span class='Value'>•file.</span><span class='Function'>At</span></code> which allows <code><span class='Value'>𝕨</span></code> to specify an alternate base directory. The value <code><span class='Value'>•path</span></code> used for a particular instance of <code><span class='Value'>•file</span></code> is determined by the file that contains that instance.</p>
<p>When a <code><span class='Value'>•file</span></code> function returns a file path or portion of a path, the path is always absolute and canonical, with <code><span class='Value'>.</span></code> and <code><span class='Value'>..</span></code> components removed.</p>
<p>Possible fields of <code><span class='Value'>•file</span></code> are given in the subsections below.</p>
-<h3 id="file-paths">File paths</h3>
+<h3 id="file-paths"><a class="header" href="#file-paths">File paths</a></h3>
<p>The following functions manipulate paths and don't access files. Each takes a relative or absolute path <code><span class='Value'>𝕩</span></code>, and <code><span class='Function'>At</span></code> may also take a base directory <code><span class='Value'>𝕨</span></code>.</p>
<table>
<thead>
@@ -118,7 +118,7 @@
</tr>
</tbody>
</table>
-<h3 id="file-metadata">File metadata</h3>
+<h3 id="file-metadata"><a class="header" href="#file-metadata">File metadata</a></h3>
<p>Metadata functions may query information about a file or directory but do not read to or write from it. Each takes a path <code><span class='Value'>𝕩</span></code>, and some functions also allow new data in <code><span class='Value'>𝕨</span></code>. The returned data in any case is the specified property.</p>
<table>
<thead>
@@ -172,7 +172,7 @@
<li><code><span class='String'>'b'</span></code>: Block device</li>
<li><code><span class='String'>'c'</span></code>: Character device</li>
</ul>
-<h3 id="file-access">File access</h3>
+<h3 id="file-access"><a class="header" href="#file-access">File access</a></h3>
<p>File access functions read or write files, either by manipulating files as a whole or interacting with the contents. Whole-file functions cannot overwrite target files: that is, <code><span class='Function'>Rename</span></code> and <code><span class='Function'>Copy</span></code> must give an error if a file exists at <code><span class='Value'>𝕨</span></code>, and <code><span class='Function'>CreateDir</span></code> if a file exists at <code><span class='Value'>𝕩</span></code>, while <code><span class='Function'>Chars</span></code>, <code><span class='Function'>Lines</span></code>, and <code><span class='Function'>Bytes</span></code> can overwrite the contents of an existing file <code><span class='Value'>𝕨</span></code>. However, these three functions must give an error if <code><span class='Value'>𝕨</span></code> exists and is a directory.</p>
<table>
<thead>
@@ -255,8 +255,8 @@
</tr>
</tbody>
</table>
-<h3 id="open-file-object">Open file object</h3>
-<h2 id="input-and-output">Input and output</h2>
+<h3 id="open-file-object"><a class="header" href="#open-file-object">Open file object</a></h3>
+<h2 id="input-and-output"><a class="header" href="#input-and-output">Input and output</a></h2>
<table>
<thead>
<tr>
@@ -285,7 +285,7 @@
</table>
<p><code><span class='Function'>•Out</span></code> prints a string to stdout, with a trailing newline. <code><span class='Function'>•Show</span></code> displays a BQN value to the programmer (the representation is not specified, and does not need to be plain text). <code><span class='Function'>•Fmt</span></code> returns a string (not a character table: lines are separated by linefeeds) indicating how <code><span class='Value'>𝕩</span></code> would be printed by the interactive environment. Both <code><span class='Function'>•Show</span></code> and <code><span class='Function'>•Fmt</span></code> may take a left argument configuring how the value should be formatted.</p>
<p><code><span class='Function'>•Repr</span></code> attempts to return a string so that <code><span class='Function'>•BQN</span> <span class='Function'>•Repr</span> <span class='Value'>𝕩</span></code> matches <code><span class='Value'>𝕩</span></code>. If <code><span class='Value'>𝕩</span></code> contains any mutable values (operations or namespaces), this is not possible. However, if such a values is stateless, in the sense that they don't access variables outside of their own scopes, it is permissible for <code><span class='Function'>•Repr</span></code> to return source code that would create a value with identical behavior.</p>
-<h2 id="operation-properties">Operation properties</h2>
+<h2 id="operation-properties"><a class="header" href="#operation-properties">Operation properties</a></h2>
<table>
<thead>
<tr>
@@ -411,7 +411,7 @@
</tr>
</tbody>
</table>
-<h2 id="time">Time</h2>
+<h2 id="time"><a class="header" href="#time">Time</a></h2>
<table>
<thead>
<tr>
diff --git a/docs/spec/token.html b/docs/spec/token.html
index e2b851a3..11e661f9 100644
--- a/docs/spec/token.html
+++ b/docs/spec/token.html
@@ -4,7 +4,7 @@
<title>Specification: BQN token formation</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">spec</a></div>
-<h1 id="specification-bqn-token-formation">Specification: BQN token formation</h1>
+<h1 id="specification-bqn-token-formation"><a class="header" href="#specification-bqn-token-formation">Specification: BQN token formation</a></h1>
<p>This page describes BQN's token formation rules (token formation is also called scanning). Most tokens in BQN are a single character long, but quoted characters and strings, identifiers, and numbers can consist of multiple characters, and comments, spaces, and tabs are discarded during token formation.</p>
<p>BQN source code should be considered as a series of unicode code points, which we refer to as &quot;characters&quot;. The separator between lines in a file is considered to be a single character, newline, even though some operating systems such as Windows typically represent it with a two-character CRLF sequence. Implementers should note that not all languages treat unicode code points as atomic, as exposing the UTF-8 or UTF-16 representation instead is common. For a language such as JavaScript that uses UTF-16, the double-struck characters <code><span class='Value'>𝕨</span><span class='Function'>𝕎</span><span class='Value'>𝕩</span><span class='Function'>𝕏</span><span class='Value'>𝕗</span><span class='Function'>𝔽</span><span class='Value'>𝕘</span><span class='Function'>𝔾</span></code> are represented as two 16-bit surrogate characters, but BQN treats them as a single unit.</p>
<p>A BQN <em>character literal</em> consists of a single character between single quotes, such as <code><span class='String'>'a'</span></code>, and a <em>string literal</em> consists of any number of characters between double quotes, such as <code><span class='String'>&quot;&quot;</span></code> or <code><span class='String'>&quot;abc&quot;</span></code>. Character and string literals take precedence with comments over other tokenization rules, so that <code><span class='Comment'>#</span></code> between quotes does not start a comment and whitespace between quotes is not removed, but a quote within a comment does not start a character literal. Almost any character can be included directly in a character or string literal without escaping. The only exception is the double quote character <code><span class='String'>&quot;</span></code>, which must be written twice to include it in a string, as otherwise it would end the string instead. Character literals require no escaping at all, as the length is fixed. In particular, literals for the double and single quote characters are written <code><span class='String'>'''</span></code> and <code><span class='String'>'&quot;'</span></code>, while length-1 strings containing these characters are <code><span class='String'>&quot;'&quot;</span></code> and <code><span class='String'>&quot;&quot;&quot;&quot;</span></code>.</p>
diff --git a/docs/spec/types.html b/docs/spec/types.html
index ea44bb76..ce432dbd 100644
--- a/docs/spec/types.html
+++ b/docs/spec/types.html
@@ -4,7 +4,7 @@
<title>Specification: BQN types</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">spec</a></div>
-<h1 id="specification-bqn-types">Specification: BQN types</h1>
+<h1 id="specification-bqn-types"><a class="header" href="#specification-bqn-types">Specification: BQN types</a></h1>
<p>BQN programs manipulate data of seven types:</p>
<ul>
<li>Character</li>
diff --git a/docs/style.css b/docs/style.css
index 3264e776..4c8eb51b 100644
--- a/docs/style.css
+++ b/docs/style.css
@@ -21,6 +21,19 @@ h1, h2, h3, h4 {
padding-bottom: 0.1em;
border-bottom: 0.01em solid #9995
}
+a:link.header, a:visited.header {
+ text-decoration:none; color:inherit;
+}
+.header { position:relative; }
+.header:before {
+ position: absolute;
+ left: -0.9em;
+ content: "§";
+ opacity: 0;
+}
+.header:hover:before {
+ opacity: 0.3;
+}
table {
border-spacing: 0;
diff --git a/docs/tutorial/combinator.html b/docs/tutorial/combinator.html
index 5052aad1..a9cd7627 100644
--- a/docs/tutorial/combinator.html
+++ b/docs/tutorial/combinator.html
@@ -4,11 +4,11 @@
<title>BQN Tutorial: Combinators</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">tutorial</a></div>
-<h1 id="tutorial-combinators">Tutorial: Combinators</h1>
+<h1 id="tutorial-combinators"><a class="header" href="#tutorial-combinators">Tutorial: Combinators</a></h1>
<p>BQN has a normal enough curly-brace syntax for functions and so on. I don't want to talk about it just yet. Before you get to thinking about how to write <a href="http://www.pbm.com/~lindahl/real.programmers.html">FORTRAN in any language</a> in BQN, let's see if we can acquire some instincts about idiomatic BQN the way that only being stuck in a tightly restricted and horribly confining programming environment can accomplish.</p>
<p>There are benefits to being tightly restricted and horribly confined! In programming. I don't just mean that it forces you to learn new techniques like I said, I mean that using the restricted style we will learn is actually a better way to write portions of a program. This is because a restriction you apply in one part of a program is a promise you can rely on in the rest of the program. So what are we giving up, and what can we rely on in return?</p>
<p><em>Tacit programming</em> does not use variables during the execution of a function (but you might use them for convenience in order to <em>construct</em> a tacit program). Variables allow you to use any accessible value in the program with the same level of ease. Tacit code doesn't. In fact it becomes pretty unusable when more than about three values are active at once. One consequence is that tacit code won't cause confusion by modifying far-away variables. But something unique to the tacit paradigm is that when only a small number of values are active—which is always true in a small enough portion of a program!—it has more powerful ways to describe the way these values flow through the program. The main way it achieves this is with combinators.</p>
-<h2 id="whats-a-combinator">What's a combinator?</h2>
+<h2 id="whats-a-combinator"><a class="header" href="#whats-a-combinator">What's a combinator?</a></h2>
<p>(It's when you can't stop adding suffixes to &quot;combine&quot;). In the first tutorial, we briefly presented three <em>combinators</em>, <code><span class='Modifier2'>∘</span></code>, <code><span class='Modifier'>˜</span></code>, and <code><span class='Modifier'>˙</span></code>. These are functions or modifiers that produce a result from their inputs (arguments or operands) only by applying functions to arguments. For example, let's look at a composition:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=fOKImC0gNg==">↗️</a><pre> <span class='Function'>|</span><span class='Modifier2'>∘</span><span class='Function'>-</span> <span class='Number'>6</span>
6
@@ -156,7 +156,7 @@
</g>
</svg>
-<h2 id="comparisons">Comparisons</h2>
+<h2 id="comparisons"><a class="header" href="#comparisons">Comparisons</a></h2>
<table class='primitives'>
<tr>
<td><span class='Function'><</span></td>
@@ -205,7 +205,7 @@
<span class='Number'>∞</span> <span class='Function'>&lt;</span> <span class='String'>@</span>
1
</pre>
-<h3 id="booleans">Booleans</h3>
+<h3 id="booleans"><a class="header" href="#booleans">Booleans</a></h3>
<p>The return values <code><span class='Number'>0</span></code> and <code><span class='Number'>1</span></code> are natural choices because BQN has no dedicated boolean type: instead, in BQN, the word <em>boolean</em> indicates a number that's 0 or 1, much like &quot;natural number&quot; selects a subset of the possible numbers. This is a choice that might be at odds with your own programming experience, and especially clashes with the world of typed functional programming, where even using the boolean type rather than a dedicated type for an option might be considered a code smell! The design principle guiding this decision, and most of BQN's type system, is that there should only be one type that accomplishes any given programming task. Any distinctions that it has are there because they are really necessary: conflating numbers and characters would make working with strings too difficult, and functions can't really be combined with modifiers because one-argument functions and 1-modifiers take their inputs on different sides.</p>
<p>The advantage of this strategy is that you will spend much less time thinking about types when writing programs. The decisions are already made: if there are a few things, they go in a list; if there a few possible values in a qualitative category then they should be labelled with numbers. And if some value has multiple interpretations then BQN is less likely to require an explicit conversion between these. For example, while the result of <code><span class='Function'>=</span></code> might be taking to say <em>whether</em> two atoms have equal values, maybe it also says <em>how many times</em> the atom on the left appears in the right argument—which is at most one, because there's only one right argument. A silly distinction, or is it? An important property of counts is that we can add them together, for instance, to find how many times the letter &quot;e&quot; appears in a string.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=J2UnID0gIkdlb3JnZSBCb29sZSIKCivCtCAnZScgPSAiR2VvcmdlIEJvb2xlIgoKJ2UnICvCtOKImD0gIkdlb3JnZSBCb29sZSIgICMgV2l0aCBhIGNvbWJpbmF0b3I=">↗️</a><pre> <span class='String'>'e'</span> <span class='Function'>=</span> <span class='String'>&quot;George Boole&quot;</span>
@@ -218,7 +218,7 @@
</span>3
</pre>
<p>This, a well-typed and well-spoken programmer should declare, is an outrage! The purpose of types is to <em>protect</em> us from applying functions to types they're not intended for, because the most likely result is that such an application doesn't make sense. Static types provide a valuable service by catching these dangerous actions at compile time and allowing a programmer to prove that they never happen. Well… this is all true. BQN chooses not to pay the type price of this service and so doesn't get the type protection. And it helps that it's consistent about this choice, so you know that BQN's types are never the answer to these sorts of safety concerns. You will have to find a different way to avoid type errors: perhaps just programming carefully in a small or one-off program, and testing and code review or even external tools in a large one. All that said, I think programmers from outside the array programming world (and even many inside!) drastically underestimate how often a boolean value is really just a narrow-minded take on a counting number.</p>
-<h3 id="comparing-whole-arrays">Comparing whole arrays</h3>
+<h3 id="comparing-whole-arrays"><a class="header" href="#comparing-whole-arrays">Comparing whole arrays</a></h3>
<table class='primitives'>
<tr>
<td><span class='Function'>≡</span></td>
@@ -250,7 +250,7 @@
<span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>2</span> <span class='Function'>≢</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>2</span>
1
</pre>
-<h2 id="length-rank-and-depth">Length, rank, and depth</h2>
+<h2 id="length-rank-and-depth"><a class="header" href="#length-rank-and-depth">Length, rank, and depth</a></h2>
<p>I said above that the comparison functions might have a different meaning when called with only one argument, so let's cover a few of these.</p>
<p>Length (<code><span class='Function'>≠</span></code>) gives the number of elements in a list. For atoms it returns 1; it can't result in an error.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4omgICJ0ZXN0aW5nIgriiaAg4p+o4p+pCuKJoCDin6ggz4AsIOKImCwgImVsZW1lbnQiIOKLhCDin6gnbCcsMSw1LCd0J+KfqSDin6kK4omgIDQ=">↗️</a><pre> <span class='Function'>≠</span> <span class='String'>&quot;testing&quot;</span>
@@ -281,9 +281,9 @@
</span>3
</pre>
<p>You probably won't end up using Depth too much. The data in a typical program has a fixed, known depth, so there's no point in asking BQN what it is. But it might be useful if you want to write a utility function that's flexible about its input. <code><span class='Number'>0</span><span class='Function'>&lt;≡</span><span class='Value'>a</span></code> is the idiomatic way to test whether <code><span class='Value'>a</span></code> is an array.</p>
-<h2 id="composition">Composition</h2>
+<h2 id="composition"><a class="header" href="#composition">Composition</a></h2>
<p>We've discussed Atop (<code><span class='Modifier2'>∘</span></code>), but hopefully you've intuited that it's not the end of the story as far as compositions go. In fact BQN has <strong>three</strong> more modifiers that could reasonably be interpreted as varieties of composition.</p>
-<h3 id="over">Over</h3>
+<h3 id="over"><a class="header" href="#over">Over</a></h3>
<table class='primitives'>
<tr>
<td><span class='Modifier2'>○</span></td>
@@ -375,7 +375,7 @@
</g>
</svg>
-<h3 id="before-and-after">Before and After</h3>
+<h3 id="before-and-after"><a class="header" href="#before-and-after">Before and After</a></h3>
<p>Atop (<code><span class='Modifier2'>∘</span></code>) and Over (<code><span class='Modifier2'>○</span></code>) are both symmetric in some sense: with two arguments, <code><span class='Paren'>(</span><span class='Function'>F</span><span class='Modifier2'>∘</span><span class='Function'>G</span><span class='Paren'>)</span><span class='Modifier'>˜</span></code> is <code><span class='Function'>F</span><span class='Modifier2'>∘</span><span class='Paren'>(</span><span class='Function'>G</span><span class='Modifier'>˜</span><span class='Paren'>)</span></code>, and <code><span class='Paren'>(</span><span class='Function'>F</span><span class='Modifier2'>○</span><span class='Function'>G</span><span class='Paren'>)</span><span class='Modifier'>˜</span></code> is <code><span class='Paren'>(</span><span class='Function'>F</span><span class='Modifier'>˜</span><span class='Paren'>)</span><span class='Modifier2'>○</span><span class='Function'>G</span></code>. Put another way, reversing the order of arguments to Atop or Over as a whole is the same as reversing the order of every two-argument function inside—<code><span class='Function'>G</span></code> for <code><span class='Function'>F</span><span class='Modifier2'>∘</span><span class='Function'>G</span></code> and <code><span class='Function'>F</span></code> for <code><span class='Function'>F</span><span class='Modifier2'>○</span><span class='Function'>G</span></code>. If it's not obvious why this is the case, work it out for yourself by walking through how these functions would apply to their arguments! This causes their diagrams to be symmetric as well. Swap (<code><span class='Modifier'>˜</span></code>) also has a symmetric diagram, and it's very easy to show that it's symmetric: take a look at <code><span class='Paren'>(</span><span class='Function'>F</span><span class='Modifier'>˜</span><span class='Paren'>)</span><span class='Modifier'>˜</span></code> and <code><span class='Paren'>(</span><span class='Function'>F</span><span class='Modifier'>˜</span><span class='Paren'>)</span><span class='Modifier'>˜</span></code>. In both cases I started with <code><span class='Function'>F</span><span class='Modifier'>˜</span></code>, but in one case I applied <code><span class='Modifier'>˜</span></code> to the entire function and in the other I applied it on the inside, to <code><span class='Function'>F</span></code> only. And I won't tell you which is which.</p>
<table class='primitives'>
<tr>
@@ -497,7 +497,7 @@
⟨ 0 0.109375 0.1875 0.234375 0.25 0.234375 0.1875 0.109375 ⟩
</pre>
<p>Our list of arguments stops before reaching 1, because <code><span class='Function'>↕</span><span class='Number'>8</span></code> doesn't include <code><span class='Number'>8</span></code>. If we wanted a list from 0 to 1 <em>inclusive</em>, we'd need to divide by <code><span class='Number'>7</span></code> (that is, <code><span class='Number'>8</span><span class='Function'>-</span><span class='Number'>1</span></code>) instead of <code><span class='Number'>8</span></code>. We can do this as well! But first we need to understand some other ways to apply Before and After.</p>
-<h4 id="bind">Bind</h4>
+<h4 id="bind"><a class="header" href="#bind">Bind</a></h4>
<p>We showed in the first tutorial that a modifier's operand doesn't have to be a function, but can also be a data value. That hasn't come up yet, except for a cryptic use of &quot;Bind&quot; (<code><span class='Modifier2'>⊸</span></code>?) in the function <code><span class='Paren'>(</span><span class='Function'>⌽</span><span class='Number'>2</span><span class='Function'>⋆↕</span><span class='Number'>8</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>×</span><span class='Modifier'>¨</span></code> from the last tutorial. How does that work? Some kind of secret identity for Before and After?</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MeKKuCsgNQor4p+cMSA1">↗️</a><pre> <span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span> <span class='Number'>5</span>
6
@@ -550,7 +550,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKGlcO3LeKfnDEpIDg=">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>↕÷-</span><span class='Modifier2'>⟜</span><span class='Number'>1</span><span class='Paren'>)</span> <span class='Number'>8</span>
⟨ 0 0.14285714285714285 0.2857142857142857 0.42857142857142855 0.5714285714285714 0.7142857142857143 0.8571428571428571 1 ⟩
</pre>
-<h2 id="base-decoding-continued">Base decoding continued</h2>
+<h2 id="base-decoding-continued"><a class="header" href="#base-decoding-continued">Base decoding continued</a></h2>
<p>We're speeding up a bit now, so in the examples below it might take some time for you to break down what I did and why. Remember that you can open any expression in the REPL in order to change parts of it or view the syntax. And don't get discouraged just because of how long it takes to understand a line of code! First, you'll surely get faster in fitting the pieces together. Second, a line of BQN often has more code in it than a line in other languages, because primitives have such short names. Think about how much <em>functionality</em> you can read and understand rather than how few <em>lines</em> you get through.</p>
<p>In the last tutorial I <a href="list.html#example-base-decoding">went over</a> a way to decode a list of strings containing binary codes for ASCII characters:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=QCArICvCtMKoICjijL0y4ouG4oaVOCniirjDl8KoICcwJyAty5wgIjAxMDAwMDEwIuKAvyIwMTAxMDAwMSLigL8iMDEwMDExMTAi">↗️</a><pre> <span class='String'>@</span> <span class='Function'>+</span> <span class='Function'>+</span><span class='Modifier'>´¨</span> <span class='Paren'>(</span><span class='Function'>⌽</span><span class='Number'>2</span><span class='Function'>⋆↕</span><span class='Number'>8</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>×</span><span class='Modifier'>¨</span> <span class='String'>'0'</span> <span class='Function'>-</span><span class='Modifier'>˜</span> <span class='String'>&quot;01000010&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;01010001&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;01001110&quot;</span>
@@ -597,7 +597,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KEArIMK3K+KfnCgy4oq4w5cpwrTiiJjijL3CqCAt4p+cJzAnKSAiMDEwMDAwMTAi4oC/IjAxMDEwMDAxIuKAvyIwMTAwMTExMCI=">↗️</a><pre> <span class='Paren'>(</span><span class='String'>@</span><span class='Function'>+</span> <span class='Nothing'>·</span><span class='Function'>+</span><span class='Modifier2'>⟜</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Modifier2'>⊸</span><span class='Function'>×</span><span class='Paren'>)</span><span class='Modifier'>´</span><span class='Modifier2'>∘</span><span class='Function'>⌽</span><span class='Modifier'>¨</span> <span class='Function'>-</span><span class='Modifier2'>⟜</span><span class='String'>'0'</span><span class='Paren'>)</span> <span class='String'>&quot;01000010&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;01010001&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;01001110&quot;</span>
"BQN"
</pre>
-<h2 id="summary">Summary</h2>
+<h2 id="summary"><a class="header" href="#summary">Summary</a></h2>
<p>BQN has a full complement of comparison functions, which are pervasive (work on atoms only) like arithmetic functions. The non-pervasive functions Match (<code><span class='Function'>≡</span></code>) and Not Match (<code><span class='Function'>≢</span></code>) compare entire arrays. Comparison functions return <code><span class='Number'>1</span></code> if the comparison holds and <code><span class='Number'>0</span></code> if it doesn't; these two numbers make up the &quot;booleans&quot;.</p>
<table>
<thead>
diff --git a/docs/tutorial/expression.html b/docs/tutorial/expression.html
index 840ec4fd..89a43380 100644
--- a/docs/tutorial/expression.html
+++ b/docs/tutorial/expression.html
@@ -4,8 +4,8 @@
<title>Tutorial: BQN expressions</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">tutorial</a></div>
-<h1 id="tutorial-bqn-expressions">Tutorial: BQN expressions</h1>
-<h2 id="arithmetic">Arithmetic</h2>
+<h1 id="tutorial-bqn-expressions"><a class="header" href="#tutorial-bqn-expressions">Tutorial: BQN expressions</a></h1>
+<h2 id="arithmetic"><a class="header" href="#arithmetic">Arithmetic</a></h2>
<p>All right, let's get started! Since you can run BQN online from the <a href="https://mlochbaum.github.io/BQN/try.html">REPL</a> there aren't any real technical preliminaries, but if you'd like to look at non-web-based options head over to <a href="../running.html">running.md</a>.</p>
<p>In the code blocks shown here, input is highlighted and indented, while output is not colored or indented. To experiment with the code, you can click the <code><span class='Value'>↗️</span></code> arrow in the top right corner to open it in the REPL.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MiArIDMKNi0gICA1Ci0gMS41">↗️</a><pre> <span class='Number'>2</span> <span class='Function'>+</span> <span class='Number'>3</span>
@@ -102,7 +102,7 @@
</span><span class='Function'>√</span> <span class='Function'>⋆</span> <span class='Comment'># \ shift
</span></pre>
<p>In case you're wondering, Logarithm—the other inverse of Power—is written <code><span class='Function'>⋆</span><span class='Modifier'>⁼</span></code>. We'll see how that works when we introduce <code><span class='Modifier'>⁼</span></code> in the section on 1-modifiers.</p>
-<h2 id="compound-expressions">Compound expressions</h2>
+<h2 id="compound-expressions"><a class="header" href="#compound-expressions">Compound expressions</a></h2>
<p>It's sometimes useful to write programs with more than one function in them. Here is where BQN and any sort of normality part ways.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MsOXMyAtIDUKKDLDlzMpIC0gNQ==">↗️</a><pre> <span class='Number'>2</span><span class='Function'>×</span><span class='Number'>3</span> <span class='Function'>-</span> <span class='Number'>5</span>
¯4
@@ -157,7 +157,7 @@
<p>The online REPL includes a tool to create diagrams like the one shown above. To enable it, click the &quot;explain&quot; button. Then a diagram of your source code will be shown above the result each time you run an expression.</p>
<p>The following rule might help you to internalize this system in addition to identifying when parentheses are needed: an expression never needs to end with a parenthesis, or have two closing parentheses in a row. If it does, at least one set of parentheses can be removed without changing the meaning.</p>
-<h2 id="one-or-two-arguments">One or two arguments?</h2>
+<h2 id="one-or-two-arguments"><a class="header" href="#one-or-two-arguments">One or two arguments?</a></h2>
<p>What about functions without a left argument? Let's find an equation with lots of square roots in it… <a href="https://en.wikipedia.org/wiki/Nested_radical#Denesting">looks good</a>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oiaIDMgKyAyIMOXIOKImjIKMSArIOKImjI=">↗️</a><pre> <span class='Function'>√</span> <span class='Number'>3</span> <span class='Function'>+</span> <span class='Number'>2</span> <span class='Function'>×</span> <span class='Function'>√</span><span class='Number'>2</span>
2.414213562373095
@@ -227,7 +227,7 @@
<li>A set of parentheses has the same role as whatever's inside it.</li>
</ul>
<p>Perhaps more than you thought! To really get roles, it's important to understand that a role is properly a property of an expression, and not its value. In language implementation terms, roles are used only to parse expressions, giving a syntax tree, but don't dictate what values are possible when the tree is evaluated. So it's possible to have a function with a number role or a number with a function role. The reason this doesn't happen with the numeric literals and primitives we've introduced is that these tokens have a constant value. <code><span class='Function'>×</span></code> or <code><span class='Number'>∞</span></code> have the same value in any possible program, and so it makes sense that their types and roles should correspond. When we introduce identifiers, we'll see this correspondence break down—and why that's good!</p>
-<h2 id="character-arithmetic">Character arithmetic</h2>
+<h2 id="character-arithmetic"><a class="header" href="#character-arithmetic">Character arithmetic</a></h2>
<p>Gosh, that's a lot of arithmetic up there. Maybe adding characters will mix things up a bit? Hang on, you can't add characters, only subtract them… let's back up.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=J2Mn">↗️</a><pre> <span class='String'>'c'</span>
'c'
@@ -279,7 +279,7 @@
<p>It's a convenient way to write non-printing characters without having to include them in your source code: for example <code><span class='String'>@</span><span class='Function'>+</span><span class='Number'>10</span></code> is the newline character.</p>
<p>Addition and subtraction with affine characters have all the same algebraic properties that they do with numbers. One way to see this is to think of values as a combination of &quot;characterness&quot; (0 for numbers and 1 for characters) and either numeric value or code point. Addition and subtraction are done element-wise on these pairs of numbers, and are allowed if the result is a valid value, that is, its characterness is 0 or 1 and its value is a valid code point if the characterness is 1. However, because the space of values is no longer closed under addition and subtraction, certain rearrangements of valid computations might not work, if one of the values produced in the middle isn't legal.</p>
-<h2 id="modifiers">Modifiers</h2>
+<h2 id="modifiers"><a class="header" href="#modifiers">Modifiers</a></h2>
<p>Functions are nice and all, but to really bring us into the space age BQN has a second level of function called <em>modifiers</em> (the space age in this case is when operators were introduced to APL in the early 60s—hey, did you know the <a href="https://aplwiki.com/wiki/APL_conference#1970">second APL conference</a> was held at Goddard Space Flight Center?). While functions apply to subjects, modifiers can apply to functions <em>or</em> subjects, and return functions. For example, the 1-modifier <code><span class='Modifier'>˜</span></code> modifies one function by swapping the arguments before calling it (Swap), or copying the right argument to the left if there's only one (Self).</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MiAty5wgJ2QnICAjIFN1YnRyYWN0IGZyb20KK8ucIDMgICAgICAjIEFkZCB0byBpdHNlbGY=">↗️</a><pre> <span class='Number'>2</span> <span class='Function'>-</span><span class='Modifier'>˜</span> <span class='String'>'d'</span> <span class='Comment'># Subtract from
</span>'b'
@@ -332,7 +332,7 @@
</pre>
<p>Well, I guess it's not pedagogically useless, as it does demonstrate that a modifier can be applied to subjects as well as functions. Even though <code><span class='Number'>3</span></code> is a subject, <code><span class='Number'>3</span><span class='Modifier'>˙</span></code> is a function, and can be applied to and ignore the two arguments <code><span class='Number'>2</span></code> and <code><span class='Number'>4</span></code>.</p>
<p>With three examples you may have noticed that 1-modifiers tend to cluster at the top of the screen. In fact, every primitive 1-modifer is a superscript character: we've covered <code><span class='Modifier'>˜⁼˙</span></code>, and the remaining array-based modifiers <code><span class='Modifier'>˘¨⌜´˝`</span></code> will show up later.</p>
-<h2 id="2-modifiers">2-modifiers</h2>
+<h2 id="2-modifiers"><a class="header" href="#2-modifiers">2-modifiers</a></h2>
<p>Made it to the last role, the 2-modifier (if you think something's been skipped, you're free to call subjects 0-modifiers. They don't modify anything. Just not when other people can hear you). To introduce them we'll use Atop <code><span class='Modifier2'>∘</span></code>, which works a lot like mathematical composition, except that it's extended to use one or two arguments. These arguments are passed to the function on the right, and the result is passed to the function on the left. So the function on the left is only ever called with one argument.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyDDl8uc4oiYKyA0ICAjIFNxdWFyZSBvZiAzIHBsdXMgNAot4oiYKMOXy5wpIDUgICMgTmVnYXRpdmUgc3F1YXJlIG9mIDU=">↗️</a><pre> <span class='Number'>3</span> <span class='Function'>×</span><span class='Modifier'>˜</span><span class='Modifier2'>∘</span><span class='Function'>+</span> <span class='Number'>4</span> <span class='Comment'># Square of 3 plus 4
</span>49
@@ -384,7 +384,7 @@
<p>This ordering is more consistent with the rule that a 1-modifier's operand should go to its left. If we tried going from right to left we'd end up with <code><span class='Function'>×</span><span class='Paren'>(</span><span class='Modifier'>˜</span><span class='Modifier2'>∘</span><span class='Function'>+</span><span class='Paren'>)</span></code>, which uses <code><span class='Modifier'>˜</span></code> as an operand to <code><span class='Modifier2'>∘</span></code>. But a modifier can't be used as an operand. To make it work we'd have to give 1-modifiers a higher precedence than 2-modifiers.</p>
<p>In fact, the rules for modifiers are exactly the same as those for functions, but reversed. So why is there a distinction between 1- and 2-modifiers, when for functions we can look to the left to see whether there is a left argument? The reason is that it's natural to follow a 1-modifier by a subject or function that isn't supposed to be its operand. Using an example from the last section, <code><span class='Function'>+</span><span class='Modifier'>˜</span> <span class='Number'>3</span></code> has a subject to the right of the 1-modifier <code><span class='Modifier'>˜</span></code>. Even worse, <code><span class='Function'>+</span><span class='Modifier'>˜</span> <span class='Function'>÷</span> <span class='Number'>3</span></code> looks just like <code><span class='Function'>+</span><span class='Modifier2'>∘</span> <span class='Function'>÷</span> <span class='Number'>3</span></code>, but it's two functions <code><span class='Function'>+</span><span class='Modifier'>˜</span></code> and <code><span class='Function'>÷</span></code> applied to <code><span class='Number'>3</span></code> while the version with Atop is a single function <code><span class='Function'>+</span><span class='Modifier2'>∘</span><span class='Function'>÷</span></code> applied to <code><span class='Number'>3</span></code>. So the two-layer system of functions and modifiers forces modifiers to have a fixed number of operands even though every function (including those derived by applying modifiers) can be called with one or two arguments.</p>
<p>Remember that 1-modifiers are all superscripts? The characters for 2-modifiers use a different rule: each contains an <em>unbroken</em> circle (that is, lines might touch it but not go through it). The 2-modifiers in BQN are the combinators <code><span class='Modifier2'>∘○⊸⟜⊘</span></code>, the sort-of-combinators <code><span class='Modifier2'>⌾◶⍟</span></code>, and the not-at-all-combinators <code><span class='Modifier2'>⎉⚇⎊</span></code>. And the functions that make that unbroken circle rule necessary are written <code><span class='Function'>⌽⍉</span></code>. Since every primitive is a function, 1-modifier, or 2-modifier, you can always tell what type (and role) it has: a superscript is a 1-modifier, an unbroken circle makes it a 2-modifier, and otherwise it's a function.</p>
-<h2 id="summary">Summary</h2>
+<h2 id="summary"><a class="header" href="#summary">Summary</a></h2>
<p>The objects we've seen so far are:</p>
<table>
<thead>
diff --git a/docs/tutorial/index.html b/docs/tutorial/index.html
index 396aabe4..85a2431f 100644
--- a/docs/tutorial/index.html
+++ b/docs/tutorial/index.html
@@ -4,7 +4,7 @@
<title>BQN tutorials</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a></div>
-<h1 id="bqn-tutorials">BQN tutorials</h1>
+<h1 id="bqn-tutorials"><a class="header" href="#bqn-tutorials">BQN tutorials</a></h1>
<p>BQN tutorials explain how to approach and use the language as a newcomer (or they try; please get in touch if you find that they skip ahead!). Tutorials are meant to explain key ideas and may ignore details that would be included in the <a href="../doc/index.html">documentation</a>; also unlike the documentation they're meant to be read in order, as each tutorial will build on ideas from the previous ones.</p>
<p>Tutorials assume (pretty presumptively, really. Disgusting.) that you are already motivated to learn BQN and use simple rather than flashy examples. Documents to induce motivation beyond the README are not yet available. Do feel free to skim or jump around if you find you are reading a lot of things that are already obvious.</p>
<p>The tutorials available so far:</p>
diff --git a/docs/tutorial/list.html b/docs/tutorial/list.html
index a44c30b4..0e032b98 100644
--- a/docs/tutorial/list.html
+++ b/docs/tutorial/list.html
@@ -4,7 +4,7 @@
<title>BQN Tutorial: Working with lists</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">tutorial</a></div>
-<h1 id="tutorial-working-with-lists">Tutorial: Working with lists</h1>
+<h1 id="tutorial-working-with-lists"><a class="header" href="#tutorial-working-with-lists">Tutorial: Working with lists</a></h1>
<p>Enough with all these preliminaries like learning how to read basic expressions. Let's get into what makes BQN special.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oMSwgMiwgM+KfqQ==">↗️</a><pre> <span class='Bracket'>⟨</span><span class='Number'>1</span><span class='Separator'>,</span> <span class='Number'>2</span><span class='Separator'>,</span> <span class='Number'>3</span><span class='Bracket'>⟩</span>
⟨ 1 2 3 ⟩
@@ -14,7 +14,7 @@
⟨ 2 3 4 ⟩
</pre>
<p>There we go. Now in BQN arrays are not just lists, which are a 1-dimensional data structure, but can have any number of dimensions. In this tutorial we're going to discuss lists only, leaving the 5-dimensional stuff for later. So we're really only seeing the power of <a href="https://aplwiki.com/wiki/K">K</a>, an APL-family language that only uses lists (and dictionaries, which BQN doesn't have). K was powerful enough for Arthur Whitney to found <a href="https://en.wikipedia.org/wiki/Kx_Systems">two</a> <a href="https://shakti.com/">companies</a> and make millions and millions of dollars, and BQN's compiler also runs almost entirely on lists, so this is probably enough power for one webpage.</p>
-<h2 id="list-notation">List notation</h2>
+<h2 id="list-notation"><a class="header" href="#list-notation">List notation</a></h2>
<p>There are three kinds of list notation in BQN. Each of them has a subject role overall, even if expressions used inside it might have other roles. First, a <em>string</em> is a list of characters, and is written by placing those characters in double quotes.</p>
<pre><span class='String'>&quot;Text!&quot;</span>
</pre>
@@ -86,7 +86,7 @@
<span class='Number'>0</span><span class='Ligature'>‿</span><span class='Paren'>(</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Paren'>)</span>
⟨ 0 ⟨ 1 2 ⟩ ⟩
</pre>
-<h2 id="bqn-types">BQN types</h2>
+<h2 id="bqn-types"><a class="header" href="#bqn-types">BQN types</a></h2>
<p>Now that all six BQN types have been introduced, let's make a table:</p>
<table>
<thead>
@@ -111,7 +111,7 @@
</tbody>
</table>
<p>Lists are just one-dimensional arrays. Types are divided into <em>data types</em>, which tend to have a subject role, and <em>operation types</em>, which tend to have a role matching their type. Also, any value that's not an array, such as everything we used in the last tutorial, is called an <em>atom</em>.</p>
-<h2 id="arithmetic-on-lists">Arithmetic on lists</h2>
+<h2 id="arithmetic-on-lists"><a class="header" href="#arithmetic-on-lists">Arithmetic on lists</a></h2>
<p>Arithmetic functions automatically apply to each element of a list argument. If both arguments are lists, they have to have the same length, and they're matched up one element at a time.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=w7cg4p+oMiwzLDTin6kKCiJBUEwiICsgMQoKIjMxNDE1IiAtICcwJwoKNOKAvzPigL8y4oC/MSDii4YgMeKAvzLigL8z4oC/NA==">↗️</a><pre> <span class='Function'>÷</span> <span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>4</span><span class='Bracket'>⟩</span>
⟨ 0.5 0.3333333333333333 0.25 ⟩
@@ -132,7 +132,7 @@
<span class='Bracket'>⟨</span> <span class='Number'>10</span><span class='Separator'>,</span> <span class='Number'>20</span><span class='Ligature'>‿</span><span class='Number'>30</span> <span class='Bracket'>⟩</span> <span class='Function'>+</span> <span class='Bracket'>⟨</span> <span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Separator'>,</span> <span class='Number'>3</span> <span class='Bracket'>⟩</span>
⟨ ⟨ 11 12 ⟩ ⟨ 23 33 ⟩ ⟩
</pre>
-<h2 id="some-list-functions">Some list functions</h2>
+<h2 id="some-list-functions"><a class="header" href="#some-list-functions">Some list functions</a></h2>
<table class='primitives'>
<tr>
<td><span class='Function'>≍</span></td>
@@ -183,7 +183,7 @@
<span class='Number'>¯1</span> <span class='Function'>⌽</span> <span class='String'>&quot;bcdea&quot;</span>
"abcde"
</pre>
-<h3 id="and-modifiers">…and modifiers</h3>
+<h3 id="and-modifiers"><a class="header" href="#and-modifiers">…and modifiers</a></h3>
<table class='primitives'>
<tr>
<td><span class='Modifier'>¨</span></td>
@@ -235,7 +235,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oi+IOKfqCAiY29uIiwgImNhdCIsICJlbmF0IiwgImUiIOKfqQ==">↗️</a><pre> <span class='Function'>∾</span> <span class='Bracket'>⟨</span> <span class='String'>&quot;con&quot;</span><span class='Separator'>,</span> <span class='String'>&quot;cat&quot;</span><span class='Separator'>,</span> <span class='String'>&quot;enat&quot;</span><span class='Separator'>,</span> <span class='String'>&quot;e&quot;</span> <span class='Bracket'>⟩</span>
"concatenate"
</pre>
-<h2 id="example-base-decoding">Example: base decoding</h2>
+<h2 id="example-base-decoding"><a class="header" href="#example-base-decoding">Example: base decoding</a></h2>
<p>Some people like to imagine that robots or other techno-beings speak entirely in binary-encoded ASCII, like for instance &quot;01001110 01100101 01110010 01100100 00100001&quot;. This is dumb for a lot of reasons, and the encoded text probably just says something inane, but you're a slave to curiosity and can't ignore it. Are one and a half tutorials of BQN enough to clear your conscience?</p>
<table class='primitives'>
<tr>
@@ -359,7 +359,7 @@ ERROR
<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='Modifier'>´</span> <span class='Function'>⌽</span> <span class='String'>&quot;1001&quot;</span><span class='Function'>-</span><span class='String'>'0'</span>
9
</pre>
-<h2 id="summary">Summary</h2>
+<h2 id="summary"><a class="header" href="#summary">Summary</a></h2>
<p>There are three types of syntax that create lists: the <code><span class='String'>&quot;string literal&quot;</span></code> for lists of characters and either enclosing angle brackets <code><span class='Bracket'>⟨⟩</span></code> with <code><span class='Separator'>,</span></code> or <code><span class='Separator'>⋄</span></code> or newline characters or connecting ligatures <code><span class='Ligature'>‿</span></code> for lists with arbitrary elements. The ligature has a higher precedence than functions or modifiers, so we should add it to our precedence table:</p>
<table>
<thead>
diff --git a/docs/tutorial/variable.html b/docs/tutorial/variable.html
index 33f1e48c..e8a1f06e 100644
--- a/docs/tutorial/variable.html
+++ b/docs/tutorial/variable.html
@@ -4,7 +4,7 @@
<title>BQN Tutorial: Variables</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">tutorial</a></div>
-<h1 id="tutorial-variables">Tutorial: Variables</h1>
+<h1 id="tutorial-variables"><a class="header" href="#tutorial-variables">Tutorial: Variables</a></h1>
<p>To take a proud denizen of the eternal cosmos of values, held for a fleeting instant by the course of code, and bind it. Tie it down with a name, failing always to alter its inner nature but allowing context to reform its outer appearance. So labelled, perhaps through the progress of time it will know escape, or else find itself passed through one bond to another, ever tethered. It's a task to be approached only with respect.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=aGV5IOKGkCAiSGkgdGhlcmUiCgpoZXkg4oi+ICIsIFdvcmxkISI=">↗️</a><pre> <span class='Value'>hey</span> <span class='Gets'>←</span> <span class='String'>&quot;Hi there&quot;</span>
@@ -12,7 +12,7 @@
"Hi there, World!"
</pre>
<p>Like that.</p>
-<h2 id="defining-variables">Defining variables</h2>
+<h2 id="defining-variables"><a class="header" href="#defining-variables">Defining variables</a></h2>
<p>BQN uses the left-pointing arrow <code><span class='Gets'>←</span></code> to define variables, as shown above. Most of the time it's best to use it in a plain way, with just the name and its definition, but it's also possible to define multiple variables using list notation, or to define a variable as part of a larger expression that continues to the left (in terms of precedence, <code><span class='Gets'>←</span></code> behaves like a function, but it isn't one—it's a part of syntax).</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=cGnigL9l4oC/dGVuIOKGkCDin6ggz4AsIOKLhjEsIDEwIOKfqQoKdGVuIMOXIHBpCgp0aHJlZSDiiY0gdGVuIC0gdGhyZWUg4oaQIDM=">↗️</a><pre> <span class='Value'>pi</span><span class='Ligature'>‿</span><span class='Value'>e</span><span class='Ligature'>‿</span><span class='Value'>ten</span> <span class='Gets'>←</span> <span class='Bracket'>⟨</span> <span class='Number'>π</span><span class='Separator'>,</span> <span class='Function'>⋆</span><span class='Number'>1</span><span class='Separator'>,</span> <span class='Number'>10</span> <span class='Bracket'>⟩</span>
⟨ 3.141592653589793 2.718281828459045 10 ⟩
@@ -40,7 +40,7 @@ ERROR
</span>ERROR
</pre>
<p>It's an odd distinction to have when your program is just one long sequence of statements, because there's only ever one arrow you can use: it just changes annoyingly after you define the variable for the first time. With multiple scopes this isn't the case: if you start a new scope inside another, then you'll still be able to use variables from the outside scope. Then <code><span class='Gets'>↩</span></code> lets you change the value of one of these variables while <code><span class='Gets'>←</span></code> allows you to define your own. If you're coming from a typical curly-brace language, you'd say that <code><span class='Gets'>←</span></code> both declares and assigns a variable, while <code><span class='Gets'>↩</span></code> only assigns it.</p>
-<h2 id="variable-roles">Variable roles</h2>
+<h2 id="variable-roles"><a class="header" href="#variable-roles">Variable roles</a></h2>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=QlFOIOKGkCAiW21hbnkgcGFnZXMgb2Ygc3BlY2lmaWNhdGlvbl0i">↗️</a><pre> <span class='Function'>BQN</span> <span class='Gets'>←</span> <span class='String'>&quot;[many pages of specification]&quot;</span>
ERROR
</pre>
@@ -104,7 +104,7 @@ ERROR
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MV8wMDBfMDAw">↗️</a><pre> <span class='Number'>1_000_000</span>
1000000
</pre>
-<h2 id="function-assignment">Function assignment</h2>
+<h2 id="function-assignment"><a class="header" href="#function-assignment">Function assignment</a></h2>
<p>While you could build up a script by computing values and assigning them names, the main way to use assignment in tacit programming is to give names to functions, not data. For example, we might name the base-2 conversion function from our last tutorial:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=QmFzZTIg4oaQICvin5woMuKKuMOXKcK04oiY4oy9CgpCYXNlMiAx4oC/MOKAvzHigL8wCgpCYXNlMiAiMDEwMTAwMDEiLScwJwoKQCArIEJhc2UywqggJzAnIC3LnCAiMDEwMDAwMTAi4oC/IjAxMDEwMDAxIuKAvyIwMTAwMTExMCI=">↗️</a><pre> <span class='Function'>Base2</span> <span class='Gets'>←</span> <span class='Function'>+</span><span class='Modifier2'>⟜</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Modifier2'>⊸</span><span class='Function'>×</span><span class='Paren'>)</span><span class='Modifier'>´</span><span class='Modifier2'>∘</span><span class='Function'>⌽</span>
@@ -130,7 +130,7 @@ ERROR
<span class='Function'>Base2</span> <span class='Number'>6</span>
16
</pre>
-<h2 id="modifying-part-of-an-array">Modifying part of an array</h2>
+<h2 id="modifying-part-of-an-array"><a class="header" href="#modifying-part-of-an-array">Modifying part of an array</a></h2>
<p>You cannot modify part of an array. You can't modify an array: an array that differs a little bit from another array <em>is a different array</em>. And this isn't just a terminology choice: it has real effects on how BQN arrays behave and even which arrays are representable, as we'll discuss later.</p>
<p>But say I have a list, and I want to subtract one from one of the elements. With the understanding that the resulting list is different from the first one, BQN allows this!</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IkJRTiIgICAgICAgICAgICAjIEEgbGlzdCBvZiBjaGFyYWN0ZXJzCgot4p+cMeKMvigy4oq44oqRKSAiQlFOIiAgIyBXYWl0IHdoeSBkaWQgSSBkbyB0aGF0">↗️</a><pre> <span class='String'>&quot;BQN&quot;</span> <span class='Comment'># A list of characters
@@ -252,7 +252,7 @@ ERROR
"abcdEFgh"
</pre>
<p>(Here I've snuck in a train <code><span class='Number'>2</span> <span class='Function'>↑</span> <span class='Number'>4</span><span class='Modifier2'>⊸</span><span class='Function'>↓</span></code> to combine the two functions. As an exercise, you might try to write that function using combinators instead, and as an extra hard exercise you might then ponder why someone would want to add trains to a language).</p>
-<h2 id="identity-functions">Identity functions</h2>
+<h2 id="identity-functions"><a class="header" href="#identity-functions">Identity functions</a></h2>
<table class='primitives'>
<tr>
<td><span class='Function'>⊣</span></td>
@@ -282,7 +282,7 @@ ERROR
"left"
</pre>
<p>They are not complicated functions: if you're confused it's because you don't understand why anyone would ever use them. Indeed, it's harder to see why these functions are useful than to see what they do. That is a fact.</p>
-<h2 id="modified-assignment">Modified assignment</h2>
+<h2 id="modified-assignment"><a class="header" href="#modified-assignment">Modified assignment</a></h2>
<p>Let's revisit our question about modifying an array. As we said, the answer to &quot;how do I modify part of an array?&quot; is simply that you can't, and that the question doesn't make sense. But there's a seemingly similar question with a very different answer: &quot;how do I modify part of a variable whose value is an array?&quot; This is because unlike an array, a variable isn't defined by the value it has, but by the name used to refer to it (and the scope it resides in). Here's how we would modify the variable <code><span class='Value'>a</span></code>:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=YSDihpAgNCAgICAgICAgICAgICMgRmlyc3QgaXQncyBhIG51bWJlcgphCgphIOKGqSA04oC/NeKAvzYgICAgICAgICMgTm93IGl0J3MgYSBsaXN0IQph">↗️</a><pre> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='Number'>4</span> <span class='Comment'># First it's a number
</span> <span class='Value'>a</span>