aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/commentary/history.html2
-rw-r--r--docs/commentary/problems.html175
-rw-r--r--docs/doc/based.html2
-rw-r--r--docs/doc/context.html2
-rw-r--r--docs/doc/functional.html2
-rw-r--r--docs/doc/prefixes.html2
-rw-r--r--docs/doc/train.html2
-rw-r--r--docs/problems.html181
8 files changed, 189 insertions, 179 deletions
diff --git a/docs/commentary/history.html b/docs/commentary/history.html
index bb011f9d..50224618 100644
--- a/docs/commentary/history.html
+++ b/docs/commentary/history.html
@@ -212,6 +212,6 @@
<h4 id="group">Group</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>
-<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. But the model for Before and After was initially APL's Compose (∘) 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>
+<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. But the model for Before and After was initially APL's Compose (∘) 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>
<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/problems.html b/docs/commentary/problems.html
new file mode 100644
index 00000000..f74aabde
--- /dev/null
+++ b/docs/commentary/problems.html
@@ -0,0 +1,175 @@
+<head>
+ <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/>
+ <link href="../style.css" rel="stylesheet"/>
+ <title>Problems with BQN</title>
+</head>
+<div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a> / <a href="../index.html">main</a> / <a href="index.html">commentary</a></div>
+<h1 id="problems-with-bqn">Problems with BQN</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>
+<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>
+<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>
+<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="tacit-and-one-line-functions-are-hard-to-debug">Tacit and one-line functions are hard to debug</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="search-function-depth">Search function depth</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="trigonometry">Trigonometry</h3>
+<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="right-to-left-multi-line-functions-go-upwards">Right-to-left multi-line functions go upwards</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="control-flow-substitutes-have-awkward-syntax">Control flow substitutes have awkward syntax</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>
+<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>
+<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>
+<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="syntactic-type-erasure">Syntactic type erasure</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="nothing--interacts-strangely-with-before-and-after">Nothing (<code><span class='Nothing'>·</span></code>) interacts strangely with Before and After</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>
+<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>
+<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>
+<tr>
+<th>Definitely</th>
+<th>Maybe</th>
+<th>Definitely not</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code><span class='Function'>=≠≤≥&lt;&gt;</span></code></td>
+<td><code><span class='Function'>≡≢⊐⊒∊⍷|</span></code></td>
+<td><code><span class='Function'>⍋⍒</span></code></td>
+</tr>
+</tbody>
+</table>
+<h3 id="no-access-to-fast-high-precision-sum">No access to fast high-precision sum</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>
+<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>
+<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>
+<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="poor-font-support-">Poor font support</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>
+<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>
+<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>
+<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="group-doesnt-include-trailing-empty-groups">Group doesn't include trailing empty groups</h3>
+<p>But there are workarounds, described in <a href="../doc/group.html">its documentation</a>. dzaima has suggested allowing a single extra element in the index argument to specify the result shape. Another possibility is for the result prototype to be specified to allow overtaking.</p>
+<h3 id="underbind-combination-is-awkward">Under/bind combination is awkward</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>
+<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="trains-dont-like-monads">Trains don't like monads</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="inverse-is-not-fully-specified">Inverse is not fully specified</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="prefixessuffixes-add-depth-and-windows-doesnt">Prefixes/Suffixes add depth and Windows doesn't</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>
+<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, 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>
+<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="rankdepth-negative-zero">Rank/Depth negative zero</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>
+<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>
+<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="each-block-body-has-its-own-label">Each block body has its own label</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>
+<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>
+<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>
+<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>
+<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>
+<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>
+<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>
+<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>
+<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>
+<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>
+<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.</p>
+<h3 id="scan-ordering-is-weird">Scan ordering is weird</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>
+<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>
+<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>
+<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>
+<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>
+<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>
+<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>
+<p>Blanket issue for names that I don't find informative: &quot;Solo&quot;, &quot;Bins&quot;, &quot;Unique Mask&quot;, &quot;Find&quot;, and &quot;Group&quot;.</p>
+<h3 id="strands-go-left-to-right">Strands go left to right</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="should-have-a-rounding-function">Should have a rounding function</h3>
+<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="primitive-name-capitalization">Primitive name capitalization</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>
+<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="array-reductions-are-annoying">Array reductions are annoying</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>
+<li><code><span class='Function'>𝔽</span><span class='Modifier'>˝</span></code> Apply it between major cells of an array (SHARP).</li>
+<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>
+<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>
+<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>
+<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>
+<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>. However, it doesn't partition along multiple axes, so a dedicated partition function that does this could also be wanted. Or could Group be made to work with multiple axes as well as multidimensional indices?</p>
+<h3 id="key-doesnt-do-what-you-want">Key doesn't do what you want</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>
+<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>
+<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>
+<p>Fixed by allowing a variable to be written with a different syntactic class 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>
+<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>
+<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>
+<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>
+<p>Fixed with Prefix, Suffix, and Infix operators in J. Changed to functions in BQN.</p>
diff --git a/docs/doc/based.html b/docs/doc/based.html
index e070bb94..ced213c8 100644
--- a/docs/doc/based.html
+++ b/docs/doc/based.html
@@ -44,7 +44,7 @@
<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="../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>
+<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>
<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>
diff --git a/docs/doc/context.html b/docs/doc/context.html
index 1b5e949c..8c0ea92e 100644
--- a/docs/doc/context.html
+++ b/docs/doc/context.html
@@ -17,7 +17,7 @@
</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>
-<p>Yes, in the sense of <a href="../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>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>
diff --git a/docs/doc/functional.html b/docs/doc/functional.html
index 4a5b7495..7e3b3900 100644
--- a/docs/doc/functional.html
+++ b/docs/doc/functional.html
@@ -63,7 +63,7 @@
<p>Another topic we are interested in is <em>lexical scoping</em> and <em>closures</em>. Lexical scoping 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>
<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. However, it's worth noting that 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="../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>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>
<p><em>Reminder: I am discussing only first-class functional programming here, and not other concepts like pure or typed functional programming!</em></p>
diff --git a/docs/doc/prefixes.html b/docs/doc/prefixes.html
index 37bda297..9ef7cbdd 100644
--- a/docs/doc/prefixes.html
+++ b/docs/doc/prefixes.html
@@ -167,7 +167,7 @@
┘ ┘ ┘
</pre>
-<p>But Prefixes and Suffixes <a href="../problems.html#cant-take-prefixes-or-suffixes-on-multiple-axes">don't have</a> any way to specify that they should work on multiple axes, and always work on exactly one. So to extend this pattern we will have to define multi-dimensional versions. This turns out to be very easy: just replace Length with Shape in the <a href="#definition">definitions</a> above.</p>
+<p>But Prefixes and Suffixes <a href="../commentary/problems.html#cant-take-prefixes-or-suffixes-on-multiple-axes">don't have</a> any way to specify that they should work on multiple axes, and always work on exactly one. So to extend this pattern we will have to define multi-dimensional versions. This turns out to be very easy: just replace Length with Shape in the <a href="#definition">definitions</a> above.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=UHJlZnMg4oaQICjihpUxK+KJoinihpHCqDwKU3VmZnMg4oaQICjihpUxK+KJoinihpPCqDwKUHJlZnPCqFN1ZmZzIDPigL8y4qWKImFiY2RlZiI=">↗️</a><pre> <span class='Function'>Prefs</span> <span class='Gets'>←</span> <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>
<span class='Function'>Suffs</span> <span class='Gets'>←</span> <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>
<span class='Function'>Prefs</span><span class='Modifier'>¨</span><span class='Function'>Suffs</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>
diff --git a/docs/doc/train.html b/docs/doc/train.html
index d4eff715..4ae23b13 100644
--- a/docs/doc/train.html
+++ b/docs/doc/train.html
@@ -89,7 +89,7 @@
⟨ 0 2 3 4 ⟩
</pre>
<p>These two forms have a different emphasis, because the first breaks into subfunctions <code><span class='Function'>⍷</span><span class='Modifier2'>∘</span><span class='Function'>∧</span></code> and <code><span class='Function'>|</span></code> and the second into <code><span class='Function'>⍷</span></code> and <code><span class='Function'>∧|</span></code>. It's more common to use <code><span class='Function'>⍷</span><span class='Modifier2'>∘</span><span class='Function'>∧</span></code> as a unit than <code><span class='Function'>∧|</span></code>, so in this case <code><span class='Function'>⍷</span><span class='Modifier2'>∘</span><span class='Function'>∧|</span></code> is probably the better train.</p>
-<p>Many one-argument functions strung together is <a href="../problems.html#trains-dont-like-monads">a major weakness</a> for train syntax. If there are many such functions it's probably best to stick with a block function instead!</p>
+<p>Many one-argument functions strung together is <a href="../commentary/problems.html#trains-dont-like-monads">a major weakness</a> for train syntax. If there are many such functions it's probably best to stick with a block function instead!</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=e+KNt+KIp3zwnZWpfSAz4oC/NOKAv8KvM+KAv8KvMuKAvzA=">↗️</a><pre> <span class='Brace'>{</span><span class='Function'>⍷∧|</span><span class='Value'>𝕩</span><span class='Brace'>}</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>
⟨ 0 2 3 4 ⟩
</pre>
diff --git a/docs/problems.html b/docs/problems.html
index 60c26c10..e86c152f 100644
--- a/docs/problems.html
+++ b/docs/problems.html
@@ -1,175 +1,10 @@
+<!DOCTYPE html>
+<html data-destination=>
<head>
- <link href="favicon.ico" rel="shortcut icon" type="image/x-icon"/>
- <link href="style.css" rel="stylesheet"/>
- <title>Problems with BQN</title>
+ <noscript><meta http-equiv="refresh" content="0; url='commentary/problems.html'"/></noscript>
</head>
-<div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a> / <a href="index.html">main</a></div>
-<h1 id="problems-with-bqn">Problems with BQN</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>
-<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>
-<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>
-<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="tacit-and-one-line-functions-are-hard-to-debug">Tacit and one-line functions are hard to debug</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="search-function-depth">Search function depth</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="trigonometry">Trigonometry</h3>
-<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="right-to-left-multi-line-functions-go-upwards">Right-to-left multi-line functions go upwards</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="control-flow-substitutes-have-awkward-syntax">Control flow substitutes have awkward syntax</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>
-<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>
-<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>
-<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="syntactic-type-erasure">Syntactic type erasure</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="nothing--interacts-strangely-with-before-and-after">Nothing (<code><span class='Nothing'>·</span></code>) interacts strangely with Before and After</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>
-<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>
-<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>
-<tr>
-<th>Definitely</th>
-<th>Maybe</th>
-<th>Definitely not</th>
-</tr>
-</thead>
-<tbody>
-<tr>
-<td><code><span class='Function'>=≠≤≥&lt;&gt;</span></code></td>
-<td><code><span class='Function'>≡≢⊐⊒∊⍷|</span></code></td>
-<td><code><span class='Function'>⍋⍒</span></code></td>
-</tr>
-</tbody>
-</table>
-<h3 id="no-access-to-fast-high-precision-sum">No access to fast high-precision sum</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>
-<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>
-<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>
-<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="poor-font-support-">Poor font support</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>
-<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>
-<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>
-<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="group-doesnt-include-trailing-empty-groups">Group doesn't include trailing empty groups</h3>
-<p>But there are workarounds, described in <a href="doc/group.html">its documentation</a>. dzaima has suggested allowing a single extra element in the index argument to specify the result shape. Another possibility is for the result prototype to be specified to allow overtaking.</p>
-<h3 id="underbind-combination-is-awkward">Under/bind combination is awkward</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>
-<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="trains-dont-like-monads">Trains don't like monads</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="inverse-is-not-fully-specified">Inverse is not fully specified</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="prefixessuffixes-add-depth-and-windows-doesnt">Prefixes/Suffixes add depth and Windows doesn't</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>
-<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, 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>
-<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="rankdepth-negative-zero">Rank/Depth negative zero</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>
-<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>
-<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="each-block-body-has-its-own-label">Each block body has its own label</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>
-<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>
-<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>
-<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>
-<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>
-<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>
-<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>
-<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>
-<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>
-<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>
-<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.</p>
-<h3 id="scan-ordering-is-weird">Scan ordering is weird</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>
-<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>
-<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>
-<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>
-<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>
-<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>
-<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>
-<p>Blanket issue for names that I don't find informative: &quot;Solo&quot;, &quot;Bins&quot;, &quot;Unique Mask&quot;, &quot;Find&quot;, and &quot;Group&quot;.</p>
-<h3 id="strands-go-left-to-right">Strands go left to right</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="should-have-a-rounding-function">Should have a rounding function</h3>
-<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="primitive-name-capitalization">Primitive name capitalization</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>
-<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="array-reductions-are-annoying">Array reductions are annoying</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>
-<li><code><span class='Function'>𝔽</span><span class='Modifier'>˝</span></code> Apply it between major cells of an array (SHARP).</li>
-<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>
-<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>
-<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>
-<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>
-<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>. However, it doesn't partition along multiple axes, so a dedicated partition function that does this could also be wanted. Or could Group be made to work with multiple axes as well as multidimensional indices?</p>
-<h3 id="key-doesnt-do-what-you-want">Key doesn't do what you want</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>
-<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>
-<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>
-<p>Fixed by allowing a variable to be written with a different syntactic class 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>
-<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>
-<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>
-<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>
-<p>Fixed with Prefix, Suffix, and Infix operators in J. Changed to functions in BQN.</p>
+<body>
+ Redirect (moved to commentary/ folder)
+ <script>window.location.href = 'commentary/problems.html' + (window.location.hash || '');</script>
+</body>
+</html>