aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/commentary/history.html4
-rw-r--r--docs/commentary/problems.html4
-rw-r--r--docs/commentary/why.html10
-rw-r--r--docs/doc/array.html2
-rw-r--r--docs/doc/arrayrepr.html2
-rw-r--r--docs/doc/based.html4
-rw-r--r--docs/doc/embed.html10
-rw-r--r--docs/doc/fromDyalog.html4
-rw-r--r--docs/doc/fromJ.html12
-rw-r--r--docs/implementation/kclaims.html4
-rw-r--r--docs/implementation/vm.html4
-rw-r--r--docs/spec/system.html2
-rw-r--r--docs/tutorial/variable.html2
13 files changed, 32 insertions, 32 deletions
diff --git a/docs/commentary/history.html b/docs/commentary/history.html
index d1063fdd..f6955a71 100644
--- a/docs/commentary/history.html
+++ b/docs/commentary/history.html
@@ -208,12 +208,12 @@
<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"><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>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='Bracket'>[]</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"><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 consensus 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"><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='Head'>::</span></code>, but J only has the function <code><span class='Value'>[</span><span class='Head'>:</span></code> to unconditionally throw an error, with no way to set a message.</p>
+<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='Head'>::</span></code>, but J only has the function <code><span class='Bracket'>[</span><span class='Head'>:</span></code> to unconditionally throw an error, with no way to set a message.</p>
<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. Although I considered swapping subjects and functions, I ended up using exactly the conventions of his APL <a href="https://abrudz.github.io/style/#nc">style guide</a>.</p>
<h4 id="headers"><a class="header" href="#headers">Headers</a></h4>
diff --git a/docs/commentary/problems.html b/docs/commentary/problems.html
index 38d41ea9..2937be17 100644
--- a/docs/commentary/problems.html
+++ b/docs/commentary/problems.html
@@ -35,7 +35,7 @@
<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 in BQN is to just say give your functions names and don't do this. But <a href="ltr.html">left to right</a> programming beckons.</p>
<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 Nothing syntax <code><span class='Nothing'>·</span></code>, which acts like J's Cap (<code><span class='Value'>[</span><span class='Head'>:</span></code>) in a train, but still a minor frustration.</p>
+<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 Nothing syntax <code><span class='Nothing'>·</span></code>, which acts like J's Cap (<code><span class='Bracket'>[</span><span class='Head'>:</span></code>) in a train, but still a minor frustration.</p>
<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>. Another form of Under that's sometimes wanted is <code><span class='Brace'>{</span><span class='Value'>𝕨</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>. One modifier can only do so much.</p>
<h3 id="list-splicing-is-fiddly"><a class="header" href="#list-splicing-is-fiddly">List splicing is fiddly</a></h3>
@@ -102,7 +102,7 @@
<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="high-rank-array-notation-awkwardness"><a class="header" href="#high-rank-array-notation-awkwardness">High-rank array notation awkwardness</a></h3>
-<p>The notation <code><span class='Value'>[]</span></code> will be added for high-rank arrays, the same as BQN's lists <code><span class='Bracket'>⟨⟩</span></code> except it mixes at the end. It 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? A more concrete point of awkwardness is that literal notations can only form arrays with rank 1 or more, preventing unit arrays from being destructured. Syntax with <code><span class='Function'>&lt;</span></code> and <code><span class='Value'>[]</span></code> would be complete over non-empty arrays.</p>
+<p>The notation <code><span class='Bracket'>[]</span></code> will be added for high-rank arrays, the same as BQN's lists <code><span class='Bracket'>⟨⟩</span></code> except it mixes at the end. It 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? A more concrete point of awkwardness is that literal notations can only form arrays with rank 1 or more, preventing unit arrays from being destructured. Syntax with <code><span class='Function'>&lt;</span></code> and <code><span class='Bracket'>[]</span></code> would be complete over non-empty arrays.</p>
<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 on that. Kind of awkward, but better than it used to be before one-argument Assert was changed to use <code><span class='Value'>𝕩</span></code> for the message. The issue generally applies to high-quality tools built in BQN, where giving the user good errors is a priority.</p>
<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>
diff --git a/docs/commentary/why.html b/docs/commentary/why.html
index 158dc679..9ab7e0a0 100644
--- a/docs/commentary/why.html
+++ b/docs/commentary/why.html
@@ -14,7 +14,7 @@
<p>BQN is more like APL, but adopts some of the developments made by J as well. However, it's much simpler than both, with fewer and less overloaded primitives as well as less special syntax (J has fewer syntactic rules, but more special cases handled during execution that I think <em>should</em> have been implemented with syntax).</p>
<p>The major differences are listed on <a href="../index.html#whats-the-language-like">the front page</a> (&quot;But it's redesigned…&quot;): <a href="../doc/based.html">based arrays</a>, <a href="../doc/arrayrepr.html">list notation</a>, <a href="../doc/context.html">context-free grammar</a> and <a href="../doc/functional.html">first-class functions</a>, <a href="../doc/primitive.html">reworked primitives</a>, and dedicated <a href="../doc/namespace.html">namespace syntax</a>.</p>
<p>In addition to these, BQN's <a href="../doc/block.html">block system</a> extends APL dfns with headers, adding some very useful functionality: the header specifies block type and argument names, and also allows for simple pattern matching when used with multiple block bodies.</p>
-<p>Since this section gets into the details, it's worth highlighting stranding, a feature I think of as an obvious improvement but that many BQN newcomers see as an obvious sign that I don't know what I'm doing! My full argument for this decision is <a href="../doc/arrayrepr.html#why-not-whitespace">here</a>; the two key points are that stranding is a source of ambiguity that can strike at any time, requiring a correction with <code><span class='Function'>⊢</span></code> or <code><span class='Value'>]</span></code>, and that typing <code><span class='Ligature'>‿</span></code> is really not hard I promise.</p>
+<p>Since this section gets into the details, it's worth highlighting stranding, a feature I think of as an obvious improvement but that many BQN newcomers see as an obvious sign that I don't know what I'm doing! My full argument for this decision is <a href="../doc/arrayrepr.html#why-not-whitespace">here</a>; the two key points are that stranding is a source of ambiguity that can strike at any time, requiring a correction with <code><span class='Function'>⊢</span></code> or <code><span class='Bracket'>]</span></code>, and that typing <code><span class='Ligature'>‿</span></code> is really not hard I promise.</p>
<p>BQN's heavier-weight <code><span class='Bracket'>⟨⟩</span></code> syntax for lists also has its own advantages, because it can be formatted nicely across multiple lines, and also allows functions and modifiers to be used easily as elements. Being able to easily map over a list of functions is surprisingly useful!</p>
<p>BQN has no built-in control structures, which can be quite an adjustment coming from certain styles of APL or J. The <a href="../doc/control.html">control structures</a> page gives some ways to write in a more imperative style, but it's definitely not the same.</p>
<p>Primitives in BQN are pure functions that don't depend on interpreter settings. The following kinds of interpreter state don't apply:</p>
@@ -27,10 +27,10 @@
<h3 id="apl"><a class="header" href="#apl">APL</a></h3>
<p><em>See also the <a href="../doc/fromDyalog.html">BQN-Dyalog APL dictionary</a>. I compare to Dyalog here as it's the most widely used dialect.</em></p>
<p>BQN cleans up some awkward syntax left over from when each APL operator was special: the outer product is written <code><span class='Function'>Fn</span><span class='Modifier'>⌜</span></code> rather than <code><span class='Modifier2'>∘</span><span class='Value'>.fn</span></code>, and reduction <code><span class='Function'>Fn</span><span class='Modifier'>´</span> <span class='Value'>arr</span></code> is separated from compress <code><span class='Value'>b</span><span class='Function'>/</span><span class='Value'>arr</span></code> instead of <a href="https://aplwiki.com/wiki/Function-operator_overloading">overloading</a>.</p>
-<p>BQN adopts <a href="../doc/leading.html">leading axis theory</a> as developed in SHARP APL and applied in A+ and J. With this it can collapse APL pairs such as <code><span class='Function'>⌽</span><span class='Value'>⊖</span></code> and <code><span class='Function'>/</span><span class='Value'>⌿</span></code> to one primitive each, and remove APL's complicated function axis (such as <code><span class='Function'>⌽</span><span class='Value'>[</span><span class='Number'>2</span><span class='Value'>]</span></code>) mechanism. The Rank modifier <code><span class='Modifier2'>⎉</span></code> then applies these primitives to non-leading axes. While this method is required in J and also favored by many users of Dyalog APL, it definitely doesn't enjoy universal support—it can be harder to learn, and less convenient for some common cases. Summing rows with <code><span class='Function'>+/</span></code> in APL is quite convenient, and BQN's <code><span class='Function'>+</span><span class='Modifier'>˝</span><span class='Modifier2'>⎉</span><span class='Number'>1</span></code>, or <code><span class='Function'>+</span><span class='Modifier'>˝˘</span></code> for matrices, just aren't as nice.</p>
+<p>BQN adopts <a href="../doc/leading.html">leading axis theory</a> as developed in SHARP APL and applied in A+ and J. With this it can collapse APL pairs such as <code><span class='Function'>⌽</span><span class='Value'>⊖</span></code> and <code><span class='Function'>/</span><span class='Value'>⌿</span></code> to one primitive each, and remove APL's complicated function axis (such as <code><span class='Function'>⌽</span><span class='Bracket'>[</span><span class='Number'>2</span><span class='Bracket'>]</span></code>) mechanism. The Rank modifier <code><span class='Modifier2'>⎉</span></code> then applies these primitives to non-leading axes. While this method is required in J and also favored by many users of Dyalog APL, it definitely doesn't enjoy universal support—it can be harder to learn, and less convenient for some common cases. Summing rows with <code><span class='Function'>+/</span></code> in APL is quite convenient, and BQN's <code><span class='Function'>+</span><span class='Modifier'>˝</span><span class='Modifier2'>⎉</span><span class='Number'>1</span></code>, or <code><span class='Function'>+</span><span class='Modifier'>˝˘</span></code> for matrices, just aren't as nice.</p>
<p>Arguably BQN cuts down the set of primitives too much. Base conversion <code><span class='Value'>⊥⊤</span></code>, partitioning <code><span class='Value'>⊂⊆</span></code>, and matrix division <code><span class='Value'>⌹</span></code> are commonly asked-for primitives, but they don't match <a href="primitive.html">my conception</a> of a primitive. And while each can be implemented (with short snippets, other than <code><span class='Value'>⌹</span></code> which requires a library), there's definitely a convenience loss. But there's always <a href="../doc/rebqn.html">ReBQN</a>…</p>
<p>BQN's Power modifier <code><span class='Modifier2'>⍟</span></code> allows an array operand to specify multiple results, for example <code><span class='Function'>Fn</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Function'>↕</span><span class='Number'>4</span><span class='Paren'>)</span></code> to get 0 up to 3 iterations. Intermediate results are saved, so the number of calls only depends on the highest iteration number present. On the other hand, BQN has no direct equivalent of Power Limit <code><span class='Value'>⍣</span><span class='Function'>≡</span></code>, requiring it to be <a href="https://mlochbaum.github.io/bqncrate/?q=power%20limit">implemented manually</a>.</p>
-<p>An APL selective assignment <code><span class='Value'>arr[</span><span class='Number'>2</span> <span class='Number'>3</span><span class='Value'>]</span><span class='Function'>+</span><span class='Gets'>←</span><span class='Number'>1</span></code> should usually be written with Under in BQN: <code><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span><span class='Paren'>)</span><span class='Value'>arr</span></code> (but the correspondence might not always be so direct). You can think of this as a very fancy At (<code><span class='String'>@</span></code>) operator, that lets you pull out an arbitrary part of an array.</p>
+<p>An APL selective assignment <code><span class='Value'>arr</span><span class='Bracket'>[</span><span class='Number'>2</span> <span class='Number'>3</span><span class='Bracket'>]</span><span class='Function'>+</span><span class='Gets'>←</span><span class='Number'>1</span></code> should usually be written with Under in BQN: <code><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span><span class='Paren'>)</span><span class='Value'>arr</span></code> (but the correspondence might not always be so direct). You can think of this as a very fancy At (<code><span class='String'>@</span></code>) operator, that lets you pull out an arbitrary part of an array.</p>
<p>Dfns are adjusted in a few ways that make them more useful for general-purpose programming. A BQN block always runs to the last statement, so a block like <code><span class='Brace'>{</span><span class='Function'>Update</span> <span class='Value'>𝕩</span> <span class='Separator'>⋄</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Value'>x</span><span class='Brace'>}</span></code> won't return early. Writing modification with <code><span class='Gets'>↩</span></code> makes it clearer which variable's which. Dfns also do a weird shadowing thing where <code><span class='Value'>a</span><span class='Gets'>←</span><span class='Number'>1</span><span class='Separator'>⋄</span><span class='Value'>a</span><span class='Gets'>←</span><span class='Number'>2</span></code> makes two different variables; in BQN this is an error because the second should use <code><span class='Gets'>↩</span></code>. Tradfns are removed entirely, along with control structures.</p>
<p>BQN doesn't have an exact replacement for dfn guards, although the predicate <code><span class='Head'>?</span></code> can look similar: <code><span class='Brace'>{</span><span class='Number'>2</span><span class='Function'>|</span><span class='Value'>⍵</span> <span class='Head'>:</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×</span><span class='Value'>⍵</span> <span class='Separator'>⋄</span> <span class='Value'>⍵</span><span class='Function'>÷</span><span class='Number'>2</span><span class='Brace'>}</span></code> is equivalent to <code><span class='Brace'>{</span><span class='Number'>2</span><span class='Function'>|</span><span class='Value'>𝕩</span> <span class='Head'>?</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×</span><span class='Value'>𝕩</span> <span class='Head'>;</span> <span class='Value'>𝕩</span><span class='Function'>÷</span><span class='Number'>2</span><span class='Brace'>}</span></code>. But note that where APL uses the statement separator <code><span class='Separator'>⋄</span></code>, BQN uses the body separator <code><span class='Head'>;</span></code>. This means that the if-true branch in BQN can consist of multiple statements (including additional predicates), but also that the if-false branch can't access variables defined in or before the condition. In both cases the &quot;better&quot; behavior can be obtained with an extra set of braces and possibly assigning names to arguments <code><span class='Value'>⍵</span></code>/<code><span class='Value'>𝕩</span></code>. I think guards end up being cleaner when they work, and predicates are more versatile.</p>
<p>BQN's namespaces have a dedicated syntax, are <em>much</em> easier to create than Dyalog namespaces, and have better performance. I use them all the time, and they feel like a natural part of the language.</p>
@@ -46,9 +46,9 @@
<p>But J has its type advantages as well. I miss complex number support in BQN, as it's an optional extension that we haven't yet implemented. And BQN has a hard rule that only one numeric type is exposed to the programmer, which means high-precision integers and rationals aren't allowed at all for a float-based implementation. I think this rule is worth it because J's implicit type conversion is hard to predict and an unexpected numeric type can cause sporadic or subtle program errors.</p>
<p>BQN uses a modifier <code><span class='Modifier2'>⟜</span></code> for J's hook, adding <code><span class='Modifier2'>⊸</span></code> for a reversed version (which I use nearly twice as often). This frees up the 2-train, which is made equivalent to Atop (<code><span class='Modifier2'>∘</span></code>). It's the system Roger Hui came to advocate, since he argued in favor of a hook conjunction <a href="https://code.jsoftware.com/wiki/Essays/Hook_Conjunction%3F">here</a> and made 2-train an Atop when he brought it to Dyalog APL. As an example, the J hook <code><span class='Paren'>(</span><span class='Comment'>#~0&amp;&lt;:)</span></code> to remove negative numbers becomes <code><span class='Number'>0</span><span class='Modifier2'>⊸</span><span class='Function'>≤</span><span class='Modifier2'>⊸</span><span class='Function'>/</span></code> in BQN. Hooks are also the topic of <a href="https://www.arraycast.com/episodes/episode17-tacit4-the-dyadic-hook">Array Cast episode 14</a>, where the panel points out that in J, adding a verb at the far left of a dyadic train changes the rest of the train from dyadic to monadic or vice-versa, an effect that doesn't happen in BQN.</p>
<p>J locales are not first-class values, and BQN namespaces are. I think BQN's namespaces are a lot more convenient to construct, although it is lacking an inheritance mechanism (but J's path system can become confusing quickly). More importantly, BQN namespaces (and closures) are garbage collected. J locales leak unless manually freed by the programmer. More generally, J has no mutable data at all, and to simulate it properly you'd have to write your own tracing garbage collection as the J interpreter doesn't have any. I discussed this issue some in <a href="http://www.jsoftware.com/pipermail/programming/2021-April/058006.html">this J forum thread</a>.</p>
-<p>In J, each function has a built-in rank attribute: for example the ranks of <code><span class='Function'>+</span></code> are <code><span class='Number'>0</span> <span class='Number'>0</span> <span class='Number'>0</span></code>. This rank is accessed by the &quot;close&quot; compositions <code><span class='String'>@</span></code>, <code><span class='Value'>&amp;</span></code>, and <code><span class='Value'>&amp;.</span></code>. Choosing the shorter form for the close compositions—for example <code><span class='String'>@</span></code> rather than <code><span class='String'>@</span><span class='Head'>:</span></code>—is often considered a mistake within the J community. And function ranks are unreliable: consider that the ranks of <code><span class='Value'>]</span><span class='String'>@</span><span class='Head'>:</span><span class='Function'>+</span></code>, a function that always has the same result as <code><span class='Function'>+</span></code>, are <code><span class='Modifier2'>_</span> <span class='Modifier2'>_</span> <span class='Modifier2'>_</span></code>. In BQN there aren't any close compositions at all, and no function ranks. J's <code><span class='Value'>&amp;.</span><span class='Function'>&gt;</span></code> is simply <code><span class='Modifier'>¨</span></code>, and other close compositions, in my opinion, just aren't needed.</p>
+<p>In J, each function has a built-in rank attribute: for example the ranks of <code><span class='Function'>+</span></code> are <code><span class='Number'>0</span> <span class='Number'>0</span> <span class='Number'>0</span></code>. This rank is accessed by the &quot;close&quot; compositions <code><span class='String'>@</span></code>, <code><span class='Value'>&amp;</span></code>, and <code><span class='Value'>&amp;.</span></code>. Choosing the shorter form for the close compositions—for example <code><span class='String'>@</span></code> rather than <code><span class='String'>@</span><span class='Head'>:</span></code>—is often considered a mistake within the J community. And function ranks are unreliable: consider that the ranks of <code><span class='Bracket'>]</span><span class='String'>@</span><span class='Head'>:</span><span class='Function'>+</span></code>, a function that always has the same result as <code><span class='Function'>+</span></code>, are <code><span class='Modifier2'>_</span> <span class='Modifier2'>_</span> <span class='Modifier2'>_</span></code>. In BQN there aren't any close compositions at all, and no function ranks. J's <code><span class='Value'>&amp;.</span><span class='Function'>&gt;</span></code> is simply <code><span class='Modifier'>¨</span></code>, and other close compositions, in my opinion, just aren't needed.</p>
<p>J has several adverbs (key, prefix, infix, outfix…) to slice up an argument in various ways and apply a verb to those parts. In BQN, I rejected this approach: there are 1-modifiers for basic iteration patterns, and functions such as <a href="../doc/group.html">Group</a> (<code><span class='Function'>⊔</span></code>) that do the slicing but don't apply anything. So <code><span class='Function'>&lt;/</span><span class='Value'>.~a</span></code> is <code><span class='Function'>⊐</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span><span class='Value'>a</span></code>, but <code><span class='Value'>fn</span><span class='Function'>/</span><span class='Value'>.~a</span></code> is <code><span class='Function'>&gt;Fn</span><span class='Modifier'>¨</span><span class='Function'>⊐</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span><span class='Value'>a</span></code> (I also reject J's implicit merge except for the Rank modifier, as I don't think function results should be homogeneous by default). BQN's approach composes better, and is more predictable from a performance perspective.</p>
-<p>Gerunds are J's answer to BQN's first-class functions. For example J's <code><span class='Paren'>(</span><span class='Value'>%&amp;</span><span class='Number'>2</span><span class='Paren'>)</span><span class='Modifier'>`</span><span class='Paren'>(</span><span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Value'>*]</span><span class='Paren'>)</span><span class='String'>@</span><span class='Value'>.</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Value'>&amp;</span><span class='Function'>|</span><span class='Paren'>)</span></code> would be written <code><span class='Number'>2</span><span class='Modifier2'>⊸</span><span class='Function'>|</span><span class='Modifier2'>◶</span><span class='Bracket'>⟨</span><span class='Function'>÷</span><span class='Modifier2'>⟜</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×⊢</span><span class='Bracket'>⟩</span></code> with a list of functions. I think lists of functions are a big improvement, since there's no need to convert between gerund and function, and no worries about arrays that just happen to be valid gerunds (worried about losing the ability to construct gerunds? Constructing tacit functions in BQN is much easier). The usability gap widens because passing J functions around either as values or gerunds has presents some highly idiosyncratic challenges, discussed below.</p>
+<p>Gerunds are J's answer to BQN's first-class functions. For example J's <code><span class='Paren'>(</span><span class='Value'>%&amp;</span><span class='Number'>2</span><span class='Paren'>)</span><span class='Modifier'>`</span><span class='Paren'>(</span><span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Value'>*</span><span class='Bracket'>]</span><span class='Paren'>)</span><span class='String'>@</span><span class='Value'>.</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Value'>&amp;</span><span class='Function'>|</span><span class='Paren'>)</span></code> would be written <code><span class='Number'>2</span><span class='Modifier2'>⊸</span><span class='Function'>|</span><span class='Modifier2'>◶</span><span class='Bracket'>⟨</span><span class='Function'>÷</span><span class='Modifier2'>⟜</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×⊢</span><span class='Bracket'>⟩</span></code> with a list of functions. I think lists of functions are a big improvement, since there's no need to convert between gerund and function, and no worries about arrays that just happen to be valid gerunds (worried about losing the ability to construct gerunds? Constructing tacit functions in BQN is much easier). The usability gap widens because passing J functions around either as values or gerunds has presents some highly idiosyncratic challenges, discussed below.</p>
<h4 id="named-functions"><a class="header" href="#named-functions">Named functions</a></h4>
<p>Its impact on the programmer is smaller than a lot of the issues above, but this section describes a behavior that I find pretty hard to justify. What does the identifier <code><span class='Value'>fn</span></code> indicate in a J expression? The value of <code><span class='Value'>fn</span></code> in the current scope, one might suppose. Nope—only if the value is a noun. Let's make it a function.</p>
<pre> <span class='Value'>fn</span> <span class='Function'>=</span><span class='Head'>:</span> <span class='Function'>-</span>
diff --git a/docs/doc/array.html b/docs/doc/array.html
index ec4eab33..827f05c0 100644
--- a/docs/doc/array.html
+++ b/docs/doc/array.html
@@ -6,7 +6,7 @@
<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"><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>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='Bracket'>[]</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>
<p>An array might also have a <a href="fill.html">fill element</a> that captures some structural information about its elements and is used by a few operations. The fill, as an inferred property, isn't considered to truly be part of the array but is instead some information about the array that the interpreter keeps track of. So it's out of scope here.</p>
<svg viewBox='-36 -15 544 426'>
diff --git a/docs/doc/arrayrepr.html b/docs/doc/arrayrepr.html
index 0e59315a..ce74c543 100644
--- a/docs/doc/arrayrepr.html
+++ b/docs/doc/arrayrepr.html
@@ -229,4 +229,4 @@
0 5
</pre>
-<p>The characters <code><span class='Value'>[]</span></code> are reserved to potentially combine list notation with merging, allowing the above to be written <code><span class='Value'>[</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Separator'>,</span> <span class='Number'>4</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'>5</span><span class='Value'>]</span></code>. This would allow non-empty arrays with rank one or more to be written without a primitive, but not rank 0 or empty arrays. Since creating arrays in general would still require primitives like <code><span class='Function'>&lt;</span></code> or <code><span class='Function'>⥊</span></code>, it's not clear whether this notation is worth it. General array notation is a surprisingly complicated topic; see the article about it <a href="https://aplwiki.com/wiki/Array_notation">on the APL Wiki</a>.</p>
+<p>The characters <code><span class='Bracket'>[]</span></code> are reserved to potentially combine list notation with merging, allowing the above to be written <code><span class='Bracket'>[</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Separator'>,</span> <span class='Number'>4</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'>5</span><span class='Bracket'>]</span></code>. This would allow non-empty arrays with rank one or more to be written without a primitive, but not rank 0 or empty arrays. Since creating arrays in general would still require primitives like <code><span class='Function'>&lt;</span></code> or <code><span class='Function'>⥊</span></code>, it's not clear whether this notation is worth it. General array notation is a surprisingly complicated topic; see the article about it <a href="https://aplwiki.com/wiki/Array_notation">on the APL Wiki</a>.</p>
diff --git a/docs/doc/based.html b/docs/doc/based.html
index 7974f1d5..f03adf29 100644
--- a/docs/doc/based.html
+++ b/docs/doc/based.html
@@ -43,10 +43,10 @@
<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"><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>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='Bracket'>[</span><span class='Number'>2</span><span class='Bracket'>]</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='Bracket'>[</span><span class='Number'>2</span><span class='Bracket'>]</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"><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>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='Bracket'>[</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/embed.html b/docs/doc/embed.html
index b02342cc..b911046d 100644
--- a/docs/doc/embed.html
+++ b/docs/doc/embed.html
@@ -16,13 +16,13 @@
<span class='Value'>i</span><span class='Gets'>←</span><span class='Number'>4</span><span class='Function'>⥊</span><span class='Number'>0</span>
<span class='Brace'>{</span><span class='Value'>i</span><span class='Function'>+</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Function'>»</span><span class='Value'>i</span><span class='Brace'>}</span>
<span class='Modifier'>`</span><span class='Paren'>)</span><span class='Head'>;</span>
-<span class='Value'>push</span><span class='Paren'>(</span><span class='Number'>3</span><span class='Paren'>)</span><span class='Head'>;</span> <span class='Function'>//</span> <span class='Value'>[</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Value'>]</span>
-<span class='Value'>push</span><span class='Paren'>(</span><span class='Function'>-</span><span class='Number'>2</span><span class='Paren'>)</span><span class='Head'>;</span> <span class='Function'>//</span> <span class='Value'>[</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Value'>]</span>
-<span class='Value'>push</span><span class='Paren'>(</span><span class='Number'>4</span><span class='Paren'>)</span><span class='Head'>;</span> <span class='Function'>//</span> <span class='Value'>[</span><span class='Number'>5</span><span class='Separator'>,</span><span class='Number'>4</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Value'>]</span>
+<span class='Value'>push</span><span class='Paren'>(</span><span class='Number'>3</span><span class='Paren'>)</span><span class='Head'>;</span> <span class='Function'>//</span> <span class='Bracket'>[</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Bracket'>]</span>
+<span class='Value'>push</span><span class='Paren'>(</span><span class='Function'>-</span><span class='Number'>2</span><span class='Paren'>)</span><span class='Head'>;</span> <span class='Function'>//</span> <span class='Bracket'>[</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Bracket'>]</span>
+<span class='Value'>push</span><span class='Paren'>(</span><span class='Number'>4</span><span class='Paren'>)</span><span class='Head'>;</span> <span class='Function'>//</span> <span class='Bracket'>[</span><span class='Number'>5</span><span class='Separator'>,</span><span class='Number'>4</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Bracket'>]</span>
</pre>
<p>Note that this program doesn't have any outer braces. It's only run once, and it initializes <code><span class='Value'>i</span></code> and returns a function. Just putting braces around it wouldn't have any effect—it just changes it from a program that does something to a program that runs a block that does the same thing—but adding braces and using <code><span class='Value'>𝕨</span></code> or <code><span class='Value'>𝕩</span></code> inside them would turn it into a function that could be run multiple times to create different closures. For example, <code><span class='Value'>pushGen</span> <span class='Function'>=</span> <span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>&quot;{i←4⥊𝕩⋄{i+↩𝕩»i}}&quot;</span><span class='Paren'>)</span></code> causes <code><span class='Value'>pushGen</span><span class='Paren'>(</span><span class='Value'>n</span><span class='Paren'>)</span></code> to create a new closure with <code><span class='Value'>i</span></code> initialized to <code><span class='Number'>4</span><span class='Function'>⥊</span><span class='Value'>n</span></code>.</p>
<p>The program also returns only one function, which can be limiting. But it's possible to get multiple closures out of the same program by returning a list of functions. For example, the following program defines three functions that manipulate a shared array in different ways.</p>
-<pre><span class='Value'>let</span> <span class='Value'>[rotx</span><span class='Separator'>,</span> <span class='Value'>roty</span><span class='Separator'>,</span> <span class='Value'>flip]</span> <span class='Function'>=</span> <span class='Value'>bqn</span><span class='Paren'>(</span><span class='Modifier'>`</span>
+<pre><span class='Value'>let</span> <span class='Bracket'>[</span><span class='Value'>rotx</span><span class='Separator'>,</span> <span class='Value'>roty</span><span class='Separator'>,</span> <span class='Value'>flip</span><span class='Bracket'>]</span> <span class='Function'>=</span> <span class='Value'>bqn</span><span class='Paren'>(</span><span class='Modifier'>`</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='Number'>6</span>
<span class='Function'>RotX</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>a</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Function'>⌽</span><span class='Modifier'>˘</span><span class='Value'>a</span><span class='Brace'>}</span>
<span class='Function'>RotY</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>a</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Function'>⌽</span><span class='Value'>a</span><span class='Brace'>}</span>
@@ -35,7 +35,7 @@
<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>There are two utilities for converting from JS to BQN data: <code><span class='Value'>list</span><span class='Paren'>(</span><span class='Bracket'>[</span><span class='Value'>…</span><span class='Bracket'>]</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"><a class="header" href="#other-functionality">Other functionality</a></h2>
diff --git a/docs/doc/fromDyalog.html b/docs/doc/fromDyalog.html
index 1f256416..ea036ec9 100644
--- a/docs/doc/fromDyalog.html
+++ b/docs/doc/fromDyalog.html
@@ -133,8 +133,8 @@
<td align="center">Monad</td>
<td align="center"><code><span class='Value'>*</span></code></td>
<td align="center"><code><span class='Value'>*</span><span class='Modifier2'>∘</span><span class='Paren'>(</span><span class='Function'>÷</span><span class='Number'>2</span><span class='Paren'>)</span></code></td>
-<td align="center"><code><span class='Value'>[</span><span class='Function'>⍋</span><span class='Value'>]</span></code></td>
-<td align="center"><code><span class='Value'>[</span><span class='Function'>⍒</span><span class='Value'>]</span></code></td>
+<td align="center"><code><span class='Bracket'>[</span><span class='Function'>⍋</span><span class='Bracket'>]</span></code></td>
+<td align="center"><code><span class='Bracket'>[</span><span class='Function'>⍒</span><span class='Bracket'>]</span></code></td>
<td align="center"><code><span class='Value'>~</span></code></td>
<td align="center"><code><span class='Function'>≢</span><span class='Value'>⍤⍴</span></code></td>
<td align="center"><code><span class='Function'>≢</span></code></td>
diff --git a/docs/doc/fromJ.html b/docs/doc/fromJ.html
index 524ec8d3..338a17d5 100644
--- a/docs/doc/fromJ.html
+++ b/docs/doc/fromJ.html
@@ -96,7 +96,7 @@
<td></td>
</tr>
<tr>
-<td><code><span class='Value'>[</span><span class='Head'>:</span></code></td>
+<td><code><span class='Bracket'>[</span><span class='Head'>:</span></code></td>
<td><code><span class='Nothing'>·</span></code></td>
<td>Cap</td>
</tr>
@@ -138,8 +138,8 @@
<td align="center"><code><span class='Function'>&gt;</span><span class='Value'>.</span></code></td>
<td align="center"><code><span class='Function'>&lt;</span><span class='Head'>:</span></code></td>
<td align="center"><code><span class='Function'>&gt;</span><span class='Head'>:</span></code></td>
-<td align="center"><code><span class='Value'>[</span></code></td>
-<td align="center"><code><span class='Value'>]</span></code></td>
+<td align="center"><code><span class='Bracket'>[</span></code></td>
+<td align="center"><code><span class='Bracket'>]</span></code></td>
</tr>
</tbody>
</table>
@@ -231,7 +231,7 @@
<td align="center">Dyad</td>
<td align="center"><code><span class='Brace'>{</span><span class='Value'>.</span></code></td>
<td align="center"><code><span class='Brace'>}</span><span class='Value'>.</span></code></td>
-<td align="center"><code><span class='Value'>]\</span></code></td>
+<td align="center"><code><span class='Bracket'>]</span><span class='Value'>\</span></code></td>
<td align="center"><code><span class='Comment'>#@]{.,</span></code></td>
<td align="center"><code><span class='Function'>-</span><span class='String'>@</span><span class='Comment'>#@]{.,~</span></code></td>
<td align="center"><code><span class='Comment'>#</span></code></td>
@@ -375,8 +375,8 @@
<th align="center"><code><span class='Value'>%</span><span class='Head'>:</span></code></th>
<th align="center"><code><span class='Function'>&lt;</span><span class='Value'>.</span></code></th>
<th align="center"><code><span class='Function'>&gt;</span><span class='Value'>.</span></code></th>
-<th align="center"><code><span class='Value'>[</span></code></th>
-<th align="center"><code><span class='Value'>]</span></code></th>
+<th align="center"><code><span class='Bracket'>[</span></code></th>
+<th align="center"><code><span class='Bracket'>]</span></code></th>
<th align="center"><code><span class='Function'>|</span><span class='Value'>.</span></code></th>
<th align="center"><code><span class='Function'>|</span><span class='Head'>:</span></code></th>
</tr>
diff --git a/docs/implementation/kclaims.html b/docs/implementation/kclaims.html
index c92318c3..670187b3 100644
--- a/docs/implementation/kclaims.html
+++ b/docs/implementation/kclaims.html
@@ -38,7 +38,7 @@
</pre>
<p><code><span class='Value'>cycles</span></code> is the total number of CPU cycles run. <code><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></code> shows L1 data cache misses and <code><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></code> shows the instruction cache misses; <code><span class='Value'>cache</span><span class='Function'>-</span><span class='Value'>misses</span></code> shows accesses that miss every layer of caching, which is a subset of those two (more detailed explanation <a href="https://stackoverflow.com/questions/55035313/how-does-linux-perf-calculate-the-cache-references-and-cache-misses-events">here</a>). <code><span class='Value'>icache_16b.ifdata_stall</span></code> is a little fancy. Here's the summary given by <code><span class='Value'>perf</span> <span class='Value'>list</span></code>:</p>
<pre> <span class='Value'>icache_16b.ifdata_stall</span>
- <span class='Value'>[</span><span class='Function'>Cycles</span> <span class='Value'>where</span> <span class='Value'>a</span> <span class='Value'>code</span> <span class='Value'>fetch</span> <span class='Value'>is</span> <span class='Value'>stalled</span> <span class='Value'>due</span> <span class='Value'>to</span> <span class='Function'>L1</span> <span class='Value'>instruction</span> <span class='Value'>cache</span> <span class='Value'>miss]</span>
+ <span class='Bracket'>[</span><span class='Function'>Cycles</span> <span class='Value'>where</span> <span class='Value'>a</span> <span class='Value'>code</span> <span class='Value'>fetch</span> <span class='Value'>is</span> <span class='Value'>stalled</span> <span class='Value'>due</span> <span class='Value'>to</span> <span class='Function'>L1</span> <span class='Value'>instruction</span> <span class='Value'>cache</span> <span class='Value'>miss</span><span class='Bracket'>]</span>
</pre>
<p>That's just the whole cost (in cycles) of L1 misses, exactly what we want! First I'll run this on a J program I have lying around, building my old <a href="https://cdr.lib.unc.edu/concern/honors_theses/pg15bk00p">Honors thesis</a> with <a href="https://github.com/mlochbaum/JtoLaTeX">JtoLaTeX</a>.</p>
<pre> <span class='Function'>Performance</span> <span class='Value'>counter</span> <span class='Value'>stats</span> <span class='Value'>for</span> <span class='String'>'</span><span class='Value'>jlatex</span> <span class='Value'>document.jtex</span> <span class='Value'>nopdf</span><span class='String'>'</span><span class='Head'>:</span>
@@ -73,7 +73,7 @@
<span class='Number'>2.138414849</span> <span class='Value'>seconds</span> <span class='Value'>time</span> <span class='Value'>elapsed</span>
</pre>
<p>And the Python-based font tool I use to build <a href="https://mlochbaum.github.io/BQN/fonts.html">font samples</a> for this site:</p>
-<pre> <span class='Function'>Performance</span> <span class='Value'>counter</span> <span class='Value'>stats</span> <span class='Value'>for</span> <span class='String'>'</span><span class='Value'>pyftsubset</span> <span class='Value'>[…more</span> <span class='Value'>stuff]</span><span class='String'>'</span><span class='Head'>:</span>
+<pre> <span class='Function'>Performance</span> <span class='Value'>counter</span> <span class='Value'>stats</span> <span class='Value'>for</span> <span class='String'>'</span><span class='Value'>pyftsubset</span> <span class='Bracket'>[</span><span class='Value'>…more</span> <span class='Value'>stuff</span><span class='Bracket'>]</span><span class='String'>'</span><span class='Head'>:</span>
<span class='Number'>499</span><span class='Separator'>,</span><span class='Number'>025</span><span class='Separator'>,</span><span class='Number'>775</span> <span class='Value'>cycles</span><span class='Head'>:</span><span class='Value'>u</span>
<span class='Number'>24</span><span class='Separator'>,</span><span class='Number'>869</span><span class='Separator'>,</span><span class='Number'>974</span> <span class='Value'>icache_16b.ifdata_stall</span><span class='Head'>:</span><span class='Value'>u</span>
diff --git a/docs/implementation/vm.html b/docs/implementation/vm.html
index ba96ac12..7a0093db 100644
--- a/docs/implementation/vm.html
+++ b/docs/implementation/vm.html
@@ -43,7 +43,7 @@
<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"><a class="header" href="#instructions">Instructions</a></h3>
-<p>The following instructions are defined (those without names are tentatively reserved only). The ones emitted by the self-hosted BQN compiler are marked in the &quot;used&quot; column. Only those marked &quot;X&quot; are needed to support the compiler and self-hosted runtime. &quot;NS&quot; indicates instructions used only in programs with namespaces, &quot;HE&quot; is for headers <code><span class='Head'>:</span></code> or predicates <code><span class='Head'>?</span></code>, and &quot;HR&quot; is for high-rank array notation <code><span class='Value'>[]</span></code>.</p>
+<p>The following instructions are defined (those without names are tentatively reserved only). The ones emitted by the self-hosted BQN compiler are marked in the &quot;used&quot; column. Only those marked &quot;X&quot; are needed to support the compiler and self-hosted runtime. &quot;NS&quot; indicates instructions used only in programs with namespaces, &quot;HE&quot; is for headers <code><span class='Head'>:</span></code> or predicates <code><span class='Head'>?</span></code>, and &quot;HR&quot; is for high-rank array notation <code><span class='Bracket'>[]</span></code>.</p>
<table>
<thead>
<tr>
@@ -134,7 +134,7 @@
<td align="center">HR</td>
<td align="right"></td>
<td align="left"></td>
-<td>Merge top of stack (for <code><span class='Value'>[]</span></code>)</td>
+<td>Merge top of stack (for <code><span class='Bracket'>[]</span></code>)</td>
</tr>
<tr>
<td align="right">10</td>
diff --git a/docs/spec/system.html b/docs/spec/system.html
index 4fe4dd89..67af11c2 100644
--- a/docs/spec/system.html
+++ b/docs/spec/system.html
@@ -447,7 +447,7 @@
<p>Beginning with the type declarations themselves, a <strong>number</strong> such as <code><span class='Value'>f32</span></code> corresponds to a C type with the given quality (<code><span class='Value'>i</span></code> for signed integer, <code><span class='Value'>u</span></code> for unsigned, <code><span class='Value'>f</span></code> for floating-point) and width in bits. The corresponding BQN value is a number, and should be converted exactly for integers and with rounding for decreasing-type conversions. For conversions to or from an integer type, attempting to convert a value to a type that can't contain it, or one outside of the exactly representable integer range (<code><span class='Function'>-</span><span class='Number'>2</span><span class='Function'>⋆</span><span class='Number'>53</span></code> to <code><span class='Number'>2</span><span class='Function'>⋆</span><span class='Number'>53</span></code> for IEEE doubles), results in an error.</p>
<p>A <strong>pointer</strong> such as <code><span class='Value'>*u8</span></code> comes from a BQN list. If the symbol <code><span class='Value'>&amp;</span></code> is used rather than <code><span class='Value'>*</span></code>, the pointer is called <strong>mutable</strong> and its contents after the function call completes are also returned as an element of the result. If there is any mutable pointer, the result is a list, unless the result type is <code><span class='String'>&quot;&amp;&quot;</span></code>, in which case there must be exactly one mutable pointer and the result is its value alone. These prefixes can only be used in arguments, meaning that a BQN value is provided, and this value determines the length of both the input and the mutable result.</p>
<p>The letter <code><span class='Value'>a</span></code> indicates that a <strong>BQN value</strong> is to be passed directly, interpreted in whatever way makes sense for the implementation. A plain <code><span class='Value'>*</span></code> indicates an <strong>opaque pointer</strong>, to be mapped to a BQN value of namespace type. The behavior of this value is not yet specified. The <strong>array</strong> and <strong>struct</strong> types indicate C structs and arrays, and correspond to BQN lists.</p>
-<p>The <code><span class='Value'>bqn</span></code> value in a <code><span class='Value'>conv</span></code> term indicates a BQN element type to be used. It can be appear after the whole type, or any member of a struct, and applies to the final component (that is, <code><span class='Value'>type</span></code> term) of the type <em>and</em> one preceding <code><span class='Value'>*</span></code>, <code><span class='Value'>&amp;</span></code>, or <code><span class='Value'>[n]</span></code> if present (if a type ends in <code><span class='Value'>**</span></code>, it applies to both <code><span class='Value'>*</span></code>s). This portion of the type corresponds to a BQN list of the given element type, interpreted much like <a href="#bitwise-operations">bitwise</a> conversion <code><span class='Value'>•bit.</span><span class='Modifier'>_cast</span></code>. The C type is treated as pure data, a stream of bits. For a prefix <code><span class='Value'>*</span></code> or <code><span class='Value'>&amp;</span></code>, the data in question is the region of memory pointed to.</p>
+<p>The <code><span class='Value'>bqn</span></code> value in a <code><span class='Value'>conv</span></code> term indicates a BQN element type to be used. It can be appear after the whole type, or any member of a struct, and applies to the final component (that is, <code><span class='Value'>type</span></code> term) of the type <em>and</em> one preceding <code><span class='Value'>*</span></code>, <code><span class='Value'>&amp;</span></code>, or <code><span class='Bracket'>[</span><span class='Value'>n</span><span class='Bracket'>]</span></code> if present (if a type ends in <code><span class='Value'>**</span></code>, it applies to both <code><span class='Value'>*</span></code>s). This portion of the type corresponds to a BQN list of the given element type, interpreted much like <a href="#bitwise-operations">bitwise</a> conversion <code><span class='Value'>•bit.</span><span class='Modifier'>_cast</span></code>. The C type is treated as pure data, a stream of bits. For a prefix <code><span class='Value'>*</span></code> or <code><span class='Value'>&amp;</span></code>, the data in question is the region of memory pointed to.</p>
<h2 id="operation-properties"><a class="header" href="#operation-properties">Operation properties</a></h2>
<table>
<thead>
diff --git a/docs/tutorial/variable.html b/docs/tutorial/variable.html
index df0d7c74..1bb916ac 100644
--- a/docs/tutorial/variable.html
+++ b/docs/tutorial/variable.html
@@ -223,7 +223,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=OOKMvuKKkSAiQlFOIiAgICAgICAgIyBDaGFuZ2UgdGhlIGZpcnN0IGVsZW1lbnQgdG8gOA==">↗️</a><pre> <span class='Number'>8</span><span class='Modifier2'>⌾</span><span class='Function'>⊑</span> <span class='String'>&quot;BQN&quot;</span> <span class='Comment'># Change the first element to 8
</span>⟨ 8 'Q' 'N' ⟩
</pre>
-<p>BQN doesn't have a dedicated syntax such as <code><span class='Value'>list[index]</span></code> to select from a list, because a function is more consistent with the rest of BQN's notation and can be manipulated more easily. This decision has already been useful to us, because Under's right operand is a function! With a special notation we'd have to first &quot;package&quot; index selection into a function to use it.</p>
+<p>BQN doesn't have a dedicated syntax such as <code><span class='Value'>list</span><span class='Bracket'>[</span><span class='Value'>index</span><span class='Bracket'>]</span></code> to select from a list, because a function is more consistent with the rest of BQN's notation and can be manipulated more easily. This decision has already been useful to us, because Under's right operand is a function! With a special notation we'd have to first &quot;package&quot; index selection into a function to use it.</p>
<table class='primitives'>
<tr>
<td><span class='Function'>↑</span></td>