aboutsummaryrefslogtreecommitdiff
path: root/docs/commentary/problems.html
blob: ca964274ad90996a75882d8432211cac6f46e0e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
<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">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">commentary</a></div>
<h1 id="problems-with-bqn"><a class="header" href="#problems-with-bqn">Problems with BQN</a></h1>
<p>Every language has some issues that everyone can agree make programming harder. Sometimes there is a simple solution that has not yet been discovered; sometimes the problem is inherent to the language because it's caused by fundamental choices (or anywhere in between). Below are problems I have identified in BQN, ordered from what I consider the most severe to the least. This is independent of whether the issue can be solved—if it somehow went away, how much better would the language be?</p>
<p>This list is meant to be specific, so it addresses particular features rather than overall philosophy, and only includes missing functionality if some feature would be expected to provide it but doesn't. 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"><a class="header" href="#empty-arrays-lose-type-information">Empty arrays lose type information</a></h3>
<p>A pretty fundamental problem with dynamically-typed array languages: when computing something (say, a sum) that depends on all elements, if there are no elements then the structure of the result is indeterminate. Shape arithmetic means the shape of a cell is always known, except when using the Rank modifier so that every cell is computed independently. <a href="../doc/fill.html">Fills</a> are BQN's solution for deeper structure, but they're incomplete. They store only types and not data, but operations like Reshape that use data to determine type are common enough to make this unreliable.</p>
<h3 id="incoherent-monad-dyad-builtin-pairs"><a class="header" href="#incoherent-monad-dyad-builtin-pairs">Incoherent monad-dyad builtin pairs</a></h3>
<p>BQN inherits the functions <code><span class='Function'>+×⌊⌈|</span></code>, and adds the functions <code><span class='Function'>∧∨&lt;&gt;≠≡≢↕⍷</span></code>, that are only paired for their glyphs and not for any other reason (that is, both function valences match the symbol but they don't match with each other). I find there are just not enough good glyphs to separate all of these out, but I'm sure the pairings could be improved. In some future language, that is, as BQN is past the point of being able to change these.</p>
<h3 id="glyphs-are-hard-to-type"><a class="header" href="#glyphs-are-hard-to-type">Glyphs are hard to type</a></h3>
<p>There's been a lot of work done on this. Still there, still a problem. On the other hand, glyphs are easy to read, and write by hand!</p>
<h3 id="search-function-depth"><a class="header" href="#search-function-depth">Search function depth</a></h3>
<p>The simplest way to define a search function like Index Of is to require <code><span class='Value'>𝕨</span></code> to be a list, and search for an element that matches <code><span class='Value'>𝕩</span></code>. 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="body-determines-a-headerless-blocks-type"><a class="header" href="#body-determines-a-headerless-blocks-type">Body determines a headerless block's type</a></h3>
<p>The major problem here is the ease of programmer error: it's common to want a function that ignores the argument, and get an immediate block. Some syntactic contexts catch this error; some don't.</p>
<p>In a body with no header, you have to scan double-struck names, and so does a compiler. A little inelegant, and difficult to describe in BNF. You could just always use headers, but are you really going to?</p>
<h3 id="control-flow-substitutes-have-awkward-syntax"><a class="header" href="#control-flow-substitutes-have-awkward-syntax">Control flow substitutes have awkward syntax</a></h3>
<p>At the moment BQN has no control structures, instead <a href="../doc/control.html">preferring</a> headers, recursion, and modifiers. When working with pure functions, these can be better than control structures, but it doesn't fit an imperative style so well. With predicates, decision trees are okay but looping code is substantially worse than it is in imperative languages, particularly if tail recursion can't be relied on.</p>
<p>One particular sore point with Repeat (<code><span class='Modifier2'></span></code>) and Choose (<code><span class='Modifier2'></span></code>) is that the condition and action(s) always apply to the same set of arguments. Often you'd like them to apply to completely different things: this seems like the sort of thing that split compose <code><span class='Function'>F</span><span class='Modifier2'></span><span class='Function'>G</span><span class='Modifier2'></span><span class='Function'>H</span></code> solved for trains, but here there's no such solution.</p>
<h3 id="syntactic-type-erasure"><a class="header" href="#syntactic-type-erasure">Syntactic type erasure</a></h3>
<p>A programmer can call a modifier on either a syntactic function or subject, but there's no way to know within the modifier which syntax that operand had. Maybe this is a better design, but it doesn't feel quite right that <code><span class='Value'>f</span><span class='Modifier'>˜</span></code> is <code><span class='Value'>f</span></code>-Swap if <code><span class='Value'>f</span></code> has a function value. The subject syntax suggests it should be Constant. Instead the Constant modifier <code><span class='Modifier'>˙</span></code> has been added partially to mitigate this.</p>
<h3 id="group-doesnt-include-trailing-empty-groups"><a class="header" href="#group-doesnt-include-trailing-empty-groups">Group doesn't include trailing empty groups</a></h3>
<p>A length can now be specified either in an extra element in any rank-1 component of <code><span class='Value'>𝕨</span></code>, or by overtaking, since the result's fill element is an empty group. However, it still seems like it would be pretty easy to end up with a length error when a program using Group encounters unexpected data. It's a fundamental safety-convenience tradeoff, though, because specifying a length has to take more code in the general case.</p>
<h3 id="variable-length-loops"><a class="header" href="#variable-length-loops">Variable-length loops</a></h3>
<p>If the intended length of a loop isn't known before it begins, it can't be implemented with BQN primitives. The sensible way to handle such loops should be recursion… except that BQN implementations have stack limits. Some of them could support tail recursion, but for others it would be pretty hard and the result would be a lot of fragmentation. So uglier techniques are required, like <code><span class='Modifier2'>•_while_</span></code>, or the <a href="../doc/control.html#low-stack-version">low-stack recursion</a> that no one could be expected to invent.</p>
<h3 id="an-unmatched-predicate-loses-locals"><a class="header" href="#an-unmatched-predicate-loses-locals">An unmatched predicate loses locals</a></h3>
<p>For example <code><span class='Brace'>{</span><span class='Number'>0</span><span class='Function'></span><span class='Value'>a</span><span class='Gets'></span><span class='Value'>𝕩</span><span class='Function'>-</span><span class='Number'>2</span> <span class='Head'>?</span> <span class='Value'>a</span> <span class='Head'>;</span> <span class='Function'>-</span><span class='Value'>a</span><span class='Brace'>}</span></code> doesn't compile: the <code><span class='Head'>;</span></code> separates bodies and the second one never defines <code><span class='Value'>a</span></code>. This can be fixed by enclosing in an immediate block, which might then require you to reassign some special names. So it's only ever a syntactic difficulty, but it gets pretty annoying at times.</p>
<p>The root cause is repurposing the header-body system for an if-else thing (I found it quite surprising for this to be the worst issue caused by the approach). It can't be fixed with an extension, because the variable might really not be defined: consider <code><span class='Brace'>{</span><span class='Value'>l</span><span class='Function'>𝕊</span><span class='Value'>𝕩</span><span class='Head'>:</span> <span class='Value'>a</span><span class='Gets'></span><span class='Function'>+</span><span class='Modifier'>´</span><span class='Value'>l</span><span class='Separator'></span><span class='Function'></span><span class='Value'>l</span><span class='Head'>?</span><span class='Number'>0</span> <span class='Head'>;</span> <span class='Value'>a</span><span class='Brace'>}</span></code>. If called with no left argument, it will go into the second case, never seeing an <code><span class='Value'>a</span><span class='Gets'></span></code>.</p>
<h3 id="hard-to-search-part-of-an-array-or-in-a-different-order"><a class="header" href="#hard-to-search-part-of-an-array-or-in-a-different-order">Hard to search part of an array or in a different order</a></h3>
<p>This includes index-of-last, and searching starting at a particular index, when the desired result indices are to the array to be seached <em>before</em> it is modified. Given indices <code><span class='Value'>i</span></code> into an array <code><span class='Value'>𝕨</span></code> (for example <code><span class='Function'>⌽↕≠</span><span class='Value'>𝕨</span></code> or <code><span class='Value'>a</span><span class='Function'>+↕</span><span class='Value'>b</span></code>), this section can be searched with <code><span class='Paren'>(</span><span class='Value'>i</span><span class='Function'>∾≠</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'></span><span class='Modifier'>˜</span><span class='Paren'>(</span><span class='Value'>i</span><span class='Function'></span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'></span><span class='Value'>𝕩</span></code>. But this is clunky and difficult for the implementation to optimize.</p>
<h3 id="right-to-left-multi-line-functions-go-upwards"><a class="header" href="#right-to-left-multi-line-functions-go-upwards">Right-to-left multi-line functions go upwards</a></h3>
<p>If you include multiple multi-line functions in what would otherwise be a one-liner, the flow in each function goes top to bottom but the functions are executed bottom to top. I think the fix in BQN is to just say give your functions names and don't do this. But <a href="ltr.html">left to right</a> programming beckons.</p>
<h3 id="trains-dont-like-monads"><a class="header" href="#trains-dont-like-monads">Trains don't like monads</a></h3>
<p>If you have the normal mix of monads and dyads you'll need a lot of parentheses and might end up abusing <code><span class='Modifier2'></span></code>. Largely solved with the Nothing syntax <code><span class='Nothing'>·</span></code>, which acts like J's Cap (<code><span class='Value'>[</span><span class='Head'>:</span></code>) in a train, but still a minor frustration.</p>
<h3 id="underbind-combination-is-awkward"><a class="header" href="#underbind-combination-is-awkward">Under/bind combination is awkward</a></h3>
<p>It's most common to use Under with dyadic structural functions in the form <code><span class='Value'></span><span class='Modifier2'></span><span class='Paren'>(</span><span class='Value'>i</span><span class='Modifier2'></span><span class='Function'>F</span><span class='Paren'>)</span></code>, for example where <code><span class='Function'>F</span></code> is one of <code><span class='Function'>/</span></code> or <code><span class='Function'></span></code>. This is frustrating for two reasons: it requires parentheses, and it doesn't allow <code><span class='Value'>i</span></code> to be computed tacitly. If there's no left argument then the modifier <code><span class='Brace'>{</span><span class='Function'>𝔽</span><span class='Modifier2'></span><span class='Paren'>(</span><span class='Value'>𝕨</span><span class='Modifier2'></span><span class='Function'>𝔾</span><span class='Paren'>)</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> can be more useful, but it doesn't cover some useful cases such as mask <code><span class='Value'>a</span> <span class='Function'></span><span class='Modifier2'></span><span class='Paren'>(</span><span class='Value'>u</span><span class='Modifier2'></span><span class='Function'>/</span><span class='Paren'>)</span> <span class='Value'>b</span></code>.</p>
<h3 id="list-splicing-is-fiddly"><a class="header" href="#list-splicing-is-fiddly">List splicing is fiddly</a></h3>
<p>It's common when manipulating text to want to replace a slice with a different slice with an unrelated length. Structural Under works well for this if the new slice has the same length but doesn't otherwise (an implementation could choose to support it, but <em>only</em> if the slice is extracted using two Drops, not Take). So in general the programmer has to cut off initial and final segments and join them to the new slice. If the new slice is computed from the old one it's much worse, as there will be duplication between the code to extract that slice and the other segments. The duplication can be avoided with Group using <code><span class='Function'>∾F</span><span class='Modifier2'></span><span class='Paren'>(</span><span class='Number'>1</span><span class='Modifier2'></span><span class='Function'></span><span class='Paren'>)(</span><span class='Value'>s</span><span class='Ligature'></span><span class='Value'>e</span><span class='Function'>⍋↕</span><span class='Modifier2'></span><span class='Function'></span><span class='Paren'>)</span><span class='Modifier2'></span><span class='Function'></span></code>, but this is a lot of work and will execute slowly without some special support. In fact, everything here is liable to run slowly, making too many copies of the unmodified part of the stream.</p>
<p>Dyalog's solution here (and dzaima/BQN's) is Regex, which is a nice feature but also an entire second language to learn.</p>
<h3 id="subtraction-division-and-span-are-backwards"><a class="header" href="#subtraction-division-and-span-are-backwards">Subtraction, division, and span are backwards</a></h3>
<p>The left argument feels much more like the primary one in these cases (indeed, this matches the typical left-to-right ordering of binary operators in mathematics). The commonly-paired <code><span class='Function'></span><span class='Modifier2'></span><span class='Function'>÷</span></code> and <code><span class='Function'>|</span></code> have opposite orders for this reason. Not really fixable; too much precedent.</p>
<h3 id="poor-font-support"><a class="header" href="#poor-font-support">Poor font support</a></h3>
<p>Characters <code><span class='Function'>⥊∾</span><span class='Modifier2'>⟜⎉⚇</span><span class='Modifier'>˜</span></code> and double-struck letters are either missing from many fonts or drawn strangely.</p>
<h3 id="deshape-and-reshape-cant-ignore-trailing-axes"><a class="header" href="#deshape-and-reshape-cant-ignore-trailing-axes">Deshape and Reshape can't ignore trailing axes</a></h3>
<p>If you want to repeat 3 major cells until there are 7 of them, or combine the first 4 axes of a rank-6 array, what's your best option? Nothing's too good: you could compute a full shape for Reshape, enclose cells and merge afterwards (for example <code><span class='Number'>7</span><span class='Modifier2'></span><span class='Function'></span><span class='Modifier2'></span><span class='Paren'>(</span><span class='Function'>&lt;</span><span class='Modifier'>˘</span><span class='Paren'>)</span></code>), use Select to reshape one axis to multiple, or use <code><span class='Function'></span><span class='Modifier'>˝</span></code> to merge two axes (with possible empty-array issues). This is particularly dangerous with computed-length reshapes like <code><span class='Number'>2</span><span class='Ligature'></span><span class='Modifier2'></span><span class='Function'></span><span class='Value'></span></code>, since the idea of splitting off a length-2 axis from an array's first axis is generally useful, but this version has an implicit Deshape first.</p>
<p>J's Reshape analogue (<code><span class='Value'>$</span></code>) only ever applies to the first axis. I now think this is probably a better primitive to have overall, as <code><span class='Value'>$</span><span class='Modifier2'></span><span class='Function'></span></code> gives the APL behavior back and is rarely needed. It's not an intuitive pair with Deshape though.</p>
<h3 id="long-trains-are-hard-for-humans-to-parse"><a class="header" href="#long-trains-are-hard-for-humans-to-parse">Long trains are hard for humans to parse</a></h3>
<p>In a train consisting only of functions, the behavior of a function (whether it's applied directly to arguments, or to the results of other functions) is determined by its distance from the right side of the train. With a longer train it gets easy to lose track of whether the distance is even or odd. Sure, any bit of syntax gets hard when you put too much of it on a line, but it's notable that with trains this happens very quickly. The length where difficulty begins varies from about 4 to 8 parts, depending on the reader. A train of only functions is the worst case, as subjects can only go in one position and thus serve as anchors.</p>
<h3 id="prefixessuffixes-add-depth-and-windows-doesnt"><a class="header" href="#prefixessuffixes-add-depth-and-windows-doesnt">Prefixes/Suffixes add depth and Windows doesn't</a></h3>
<p>It's an awkward inconsistency. Prefixes and Suffixes have to have a nested result, but Windows doesn't have to be flat; it's just that making it nested ignores the fact that it does have an array structure.</p>
<h3 id="converting-a-function-expression-to-a-subject-is-tricky"><a class="header" href="#converting-a-function-expression-to-a-subject-is-tricky">Converting a function expression to a subject is tricky</a></h3>
<p>You can name it, you can write <code><span class='Function'></span><span class='Bracket'></span><span class='Function'>Expr</span><span class='Bracket'></span></code> or <code><span class='Paren'>(</span><span class='Function'>Expr</span><span class='Paren'>)</span><span class='Modifier'>˙</span><span class='Number'>0</span></code>, and if it doesn't use special names you can write <code><span class='Brace'>{</span><span class='Function'>Expr</span><span class='Brace'>}</span></code>. All of these are at least a little awkward in reasonable cases. Should there be a dedicated syntax? Note that going the other way, from subject to function, isn't too bad: the modifier <code><span class='Brace'>{</span><span class='Function'>𝔽</span><span class='Brace'>}</span></code> does it, as does <code><span class='Modifier2'></span><span class='Function'></span></code>.</p>
<h3 id="cant-reduce-or-scan-over-arrays-jointly"><a class="header" href="#cant-reduce-or-scan-over-arrays-jointly">Can't Reduce or Scan over arrays jointly</a></h3>
<p>Each allows you to move along two arrays simultaneously (sure, three isn't good, but you can usually split into two Each-ed functions). Reduce and Scan are stuck with one, so you might need to pass in a list of tuples. Scan also encourages you to pack a few values into the result, leaving you the same annoying structure. A nested-transpose primitive, similar to <code><span class='Function'>&lt;</span><span class='Modifier'>˘</span><span class='Function'>&gt;</span></code>, would help a lot.</p>
<h3 id="axis-ordering-is-big-endian"><a class="header" href="#axis-ordering-is-big-endian">Axis ordering is big-endian</a></h3>
<p>The most natural ordering for polynomial coefficients and base representations is little-endian, because it aligns element <code><span class='Value'>i</span></code> of the list with power <code><span class='Value'>i</span></code> of the argument or base. It also allows a forward scan instead of a reverse one. Array axes go the other way. However, there are advantages to this ordering as well. For example, it's common to act only on the first few axes, so having them at the beginning of the array is good (<code><span class='Function'></span><span class='Value'>a</span> <span class='Gets'>←→</span> <span class='Function'></span><span class='Modifier2'></span><span class='Function'></span><span class='Value'>a</span></code>).</p>
<h3 id="inverse-is-not-fully-specified"><a class="header" href="#inverse-is-not-fully-specified">Inverse is not fully specified</a></h3>
<p>So it seems a bit strange to rely on it for core language features like <code><span class='Function'>/</span><span class='Modifier'></span></code> (well, that one in particular has been specified, and extended even). 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="choose-and-repeat-have-order-swapped"><a class="header" href="#choose-and-repeat-have-order-swapped">Choose and Repeat have order swapped</a></h3>
<p>In Choose, the selector goes on the left; in Repeat, the count goes on the right. Could be a strength in some contexts, since you can change Repeat-as-If to Choose if you don't like the ordering, but maybe a language that forces the programmer to make semantic decisions for syntactic reasons is not providing the greatest of services.</p>
<h3 id="have-to-enclose-scan-initial-element"><a class="header" href="#have-to-enclose-scan-initial-element">Have to enclose Scan initial element</a></h3>
<p>The most common case for Scan is of course applying to a list. Here there can only be one element, but it has to go in a unit array to keep Scan general. The reductions dodge this by leaving out the APL2 style, and Scan hits it dead on.</p>
<h3 id="cant-mix-define-and-modify-in-multiple-assignment"><a class="header" href="#cant-mix-define-and-modify-in-multiple-assignment">Can't mix define and modify in multiple assignment</a></h3>
<p>Say <code><span class='Value'>a</span></code> is a pair and <code><span class='Value'>h</span></code> isn't defined yet; how would you set <code><span class='Value'>h</span></code> to the first element of <code><span class='Value'>a</span></code> and change <code><span class='Value'>a</span></code> to be just the second? <code><span class='Value'>h</span><span class='Ligature'></span><span class='Value'>a</span><span class='Gets'></span><span class='Value'>a</span></code> doesn't work because <code><span class='Value'>h</span></code> isn't defined, so the best I have is <code><span class='Value'>h</span><span class='Gets'></span><span class='String'>@</span><span class='Separator'></span><span class='Value'>h</span><span class='Ligature'></span><span class='Value'>a</span><span class='Gets'></span><span class='Value'>a</span></code>. A heavier assignment syntax wouldn't break down; BQN could allow <code><span class='Bracket'></span><span class='Value'>h</span><span class='Gets'></span><span class='Separator'>,</span><span class='Value'>a</span><span class='Bracket'></span><span class='Gets'></span><span class='Value'>a</span></code> but I don't think this merits special syntax.</p>
<h3 id="tolerant-comparison"><a class="header" href="#tolerant-comparison">Tolerant comparison</a></h3>
<p>APL has it and BQN doesn't; after some experience it seems this causes few problems, and the extra effort required for the algorithms that do need it is negligible (anyway, it's better to be aware when your code relies on imprecise equality). APL and J also tolerate inexact indices and lengths, which is also something that could be supported.</p>
<h3 id="named-modifiers-use-way-more-space-than-primitive-ones"><a class="header" href="#named-modifiers-use-way-more-space-than-primitive-ones">Named modifiers use way more space than primitive ones</a></h3>
<p><code><span class='Function'>F</span> <span class='Modifier2'>_m_</span> <span class='Function'>G</span></code> versus <code><span class='Function'>F</span><span class='Modifier2'></span><span class='Function'>G</span></code>: the syntax is the same but these don't feel the same at all. This is the worst case, as with primitive operands, <code><span class='Function'>+</span><span class='Modifier2'>_m_</span><span class='Function'>÷</span></code> isn't as far from <code><span class='Function'>+</span><span class='Modifier2'></span><span class='Function'>÷</span></code>. It means a style-conscious programmer has to adjust the way they write code depending on whether things are named, and makes named modifiers feel less integrated into the language. A mix of named modifiers with primitive modifiers or trains can also look inconsistent.</p>
<h3 id="return-value-prevents-optimization"><a class="header" href="#return-value-prevents-optimization">Return value prevents optimization</a></h3>
<p>Run something like <code><span class='Value'>a</span><span class='Gets'></span><span class='Function'></span><span class='Number'>1e6</span> <span class='Separator'></span> <span class='Brace'>{</span><span class='Value'>a</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='Gets'></span><span class='Brace'>}</span><span class='Modifier'>¨</span><span class='Function'></span><span class='Number'>100</span></code> and you'll get poor performance in current CBQN. This is because <code><span class='Value'>a</span></code> is part of the function result to be used by <code><span class='Modifier'>¨</span></code>, creating a reference and preventing in-place updates. The function needs to return something else, with <code><span class='Separator'></span><span class='String'>@</span></code> at the end maybe. Various strategies could fix this by tracking whether the result will be needed.</p>
<h3 id="cant-always-transfer-ambivalence-in-tacit-code"><a class="header" href="#cant-always-transfer-ambivalence-in-tacit-code">Can't always transfer ambivalence in tacit code</a></h3>
<p>For example, there's no tacit equivalent of the old APL (NARS) <code><span class='Modifier2'></span></code>, which in explicit BQN is simply <code><span class='Brace'>{</span><span class='Value'>𝕨</span><span class='Function'>𝔽𝔾</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code>. Similarly, <code><span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>𝔽</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> is missing. The contrast with Atop and Over, which work very smoothly, can be jarring and make it harder to get an intuition for what the code is doing.</p>
<h3 id="index-of-privileges-the-first-match"><a class="header" href="#index-of-privileges-the-first-match">Index Of privileges the first match</a></h3>
<p>It could be more sound to look at all matches, but using just the first one is too convenient. J has an index-of-last function; in BQN you have to reverse the left argument and then do arithmetic: <code><span class='Function'></span><span class='Modifier2'></span><span class='Function'>⊣-</span><span class='Number'>1</span><span class='Function'>+⌽</span><span class='Modifier2'></span><span class='Function'></span></code>. I'm treating index-of-last as part of <a href="#hard-to-search-part-of-an-array-or-in-a-different-order">a different problem</a> higher up though.</p>
<h3 id="negative-indices-dont-fail-by-default"><a class="header" href="#negative-indices-dont-fail-by-default">Negative indices don't fail by default</a></h3>
<p>The typical case when selecting from an array is that a negative index doesn't make sense, and you'd prefer it to give an error. But negative indices are pretty useful in some contexts so BQN trades safety for convenience. Manually checking that indices are non-negative is easier than full range checking, but the issue is that you have to do it manually at all.</p>
<h3 id="at-which-scope-does-a-block-function-belong"><a class="header" href="#at-which-scope-does-a-block-function-belong">At which scope does a block function belong?</a></h3>
<p>As a general principle, a programmer should make choices in one part of a program that constrain other parts of the program most tightly. This is a weak principle, but often it doesn't conflict with any other preferences and can be followed for free. For example it's usually best to define a variable in the smallest possible scope, so the reader knows it isn't used outside that scope. The same principle applies to blocks, but there is another conflicting principle: placing the block in a broader scope guarantees it won't access the variables in narrower ones. There's no position that will tell the reader, for example, that a function only uses variables local to itself and that it's only used within one particular scope.</p>
<p>This is an issue with any lexically-scoped language; it's unlikely BQN can solve it. On the other hand, I'm surprised I've never seen any discussion of such a universal issue.</p>
<h3 id="acting-on-windows-can-be-awkward"><a class="header" href="#acting-on-windows-can-be-awkward">Acting on windows can be awkward</a></h3>
<p>When taking Windows along more than one axis, acting on the resulting array requires the Rank modifier, duplicating either the right argument rank or (negated) left argument length. A nested Windows would only require Each.</p>
<h3 id="rankdepth-negative-zero"><a class="header" href="#rankdepth-negative-zero">Rank/Depth negative zero</a></h3>
<p>A positive operand to Rank indicates the cell rank, so positive zero means to act on 0-cells. A negative operand indicates the frame length, so negative zero should act on the entire array. But it can't because it's equal to positive zero. Similar issue with Depth. Positive/negative is not really the right way to encode the frame/cell distinction, but it's convenient. Fortunately ∞ can be used in place of negative zero, but there can still be problems if the rank is computed.</p>
<h3 id="nothing--interacts-strangely-with-before-and-after"><a class="header" href="#nothing--interacts-strangely-with-before-and-after">Nothing (<code><span class='Nothing'>·</span></code>) interacts strangely with Before and After</a></h3>
<p>Since <code><span class='Value'>𝕨</span><span class='Function'>F</span><span class='Modifier2'></span><span class='Function'>G</span><span class='Value'>𝕩</span></code> is <code><span class='Paren'>(</span><span class='Function'>F</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>G</span><span class='Value'>𝕩</span></code> and <code><span class='Value'>𝕨</span><span class='Function'>F</span><span class='Modifier2'></span><span class='Function'>G</span><span class='Value'>𝕩</span></code> is <code><span class='Value'>𝕨</span><span class='Function'>F</span> <span class='Function'>G</span><span class='Value'>𝕩</span></code> in the dyadic case, we might expect these to devolve to <code><span class='Function'>G</span><span class='Value'>𝕩</span></code> and <code><span class='Function'>F</span> <span class='Function'>G</span><span class='Value'>𝕩</span></code> when <code><span class='Value'>𝕨</span></code> is not present. Not so: instead <code><span class='Value'>𝕩</span></code> is substituted for the missing <code><span class='Value'>𝕨</span></code>. And Before and After are also the main places where a programmer might try to use <code><span class='Value'>𝕨</span></code> as an operand, which doesn't work either (the right way is the train <code><span class='Value'>𝕨</span><span class='Function'>F⊢</span></code>). It's also a little strange that <code><span class='Value'>v</span> <span class='Function'>F</span><span class='Modifier'>˜</span><span class='Nothing'>·</span></code> is <code><span class='Nothing'>·</span></code>, while <code><span class='Nothing'>·</span><span class='Function'>F</span> <span class='Value'>v</span></code> is <code><span class='Function'>F</span> <span class='Value'>v</span></code>.</p>
<h3 id="glyphs-that-arent-great"><a class="header" href="#glyphs-that-arent-great">Glyphs that aren't great</a></h3>
<p>Blanket issue for unintuitive glyphs. Currently I find <code><span class='Function'>⥊⊏⊑⊐⊒⍷</span><span class='Modifier'></span><span class='Modifier2'>⎉⚇</span></code> to not be particularly good fits for what they describe.</p>
<h3 id="cant-access-array-ordering-directly"><a class="header" href="#cant-access-array-ordering-directly">Can't access array ordering directly</a></h3>
<p>Only <code><span class='Function'>⍋⍒</span></code> use array ordering rather than just array equality or numeric ordering. Getting at the actual ordering to just compare two arrays is not hard but also not obvious: <code><span class='Function'></span><span class='Modifier2'></span><span class='Function'></span></code> is TAO <code><span class='Function'></span></code>.</p>
<h3 id="tacit-evaluation-is-opaque"><a class="header" href="#tacit-evaluation-is-opaque">Tacit evaluation is opaque</a></h3>
<p>Evaluating a derived function does a lot of work that often can't be connected with any particular source location. This is why stack traces don't dig into tacit functions, for now at least. For the interactive side of debugging, <code><span class='Function'>•Show</span></code> is so powerful in tacit code that I'm not sure this is even an issue, but it's still worth keeping in mind if BQN adds a more traditional debugger. And it's troublesome for implementers, who tend to rely on stepping through opcodes.</p>
<h3 id="no-access-to-fast-high-precision-sum"><a class="header" href="#no-access-to-fast-high-precision-sum">No access to fast high-precision sum</a></h3>
<p>Fold has a specific order of application, which must be used for <code><span class='Function'>+</span><span class='Modifier'>`</span></code>. But other orders can be both faster and more precise (in typical cases) by enabling greater parallelism. Generally ties into the question of providing precision control for a program: it could be fixed by a flag that enables BQN to optimize as long as the results will be at least as precise (relative to the same program in infinite precision) as the spec. Absent this feature it will probably be provided with <code><span class='Value'>•math.</span><span class='Function'>Sum</span></code>.</p>
<h3 id="no-one-right-way-to-check-if-a-value-is-an-array"><a class="header" href="#no-one-right-way-to-check-if-a-value-is-an-array">No one right way to check if a value is an array</a></h3>
<p>The mathematical approach is <code><span class='Number'>0</span><span class='Function'>&lt;</span><span class='Value'>𝕩</span></code>, which can be slow without runtime support, while the efficient approach is <code><span class='Number'>0</span><span class='Function'>=•Type</span><span class='Value'>𝕩</span></code>, which is ugly and uses a system function for something that has nothing at all to do with the system. These are minor flaws, but programmers shouldn't have to hesitate about which one they want to use.</p>
<h3 id="tacit-code-cant-build-lists-easily"><a class="header" href="#tacit-code-cant-build-lists-easily">Tacit code can't build lists easily</a></h3>
<p>It's unergonomic, and also quadratic in a naive runtime. The problem of course is that tacit code can only combine up to two values at a time, while in explicit code, list notation combines any number of them. In a language less beholden to syntax, <code><span class='Function'>List</span></code> would simply be a function with an arbitrary number of arguments and you'd be able to form trains with it—although this <em>does</em> require distinguishing when it's used as a train versus as a plain function. First-class functions get you this behavior if you really need it.</p>
<h3 id="monadic-argument-corresponds-to-left-for--and-"><a class="header" href="#monadic-argument-corresponds-to-left-for--and-">Monadic argument corresponds to left for <code><span class='Function'>/</span></code> and <code><span class='Function'></span></code></a></h3>
<p>Called dyadically, both functions shuffle cells of the right argument around, which is consistent with other selection-type functions. But the monadic case applies to what would be the left argument in the dyadic case.</p>
<h3 id="high-rank-array-notation-awkwardness"><a class="header" href="#high-rank-array-notation-awkwardness">High-rank array notation awkwardness</a></h3>
<p>The notation <code><span class='Value'>[]</span></code> will be added for high-rank arrays, the same as BQN's lists <code><span class='Bracket'>⟨⟩</span></code> except it mixes at the end. It looks okay with BQN strands but clashes with BQN lists. At that point it becomes apparent that specifying whether something is a high-rank array at the top axes is kind of strange: shouldn't it be the lower axes saying to combine with higher ones? A more concrete point of awkwardness is that literal notations can only form arrays with rank 1 or more, preventing unit arrays from being destructured. Syntax with <code><span class='Function'>&lt;</span></code> and <code><span class='Value'>[]</span></code> would be complete over non-empty arrays.</p>
<h3 id="assert-has-no-way-to-compute-the-error-message"><a class="header" href="#assert-has-no-way-to-compute-the-error-message">Assert has no way to compute the error message</a></h3>
<p>In the compiler, error messages could require expensive diagnostics, and in some cases the message includes parts that can only be computed if there's an error (for example, the index of the first failure). However, Assert (<code><span class='Function'>!</span></code>) only takes a static error message, so you have to first check a condition, then compute the message, then call Assert on that. Kind of awkward, but better than it used to be before one-argument Assert was changed to use <code><span class='Value'>𝕩</span></code> for the message. The issue generally applies to high-quality tools built in BQN, where giving the user good errors is a priority.</p>
<h3 id="monadic--versus-"><a class="header" href="#monadic--versus-">Monadic <code><span class='Function'></span></code> versus <code><span class='Function'>&gt;</span></code></a></h3>
<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"><a class="header" href="#cant-take-prefixes-or-suffixes-on-multiple-axes">Can't take Prefixes or Suffixes on multiple axes</a></h3>
<p>This is a natural array operation to do, and results in an array with a joinable structure, but as Prefixes and Suffixes are monadic there's no way to specify the number of axes to use.</p>
<h3 id="hard-to-manipulate-the-result-of-a-modifier"><a class="header" href="#hard-to-manipulate-the-result-of-a-modifier">Hard to manipulate the result of a modifier</a></h3>
<p>Trains and compositions make it easy to work with the results of functions, in some sense. The same can't be said for modifiers: for example, in a non-immediate block modifier, the derived function is <code><span class='Function'>𝕊</span></code>, but you can't apply <code><span class='Modifier'>˜</span></code> to it. This seems to call for modifier trains but people who worked with early J were confident they're not worth it. Except they just added them back. Who knows.</p>
<h3 id="modified-assignment-modifies-the-left-secondary-argument"><a class="header" href="#modified-assignment-modifies-the-left-secondary-argument">Modified assignment modifies the left (secondary) argument</a></h3>
<p>So you end up with <code><span class='Modifier'>˜</span><span class='Gets'></span></code> a lot of the time. For ordinary assignment it's pretty reasonable to say the value is primary, but modified assignment flips this around.</p>
<h3 id="changing-boundary-behavior-can-require-very-different-code"><a class="header" href="#changing-boundary-behavior-can-require-very-different-code">Changing boundary behavior can require very different code</a></h3>
<p>This mainly applies to pairwise operations; for bigger stencils you'd use Windows, and probably handle boundaries with multidimensional selection. For pairwise operations there are four different paths you might use: decrease size using <code><span class='Function'></span></code>; periodic conditions with <code><span class='Function'></span></code>; fixed or computed boundaries with <code><span class='Function'>«</span></code> and <code><span class='Function'>»</span></code>; and increased size with <code><span class='Function'></span></code>. Having all this flexibility is great, and it's hard to imagine a parametrized system that offers the same without being difficult to remember. However, some of these functions take lengths and some take values, the latter class only works on one dimension at a time, and for <code><span class='Function'></span></code> the argument can go on either side. This is frustrating if you have a reason to switch between the conditions.</p>
<h3 id="only-errors-in-functions-can-be-caught"><a class="header" href="#only-errors-in-functions-can-be-caught">Only errors in functions can be caught</a></h3>
<p>The modifier <code><span class='Modifier2'></span></code> allows errors in a function to be caught, but a more natural unit for this is the block (scope, really). However, catching errors shouldn't be common in typical code, in the sense that an application should have only a few instances of <code><span class='Modifier2'></span></code>. Ordinary testing and control flow should be preferred instead.</p>
<h3 id="modifiers-look-looser-than-trains-without-spaces"><a class="header" href="#modifiers-look-looser-than-trains-without-spaces">Modifiers look looser than trains without spaces</a></h3>
<p>Consider <code><span class='Function'></span><span class='Modifier2'></span><span class='Function'></span><span class='Modifier'>˜</span></code>. It's just a sequence of three functions so the use of <code><span class='Modifier2'></span></code> rather than <code><span class='Nothing'>·</span></code> is to highlight structure: <code><span class='Function'></span><span class='Modifier2'></span><span class='Function'>-</span></code> is more tightly bound so the suggestion is to consider this composition as a single entity. But in fact <code><span class='Function'>-</span></code> is closer to <code><span class='Function'>×</span><span class='Modifier'>˜</span></code> than to <code><span class='Function'></span></code>, intuitively suggesting the opposite. Adding a space fixes it: <code><span class='Function'></span><span class='Modifier2'></span><span class='Function'>-</span> <span class='Function'>×</span><span class='Modifier'>˜</span></code> visually connects <code><span class='Function'></span><span class='Modifier2'></span><span class='Function'>-</span></code>. It's unfortunate that this is something the writer must do rather than something the notation encourages.</p>
<h3 id="have-to-be-careful-about-intermediate-results-with-affine-characters"><a class="header" href="#have-to-be-careful-about-intermediate-results-with-affine-characters">Have to be careful about intermediate results with affine characters</a></h3>
<p>A computation like <code><span class='Paren'>(</span><span class='Value'>a</span><span class='Function'>+</span><span class='Value'>b</span><span class='Paren'>)</span><span class='Function'>÷</span><span class='Number'>2</span></code> (midpoint between characters <code><span class='Value'>a</span></code> and <code><span class='Value'>b</span></code>, of the distance between them is even) or <code><span class='Number'>5</span><span class='Function'>&gt;</span><span class='Value'>v</span><span class='Function'>-</span><span class='Value'>n</span></code> (equivalent to <code><span class='Value'>v</span><span class='Function'>&lt;</span><span class='Number'>5</span><span class='Function'>+</span><span class='Value'>n</span></code>) is conceptually okay, but the first will always fail because <code><span class='Value'>a</span><span class='Function'>+</span><span class='Value'>b</span></code> is invalid while the second will (even worse!) fail only if <code><span class='Value'>v</span></code> is a character with code point smaller than <code><span class='Value'>n</span></code>. Arithmetic manipulations that would be valid for numbers aren't for the number-character system.</p>
<p>Numbers and characters are subsets of a linear space with components &quot;characterness&quot; (0 for numbers and 1 for characters) and value (code point for characters). Numbers are a linear subspace, and characters a subset of an affine one. Their union isn't closed under addition and subtraction in either component. Usually this is good, as failing when the user creates a nonexistent character or double-character can catch a lot of errors. But not always.</p>
<h3 id="each-block-body-has-its-own-label"><a class="header" href="#each-block-body-has-its-own-label">Each block body has its own label</a></h3>
<p>In a block with multiple bodies, the label (the self-name part of the header) refers to the entire block. However, there's no way to give only one label to the entire block. If you want to consistently use the same internal name, then you may have to write it many times. It's also a weird mismatch, conceptually.</p>
<h3 id="andormaxmin-are-all-tangled-up"><a class="header" href="#andormaxmin-are-all-tangled-up">And/Or/Max/Min are all tangled up</a></h3>
<p>Boolean And (<code><span class='Function'></span></code>) and Or (<code><span class='Function'></span></code>) are identical to Min (<code><span class='Function'></span></code>) and Max (<code><span class='Function'></span></code>) when restricted to Boolean arguments, and this would fit nicely with their monadic role as sorting functions: for example <code><span class='Value'>a</span><span class='Function'></span><span class='Value'>b</span> <span class='Gets'>←→</span> <span class='Function'>⊑∧</span><span class='Value'>a</span><span class='Ligature'></span><span class='Value'>b</span></code>. Furthermore the pairing of Min with Floor and Max with Ceiling is mnemonic only and not especially natural. The reason I have not used these glyphs for Min and Max, and have instead extended them to the somewhat superfluous <a href="../doc/logic.html">arithmetic logical functions</a> is that Min and Max have different <a href="https://aplwiki.com/wiki/Identity_element">identity elements</a> of <code><span class='Number'></span></code> and <code><span class='Number'>¯∞</span></code> rather than <code><span class='Number'>1</span></code> and <code><span class='Number'>0</span></code>. Having to code around empty arrays when using <code><span class='Function'></span><span class='Modifier'>´</span></code> would be a fairly big issue.</p>
<p>The other drawback of Min (<code><span class='Function'></span></code>) and Max (<code><span class='Function'></span></code>) is that the symbols are counterintuitive, but I have found a way to remember them: consider the graph of variables <code><span class='Value'>a</span><span class='Gets'></span><span class='Value'>x</span></code> and <code><span class='Value'>b</span><span class='Gets'></span><span class='Function'>¬</span><span class='Value'>x</span></code> for x from 0 to 1: two crossed lines. Now the graph of <code><span class='Value'>a</span><span class='Function'></span><span class='Value'>b</span></code> is a caret shape and <code><span class='Value'>a</span><span class='Function'></span><span class='Value'>b</span></code> is a vee.</p>
<h3 id="inputs-to-modifiers-are-called-operands"><a class="header" href="#inputs-to-modifiers-are-called-operands">Inputs to modifiers are called operands?</a></h3>
<p>&quot;Operand&quot; is derived from &quot;operator&quot;. &quot;Modificand&quot; would be better if it weren't both made up and hideous.</p>
<h3 id="scan-ordering-is-weird"><a class="header" href="#scan-ordering-is-weird">Scan ordering is weird</a></h3>
<p>Scan moves along the array so that it uses results as left arguments, which is opposite to the usual right-to-left order of evaluation. But I think this is still better than scanning the array in reverse. You can always use Swap on the operand, or recover the APL scan ordering by doing a Reduce-Each on Prefixes.</p>
<h3 id="bins-is-inconsistent-with-index-of"><a class="header" href="#bins-is-inconsistent-with-index-of">Bins is inconsistent with Index of</a></h3>
<p>In Dyalog APL, Interval Index is identical to Index Of if the left argument has no duplicate cells and every right argument cell intolerantly matches a left argument cell. In BQN they're off by one—Bins is one larger. But all the caveats for the Dyalog relation indicate this might not be so fundamental.</p>
<h3 id="empty-left-argument-to-select"><a class="header" href="#empty-left-argument-to-select">Empty left argument to Select</a></h3>
<p>Select chooses whether <code><span class='Value'>𝕨</span></code> maps to axes of <code><span class='Value'>𝕩</span></code> or selects from the first axis based only on its depth. 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>
<p>There's a similar problem with <code><span class='Bracket'>⟨⟩</span></code> as a left argument to <code><span class='Function'></span></code>: it could be a list of no indices, or a length-0 index. Currently it's treated as an index, causing errors when <code><span class='Value'>𝕨</span></code> is a variable-length list of indices. This could be mostly fixed with backwards compatibility by choosing the other way when <code><span class='Value'>𝕩</span></code> has nonzero rank.</p>
<h3 id="special-names-other-than-𝕣-cant-be-written-as-modifiers"><a class="header" href="#special-names-other-than-𝕣-cant-be-written-as-modifiers">Special names other than 𝕣 can't be written as modifiers</a></h3>
<p>I decided that it was better to allow <code><span class='Value'>𝕨</span><span class='Modifier2'>_m_</span><span class='Value'>𝕩</span></code> to work with no spaces than to allow <code><span class='Modifier2'>_</span><span class='Value'>𝕩</span></code> to be a modifier, and this rule also helps keep tokenization simple. But to apply <code><span class='Value'>𝕩</span></code> as a modifier you have to give it a different name. Could actually be a good thing in that it encourages you to stick to functions, as they're nicer in lots of other ways.</p>
<h3 id="nothing-in-header-is-something-in-body"><a class="header" href="#nothing-in-header-is-something-in-body">Nothing in header is something in body</a></h3>
<p>Since <code><span class='Nothing'>·</span></code> is used for an ignored value in destructuring, the header <code><span class='Nothing'>·</span><span class='Function'>𝕊</span><span class='Value'>𝕩</span><span class='Head'>:</span></code> indicates that <code><span class='Value'>𝕨</span></code> has some value, that is, that it's not <code><span class='Nothing'>·</span></code>.</p>
<h3 id="exact-result-of-power-is-unspecified"><a class="header" href="#exact-result-of-power-is-unspecified">Exact result of Power is unspecified</a></h3>
<p>The other arithmetic functions round to nearest, and compound functions such as <code><span class='Value'></span></code> have been removed. But Power makes no guarantees, and the result could change over time based on different special code. Dyadic logarithm is similar, but expected because of its inverse status.</p>
<h3 id="unclear-primitive-names"><a class="header" href="#unclear-primitive-names">Unclear primitive names</a></h3>
<p>Blanket issue for names that I don't find informative: &quot;Solo&quot;, &quot;Bins&quot;, &quot;Find&quot;, and &quot;Group&quot;.</p>
<h3 id="tacit-exports-can-leak-data"><a class="header" href="#tacit-exports-can-leak-data">Tacit exports can leak data</a></h3>
<p>One of the nice facets of BQN's module system is that it provides perfect encapsulation: if you have variables <code><span class='Value'>a</span></code> and <code><span class='Value'>b</span></code> in a namespace (or closure) initialized so that <code><span class='Value'>a</span><span class='Function'></span><span class='Value'>b</span></code>, and all exported operations maintain the property that <code><span class='Value'>a</span><span class='Function'></span><span class='Value'>b</span></code>, then that property will always be true. Well, not quite: if you define, say <code><span class='Function'>Inc</span> <span class='Gets'></span> <span class='Function'>IncA</span> <span class='Function'></span> <span class='Function'>IncB</span></code> to increase the values of both <code><span class='Value'>a</span></code> and <code><span class='Value'>b</span></code> by <code><span class='Value'>𝕩</span></code>, then <code><span class='Function'>Inc</span></code> maintains <code><span class='Value'>a</span><span class='Function'></span><span class='Value'>b</span></code>, but <code><span class='Function'>IncA</span></code> doesn't—and it can be extracted with <code><span class='Function'>•Decompose</span></code>. This isn't too serious because it sounds impossible to do accidentally, and it's easy to protect against.</p>
<h3 id="strands-go-left-to-right"><a class="header" href="#strands-go-left-to-right">Strands go left to right</a></h3>
<p>This is the best ordering, since it's consistent with <code><span class='Bracket'></span><span class='Separator'></span><span class='Bracket'></span></code> lists. And code in a strand probably shouldn't have side effects anyway. Still, it's an odd little tack-on to say separators <em>and strands</em> go left to right, and it complicates the implementation a little.</p>
<h3 id="primitive-name-capitalization"><a class="header" href="#primitive-name-capitalization">Primitive name capitalization</a></h3>
<p>I went with &quot;Index of&quot; and &quot;Less Than or Equal to&quot; but the last word blends into surrounding text. Should they be fully capitalized or hyphenated? I've started to capitalize when there's ambiguity actually.</p>
<h2 id="solved-problems"><a class="header" href="#solved-problems">Solved problems</a></h2>
<p>Problems that existed in mainstream APL or a transitional BQN that have in my opinion been put to rest (while in some cases introducing new problems). Listed in reverse chronological order by time solved, by my recollection.</p>
<h3 id="trigonometry"><a class="header" href="#trigonometry">Trigonometry</a></h3>
<p>Solved with namespaces. dzaima/BQN uses <code><span class='Value'>•math</span></code> to expose math functions, but it could also be provided in a system library (still deciding). It's up to the implementation how the functions are implemented.</p>
<p>There are a lot of standard functions and I don't want to use separate primitives or a menu-style primitive like APL Circle for them. You can define all the functions eventually if you use complex exponential and take real and imaginary parts and inverses, but this doesn't sound well-suited for implementation. And there should be a math library that gives you the standard functions with normal names, but how will it be implemented?</p>
<h3 id="should-have-a-rounding-function"><a class="header" href="#should-have-a-rounding-function">Should have a rounding function</a></h3>
<p>Also placed in the math namespace.</p>
<p>There is a standard way to round floats—to nearest integer, ties to even—but it's fairly hard to implement and would have to be specially recognized for performance. It would be nice to have a better way to access this.</p>
<h3 id="array-reductions-are-annoying"><a class="header" href="#array-reductions-are-annoying">Array reductions are annoying</a></h3>
<p>There are really three kinds of reduction a BQN programmer might want to use.</p>
<ul>
<li><code><span class='Function'>𝔽</span><span class='Modifier'>´</span></code> Apply the function between elements of a list (Lisp).</li>
<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"><a class="header" href="#modifier-and-composition-terminology">&quot;Modifier&quot; and &quot;composition&quot; terminology</a></h3>
<p>1-modifiers and 2-modifiers used to be called &quot;modifiers&quot; and &quot;compositions&quot;, respectively, and sometimes &quot;operators&quot; collectively. The new names are much better, although they do leave a disconnect between the names for modifiers, and those for their inputs—&quot;operands&quot;.</p>
<h3 id="cant-return-from-inner-functions"><a class="header" href="#cant-return-from-inner-functions">Can't return from inner functions</a></h3>
<p>Fixed by adding block returns such as <code><span class='Value'>label</span><span class='Gets'></span></code> to jump out of a block with header name <code><span class='Value'>label</span></code>. Hopefully these don't cause too many new problems.</p>
<p>This was an issue with using functions as control flow. For example, when looping through an array with Each, you can't decide to exit early. In a curly-brace language you would just use a for loop and a return. In BQN, we need… longjmp? Maybe not as crazy as it sounds, and potentially worth it in exchange for replacing control structures.</p>
<h3 id="ambivalent-explicit-functions"><a class="header" href="#ambivalent-explicit-functions">Ambivalent explicit functions</a></h3>
<p>Fixed with multiple bodies: if there are two bodies with no headers such as <code><span class='Brace'>{</span><span class='Number'>2</span><span class='Function'>×</span><span class='Value'>𝕩</span><span class='Head'>;</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"><a class="header" href="#how-to-choose-a-partitioning-function">How to choose a partitioning function?</a></h3>
<p>Fixed with <a href="../doc/group.html">Group</a>, which I found May 2020. Group serves as a much improved <a href="https://aplwiki.com/wiki/Partition">Partition</a>. Later extended to multiple axes as well to get all the functionality.</p>
<h3 id="key-doesnt-do-what-you-want"><a class="header" href="#key-doesnt-do-what-you-want">Key doesn't do what you want</a></h3>
<p>Fixed with <a href="../doc/group.html">Group</a> to my satisfaction, except for the trailing-empty-group problem. There were various issues with Key operators in J and Dyalog, such as the fact that the ordering and presence of groups depends on where and whether the keys appear. Also, Dyalog's Key can return keys and values, but they are in a different format than the input: an array of pairs instead of two arrays. Monadic Group returns indices, which can be used how the programmer wants.</p>
<h3 id="greek-letter-issues"><a class="header" href="#greek-letter-issues">Greek letter issues</a></h3>
<p>Fixed by not using Greek letters. In particular, the idea of using fancy Latin letters as fixed names for function arguments was suggested in proto-BQN sessions, possibly by Nathan Rogers.</p>
<h3 id="stranding-gotchas"><a class="header" href="#stranding-gotchas">Stranding gotchas</a></h3>
<p>Fixed with list notation, which descends from the array notation developed by Phil Last and later Adám Brudzewsky. The problem that array notation has much more cluttered syntax than stranding has pretty much been fixed by the ligature character <code><span class='Ligature'></span></code>, which I discovered during proto-BQN discussions.</p>
<h3 id="functions-are-not-first-class"><a class="header" href="#functions-are-not-first-class">Functions are not first class</a></h3>
<p>Fixed by allowing a variable to be written with a different syntactic role than it was created with, suggested by Adám in proto-BQN discussions.</p>
<h3 id="apl-is-not-context-free"><a class="header" href="#apl-is-not-context-free">APL is not context-free</a></h3>
<p>Fixed with the casing conventions for variable names, which I think I first saw in <a href="https://aplwiki.com/wiki/APL%5Civ">APL\iv</a>, although the cases are swapped relative to BQN.</p>
<h3 id="selective-assignment-requires-a-named-variable"><a class="header" href="#selective-assignment-requires-a-named-variable">Selective assignment requires a named variable</a></h3>
<p>Fixed with structural Under, which I developed in 2017 and 2018.</p>
<h3 id="its-hard-use-an-array-as-a-major-cell"><a class="header" href="#its-hard-use-an-array-as-a-major-cell">It's hard use an array as a major cell</a></h3>
<p>Fixed with <code><span class='Function'></span></code>: dyadic form from A+ and monadic/dyadic pair from J.</p>
<h3 id="scan-and-windowed-reduce-shouldnt-always-reduce"><a class="header" href="#scan-and-windowed-reduce-shouldnt-always-reduce">Scan and Windowed Reduce shouldn't always reduce</a></h3>
<p>Fixed with Prefix, Suffix, and Infix operators in J. Changed to functions in BQN.</p>