aboutsummaryrefslogtreecommitdiff
path: root/docs/commentary
diff options
context:
space:
mode:
Diffstat (limited to 'docs/commentary')
-rw-r--r--docs/commentary/history.html8
-rw-r--r--docs/commentary/problems.html4
-rw-r--r--docs/commentary/why.html32
3 files changed, 22 insertions, 22 deletions
diff --git a/docs/commentary/history.html b/docs/commentary/history.html
index 77ebec7f..cb296237 100644
--- a/docs/commentary/history.html
+++ b/docs/commentary/history.html
@@ -140,7 +140,7 @@
<td align="right">-05</td>
<td><a href="https://aplwiki.com/wiki/Ngn/apl">ngn/apl</a></td>
<td>Nikolov</td>
-<td>Multiple function bodies <code><span class='Value'>;</span></code></td>
+<td>Multiple function bodies <code><span class='Head'>;</span></code></td>
<td></td>
</tr>
<tr>
@@ -161,14 +161,14 @@
<td align="right"></td>
<td></td>
<td>dzaima</td>
-<td>Inverse headers <code><span class='Function'>𝕊</span><span class='Modifier'>⁼</span><span class='Value'>:</span></code></td>
+<td>Inverse headers <code><span class='Function'>𝕊</span><span class='Modifier'>⁼</span><span class='Head'>:</span></code></td>
<td><a href="https://chat.stackexchange.com/transcript/52405?m=54639280#54639280">0</a>, <a href="https://chat.stackexchange.com/transcript/message/55860071#55860071">1</a></td>
</tr>
<tr>
<td align="right"></td>
<td></td>
<td>w/ dzaima</td>
-<td>Headers <code><span class='Value'>:</span></code></td>
+<td>Headers <code><span class='Head'>:</span></code></td>
<td><a href="https://chat.stackexchange.com/transcript/52405?m=54768112#54768112">0</a>, <a href="https://chat.stackexchange.com/transcript/message/54776688#54776688">1</a></td>
</tr>
<tr>
@@ -213,7 +213,7 @@
<h4 id="double-struck-special-names"><a class="header" href="#double-struck-special-names">Double-struck special names</a></h4>
<p>There was a lot of discussion about names for arguments at YAG (no one liked alpha and omega); I think Nathan Rogers suggested using Unicode's mathematical variants of latin letters and I picked out the double-struck ones. My impression is that we were approaching a general concensus that &quot;w&quot; and &quot;x&quot; were the best of several bad choices of argument letters, but that I was the first to commit to them.</p>
<h4 id="assert-primitive"><a class="header" href="#assert-primitive">Assert primitive</a></h4>
-<p>Nathan Rogers suggested that assertion should be made a primitive to elevate it to a basic part of the language. I used J's <code><span class='Value'>assert</span></code> often enough for this idea to make sense immediately, but I think it was new to me. He suggested the dagger character; I changed this to the somewhat similar-looking <code><span class='Function'>!</span></code>. The error-trapping modifier <code><span class='Modifier2'>⎊</span></code> is identical to J's <code><span class='Value'>::</span></code>, but J only has the function <code><span class='Value'>[:</span></code> to unconditionally throw an error, with no way to set a message.</p>
+<p>Nathan Rogers suggested that assertion should be made a primitive to elevate it to a basic part of the language. I used J's <code><span class='Value'>assert</span></code> often enough for this idea to make sense immediately, but I think it was new to me. He suggested the dagger character; I changed this to the somewhat similar-looking <code><span class='Function'>!</span></code>. The error-trapping modifier <code><span class='Modifier2'>⎊</span></code> is identical to J's <code><span class='Head'>::</span></code>, but J only has the function <code><span class='Value'>[</span><span class='Head'>:</span></code> to unconditionally throw an error, with no way to set a message.</p>
<h4 id="context-free-grammar"><a class="header" href="#context-free-grammar">Context-free grammar</a></h4>
<p>In YAG meetings, I suggested adopting <a href="https://aplwiki.com/wiki/APL%5Civ">APL\iv</a>'s convention that variable case must match variable type in order to achieve a context-free grammar. Adám, a proponent of case-insensitive names, pointed out that the case might indicate the type the programmer wanted to use instead of the value's type, creating cross roles. Although I considered swapping subjects and functions, I ended up using exactly the conventions of his APL <a href="https://abrudz.github.io/style/#nc">style guide</a>.</p>
<h4 id="headers"><a class="header" href="#headers">Headers</a></h4>
diff --git a/docs/commentary/problems.html b/docs/commentary/problems.html
index 8b9f0955..4199ddaa 100644
--- a/docs/commentary/problems.html
+++ b/docs/commentary/problems.html
@@ -56,7 +56,7 @@
<h3 id="cant-mix-define-and-modify-in-multiple-assignment"><a class="header" href="#cant-mix-define-and-modify-in-multiple-assignment">Can't mix define and modify in multiple assignment</a></h3>
<p>Say <code><span class='Value'>a</span></code> is a pair and <code><span class='Value'>h</span></code> isn't defined yet; how would you set <code><span class='Value'>h</span></code> to the first element of <code><span class='Value'>a</span></code> and change <code><span class='Value'>a</span></code> to be just the second? <code><span class='Value'>h</span><span class='Ligature'>‿</span><span class='Value'>a</span><span class='Gets'>↩</span><span class='Value'>a</span></code> doesn't work because <code><span class='Value'>h</span></code> isn't defined, so the best I have is <code><span class='Value'>h</span><span class='Gets'>←</span><span class='String'>@</span><span class='Separator'>⋄</span><span class='Value'>h</span><span class='Ligature'>‿</span><span class='Value'>a</span><span class='Gets'>↩</span><span class='Value'>a</span></code>. A heavier assignment syntax wouldn't break down; BQN could allow <code><span class='Bracket'>⟨</span><span class='Value'>h</span><span class='Gets'>←</span><span class='Separator'>,</span><span class='Value'>a</span><span class='Bracket'>⟩</span><span class='Gets'>↩</span><span class='Value'>a</span></code> but I don't think this merits special syntax.</p>
<h3 id="trains-dont-like-monads"><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></code>) in a train, but still a minor frustration.</p>
+<p>If you have the normal mix of monads and dyads you'll need a lot of parentheses and might end up abusing <code><span class='Modifier2'>⟜</span></code>. Largely solved with the Nothing syntax <code><span class='Nothing'>·</span></code>, which acts like J's Cap (<code><span class='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="axis-ordering-is-big-endian"><a class="header" href="#axis-ordering-is-big-endian">Axis ordering is big-endian</a></h3>
@@ -155,7 +155,7 @@
<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='Function'>-</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code>, they are the monadic and dyadic case.</p>
+<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>
diff --git a/docs/commentary/why.html b/docs/commentary/why.html
index e7c80e61..158dc679 100644
--- a/docs/commentary/why.html
+++ b/docs/commentary/why.html
@@ -32,32 +32,32 @@
<p>BQN's Power modifier <code><span class='Modifier2'>⍟</span></code> allows an array operand to specify multiple results, for example <code><span class='Function'>Fn</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Function'>↕</span><span class='Number'>4</span><span class='Paren'>)</span></code> to get 0 up to 3 iterations. Intermediate results are saved, so the number of calls only depends on the highest iteration number present. On the other hand, BQN has no direct equivalent of Power Limit <code><span class='Value'>⍣</span><span class='Function'>≡</span></code>, requiring it to be <a href="https://mlochbaum.github.io/bqncrate/?q=power%20limit">implemented manually</a>.</p>
<p>An APL selective assignment <code><span class='Value'>arr[</span><span class='Number'>2</span> <span class='Number'>3</span><span class='Value'>]</span><span class='Function'>+</span><span class='Gets'>←</span><span class='Number'>1</span></code> should usually be written with Under in BQN: <code><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span><span class='Paren'>)</span><span class='Value'>arr</span></code> (but the correspondence might not always be so direct). You can think of this as a very fancy At (<code><span class='String'>@</span></code>) operator, that lets you pull out an arbitrary part of an array.</p>
<p>Dfns are adjusted in a few ways that make them more useful for general-purpose programming. A BQN block always runs to the last statement, so a block like <code><span class='Brace'>{</span><span class='Function'>Update</span> <span class='Value'>𝕩</span> <span class='Separator'>⋄</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Value'>x</span><span class='Brace'>}</span></code> won't return early. Writing modification with <code><span class='Gets'>↩</span></code> makes it clearer which variable's which. Dfns also do a weird shadowing thing where <code><span class='Value'>a</span><span class='Gets'>←</span><span class='Number'>1</span><span class='Separator'>⋄</span><span class='Value'>a</span><span class='Gets'>←</span><span class='Number'>2</span></code> makes two different variables; in BQN this is an error because the second should use <code><span class='Gets'>↩</span></code>. Tradfns are removed entirely, along with control structures.</p>
-<p>BQN doesn't have an exact replacement for dfn guards, although the predicate <code><span class='Value'>?</span></code> can look similar: <code><span class='Brace'>{</span><span class='Number'>2</span><span class='Function'>|</span><span class='Value'>⍵</span> <span class='Value'>:</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×</span><span class='Value'>⍵</span> <span class='Separator'>⋄</span> <span class='Value'>⍵</span><span class='Function'>÷</span><span class='Number'>2</span><span class='Brace'>}</span></code> is equivalent to <code><span class='Brace'>{</span><span class='Number'>2</span><span class='Function'>|</span><span class='Value'>𝕩</span> <span class='Value'>?</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×</span><span class='Value'>𝕩</span> <span class='Value'>;</span> <span class='Value'>𝕩</span><span class='Function'>÷</span><span class='Number'>2</span><span class='Brace'>}</span></code>. But note that where APL uses the statement separator <code><span class='Separator'>⋄</span></code>, BQN uses the body separator <code><span class='Value'>;</span></code>. This means that the if-true branch in BQN can consist of multiple statements (including additional predicates), but also that the if-false branch can't access variables defined in or before the condition. In both cases the &quot;better&quot; behavior can be obtained with an extra set of braces and possibly assigning names to arguments <code><span class='Value'>⍵</span></code>/<code><span class='Value'>𝕩</span></code>. I think guards end up being cleaner when they work, and predicates are more versatile.</p>
+<p>BQN doesn't have an exact replacement for dfn guards, although the predicate <code><span class='Head'>?</span></code> can look similar: <code><span class='Brace'>{</span><span class='Number'>2</span><span class='Function'>|</span><span class='Value'>⍵</span> <span class='Head'>:</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×</span><span class='Value'>⍵</span> <span class='Separator'>⋄</span> <span class='Value'>⍵</span><span class='Function'>÷</span><span class='Number'>2</span><span class='Brace'>}</span></code> is equivalent to <code><span class='Brace'>{</span><span class='Number'>2</span><span class='Function'>|</span><span class='Value'>𝕩</span> <span class='Head'>?</span> <span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×</span><span class='Value'>𝕩</span> <span class='Head'>;</span> <span class='Value'>𝕩</span><span class='Function'>÷</span><span class='Number'>2</span><span class='Brace'>}</span></code>. But note that where APL uses the statement separator <code><span class='Separator'>⋄</span></code>, BQN uses the body separator <code><span class='Head'>;</span></code>. This means that the if-true branch in BQN can consist of multiple statements (including additional predicates), but also that the if-false branch can't access variables defined in or before the condition. In both cases the &quot;better&quot; behavior can be obtained with an extra set of braces and possibly assigning names to arguments <code><span class='Value'>⍵</span></code>/<code><span class='Value'>𝕩</span></code>. I think guards end up being cleaner when they work, and predicates are more versatile.</p>
<p>BQN's namespaces have a dedicated syntax, are <em>much</em> easier to create than Dyalog namespaces, and have better performance. I use them all the time, and they feel like a natural part of the language.</p>
<h3 id="j"><a class="header" href="#j">J</a></h3>
<p><em>See also the <a href="../doc/fromJ.html">BQN-J dictionary</a>. J is under development again and a moving target. I stopped using it completely shortly after starting work on BQN in 2020, and while I try to keep up to date on language changes, some remarks here might not fit with the experience you'd get starting with J today.</em></p>
<p>To me building with J feels like making a tower out of wood and nails by hand: J itself is reliable but I soon don't trust what I'm standing on. J projects start to feel hacky when I have multiple files, locales, or a bit of global state. With BQN I begin to worry about maintainability only when I have enough functions that I can't remember what arguments they expect, and with lexically-scoped variables I simply don't use global state. If you don't reach this scale (in particular, if you use J as a calculator or spreadsheet substitute) you won't feel these concerns, and will have less to gain by moving to BQN. And if you go beyond, you'd need to augment your programs with rigorous documentation and testing in either language.</p>
-<p>The biggest difference could be in file loading. If you write a script that depends on other files, and want it to work regardless of the directory it's called from, you need to deal with this. In J, <code><span class='Function'>&gt;</span><span class='Brace'>{</span><span class='Value'>:</span><span class='Number'>4</span><span class='Function'>!</span><span class='Value'>:</span><span class='Number'>3</span> <span class='String'>''</span></code> gives the name of the most recently loaded script (the current one, if you put it before any imports), but to make it into a utility you need this glob of what's-going-on:</p>
-<pre><span class='Value'>cur_script</span> <span class='Function'>=</span><span class='Value'>:</span> <span class='Brace'>{{</span><span class='Paren'>(</span><span class='Number'>4</span><span class='Function'>!</span><span class='Value'>:</span><span class='Number'>3</span><span class='Value'>$</span><span class='Number'>0</span><span class='Paren'>)</span> <span class='Brace'>{</span><span class='Value'>::~</span> <span class='Number'>4</span><span class='Function'>!</span><span class='Value'>:</span><span class='Number'>4</span><span class='Function'>&lt;</span><span class='String'>'y'</span><span class='Brace'>}}</span>
+<p>The biggest difference could be in file loading. If you write a script that depends on other files, and want it to work regardless of the directory it's called from, you need to deal with this. In J, <code><span class='Function'>&gt;</span><span class='Brace'>{</span><span class='Head'>:</span><span class='Number'>4</span><span class='Function'>!</span><span class='Head'>:</span><span class='Number'>3</span> <span class='String'>''</span></code> gives the name of the most recently loaded script (the current one, if you put it before any imports), but to make it into a utility you need this glob of what's-going-on:</p>
+<pre><span class='Value'>cur_script</span> <span class='Function'>=</span><span class='Head'>:</span> <span class='Brace'>{{</span><span class='Paren'>(</span><span class='Number'>4</span><span class='Function'>!</span><span class='Head'>:</span><span class='Number'>3</span><span class='Value'>$</span><span class='Number'>0</span><span class='Paren'>)</span> <span class='Brace'>{</span><span class='Head'>::</span><span class='Value'>~</span> <span class='Number'>4</span><span class='Function'>!</span><span class='Head'>:</span><span class='Number'>4</span><span class='Function'>&lt;</span><span class='String'>'y'</span><span class='Brace'>}}</span>
</pre>
<p>In BQN it's <code><span class='Value'>•path</span></code>. And usually you don't need it because <code><span class='Function'>•Import</span></code> resolves paths relative to the file containing it.</p>
-<p>J uses numeric codes; BQN uses mostly names. So J's <code><span class='Number'>1</span><span class='Value'>&amp;o.</span></code> is BQN's <code><span class='Value'>•math.</span><span class='Function'>Sin</span></code>, and <code><span class='Number'>6</span><span class='Function'>!</span><span class='Value'>:</span><span class='Number'>9</span></code> corresponds to BQN's <code><span class='Function'>•MonoTime</span></code>.</p>
-<p>J uses bytestrings by default, making Unicode handling a significant difficulty (<a href="https://code.jsoftware.com/wiki/Vocabulary/uco">see</a> <code><span class='Value'>u:</span></code>). BQN strings are lists of codepoints, so you don't have to worry about how they're encoded or fight to avoid splitting up UTF-8 bytes that need to go together.</p>
+<p>J uses numeric codes; BQN uses mostly names. So J's <code><span class='Number'>1</span><span class='Value'>&amp;o.</span></code> is BQN's <code><span class='Value'>•math.</span><span class='Function'>Sin</span></code>, and <code><span class='Number'>6</span><span class='Function'>!</span><span class='Head'>:</span><span class='Number'>9</span></code> corresponds to BQN's <code><span class='Function'>•MonoTime</span></code>.</p>
+<p>J uses bytestrings by default, making Unicode handling a significant difficulty (<a href="https://code.jsoftware.com/wiki/Vocabulary/uco">see</a> <code><span class='Value'>u</span><span class='Head'>:</span></code>). BQN strings are lists of codepoints, so you don't have to worry about how they're encoded or fight to avoid splitting up UTF-8 bytes that need to go together.</p>
<p>But J has its type advantages as well. I miss complex number support in BQN, as it's an optional extension that we haven't yet implemented. And BQN has a hard rule that only one numeric type is exposed to the programmer, which means high-precision integers and rationals aren't allowed at all for a float-based implementation. I think this rule is worth it because J's implicit type conversion is hard to predict and an unexpected numeric type can cause sporadic or subtle program errors.</p>
<p>BQN uses a modifier <code><span class='Modifier2'>⟜</span></code> for J's hook, adding <code><span class='Modifier2'>⊸</span></code> for a reversed version (which I use nearly twice as often). This frees up the 2-train, which is made equivalent to Atop (<code><span class='Modifier2'>∘</span></code>). It's the system Roger Hui came to advocate, since he argued in favor of a hook conjunction <a href="https://code.jsoftware.com/wiki/Essays/Hook_Conjunction%3F">here</a> and made 2-train an Atop when he brought it to Dyalog APL. As an example, the J hook <code><span class='Paren'>(</span><span class='Comment'>#~0&amp;&lt;:)</span></code> to remove negative numbers becomes <code><span class='Number'>0</span><span class='Modifier2'>⊸</span><span class='Function'>≤</span><span class='Modifier2'>⊸</span><span class='Function'>/</span></code> in BQN. Hooks are also the topic of <a href="https://www.arraycast.com/episodes/episode17-tacit4-the-dyadic-hook">Array Cast episode 14</a>, where the panel points out that in J, adding a verb at the far left of a dyadic train changes the rest of the train from dyadic to monadic or vice-versa, an effect that doesn't happen in BQN.</p>
<p>J locales are not first-class values, and BQN namespaces are. I think BQN's namespaces are a lot more convenient to construct, although it is lacking an inheritance mechanism (but J's path system can become confusing quickly). More importantly, BQN namespaces (and closures) are garbage collected. J locales leak unless manually freed by the programmer. More generally, J has no mutable data at all, and to simulate it properly you'd have to write your own tracing garbage collection as the J interpreter doesn't have any. I discussed this issue some in <a href="http://www.jsoftware.com/pipermail/programming/2021-April/058006.html">this J forum thread</a>.</p>
-<p>In J, each function has a built-in rank attribute: for example the ranks of <code><span class='Function'>+</span></code> are <code><span class='Number'>0</span> <span class='Number'>0</span> <span class='Number'>0</span></code>. This rank is accessed by the &quot;close&quot; compositions <code><span class='String'>@</span></code>, <code><span class='Value'>&amp;</span></code>, and <code><span class='Value'>&amp;.</span></code>. Choosing the shorter form for the close compositions—for example <code><span class='String'>@</span></code> rather than <code><span class='String'>@</span><span class='Value'>:</span></code>—is often considered a mistake within the J community. And function ranks are unreliable: consider that the ranks of <code><span class='Value'>]</span><span class='String'>@</span><span class='Value'>:</span><span class='Function'>+</span></code>, a function that always has the same result as <code><span class='Function'>+</span></code>, are <code><span class='Modifier2'>_</span> <span class='Modifier2'>_</span> <span class='Modifier2'>_</span></code>. In BQN there aren't any close compositions at all, and no function ranks. J's <code><span class='Value'>&amp;.</span><span class='Function'>&gt;</span></code> is simply <code><span class='Modifier'>¨</span></code>, and other close compositions, in my opinion, just aren't needed.</p>
+<p>In J, each function has a built-in rank attribute: for example the ranks of <code><span class='Function'>+</span></code> are <code><span class='Number'>0</span> <span class='Number'>0</span> <span class='Number'>0</span></code>. This rank is accessed by the &quot;close&quot; compositions <code><span class='String'>@</span></code>, <code><span class='Value'>&amp;</span></code>, and <code><span class='Value'>&amp;.</span></code>. Choosing the shorter form for the close compositions—for example <code><span class='String'>@</span></code> rather than <code><span class='String'>@</span><span class='Head'>:</span></code>—is often considered a mistake within the J community. And function ranks are unreliable: consider that the ranks of <code><span class='Value'>]</span><span class='String'>@</span><span class='Head'>:</span><span class='Function'>+</span></code>, a function that always has the same result as <code><span class='Function'>+</span></code>, are <code><span class='Modifier2'>_</span> <span class='Modifier2'>_</span> <span class='Modifier2'>_</span></code>. In BQN there aren't any close compositions at all, and no function ranks. J's <code><span class='Value'>&amp;.</span><span class='Function'>&gt;</span></code> is simply <code><span class='Modifier'>¨</span></code>, and other close compositions, in my opinion, just aren't needed.</p>
<p>J has several adverbs (key, prefix, infix, outfix…) to slice up an argument in various ways and apply a verb to those parts. In BQN, I rejected this approach: there are 1-modifiers for basic iteration patterns, and functions such as <a href="../doc/group.html">Group</a> (<code><span class='Function'>⊔</span></code>) that do the slicing but don't apply anything. So <code><span class='Function'>&lt;/</span><span class='Value'>.~a</span></code> is <code><span class='Function'>⊐</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span><span class='Value'>a</span></code>, but <code><span class='Value'>fn</span><span class='Function'>/</span><span class='Value'>.~a</span></code> is <code><span class='Function'>&gt;Fn</span><span class='Modifier'>¨</span><span class='Function'>⊐</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span><span class='Value'>a</span></code> (I also reject J's implicit merge except for the Rank modifier, as I don't think function results should be homogeneous by default). BQN's approach composes better, and is more predictable from a performance perspective.</p>
<p>Gerunds are J's answer to BQN's first-class functions. For example J's <code><span class='Paren'>(</span><span class='Value'>%&amp;</span><span class='Number'>2</span><span class='Paren'>)</span><span class='Modifier'>`</span><span class='Paren'>(</span><span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Value'>*]</span><span class='Paren'>)</span><span class='String'>@</span><span class='Value'>.</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Value'>&amp;</span><span class='Function'>|</span><span class='Paren'>)</span></code> would be written <code><span class='Number'>2</span><span class='Modifier2'>⊸</span><span class='Function'>|</span><span class='Modifier2'>◶</span><span class='Bracket'>⟨</span><span class='Function'>÷</span><span class='Modifier2'>⟜</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Number'>1</span><span class='Function'>+</span><span class='Number'>3</span><span class='Function'>×⊢</span><span class='Bracket'>⟩</span></code> with a list of functions. I think lists of functions are a big improvement, since there's no need to convert between gerund and function, and no worries about arrays that just happen to be valid gerunds (worried about losing the ability to construct gerunds? Constructing tacit functions in BQN is much easier). The usability gap widens because passing J functions around either as values or gerunds has presents some highly idiosyncratic challenges, discussed below.</p>
<h4 id="named-functions"><a class="header" href="#named-functions">Named functions</a></h4>
<p>Its impact on the programmer is smaller than a lot of the issues above, but this section describes a behavior that I find pretty hard to justify. What does the identifier <code><span class='Value'>fn</span></code> indicate in a J expression? The value of <code><span class='Value'>fn</span></code> in the current scope, one might suppose. Nope—only if the value is a noun. Let's make it a function.</p>
-<pre> <span class='Value'>fn</span> <span class='Function'>=</span><span class='Value'>:</span> <span class='Function'>-</span>
+<pre> <span class='Value'>fn</span> <span class='Function'>=</span><span class='Head'>:</span> <span class='Function'>-</span>
<span class='Value'>fn</span><span class='Modifier'>`</span><span class='Function'>-</span>
<span class='Value'>┌──┬─┐</span>
<span class='Value'>│fn│</span><span class='Function'>-</span><span class='Value'>│</span>
<span class='Value'>└──┴─┘</span>
</pre>
-<p>The tie adverb <code><span class='Modifier'>`</span></code> makes gerund representations of both operands and places them in a list. It returns <code><span class='String'>'</span><span class='Value'>fn</span><span class='String'>'</span><span class='Value'>;</span><span class='Separator'>,</span><span class='String'>'-'</span></code> here: two different strings for what we'd think of as the same function. But it's just being honest. The value of <code><span class='Value'>fn</span></code> really is more like a name than the primitive <code><span class='Function'>-</span></code>. To see this we can pass it in to an adverb that defines its own local, totally separate copy of <code><span class='Value'>fn</span></code>.</p>
+<p>The tie adverb <code><span class='Modifier'>`</span></code> makes gerund representations of both operands and places them in a list. It returns <code><span class='String'>'</span><span class='Value'>fn</span><span class='String'>'</span><span class='Head'>;</span><span class='Separator'>,</span><span class='String'>'-'</span></code> here: two different strings for what we'd think of as the same function. But it's just being honest. The value of <code><span class='Value'>fn</span></code> really is more like a name than the primitive <code><span class='Function'>-</span></code>. To see this we can pass it in to an adverb that defines its own local, totally separate copy of <code><span class='Value'>fn</span></code>.</p>
<pre> <span class='Value'>fn</span><span class='Brace'>{{</span><span class='Value'>u</span> <span class='Number'>3</span><span class='Brace'>}}</span>
<span class='Modifier'>_3</span>
<span class='Value'>fn</span><span class='Brace'>{{</span>
@@ -67,27 +67,27 @@
<span class='Number'>0.333333</span>
</pre>
<p>That's right, it is not safe to use <code><span class='Value'>fn</span></code> as an operand! Instead you're expected to write <code><span class='Value'>fn</span> <span class='Value'>f.</span></code>, where <code><span class='Value'>f.</span></code> (<a href="https://code.jsoftware.com/wiki/Vocabulary/fdot">fix</a>) is a primitive that recursively expands all the names. Okay, but if you didn't have these weird name wrappers everywhere you wouldn't have to expand them. Why?</p>
-<pre> <span class='Value'>a</span> <span class='Function'>=</span><span class='Value'>:</span> <span class='Number'>3</span> <span class='Function'>+</span> <span class='Value'>b</span>
- <span class='Value'>b</span> <span class='Function'>=</span><span class='Value'>:</span> <span class='Value'>a^:</span><span class='Paren'>(</span><span class='Number'>10</span><span class='Value'>&amp;</span><span class='Function'>&lt;</span><span class='Paren'>)</span> <span class='String'>@</span><span class='Value'>:</span> <span class='Function'>-</span><span class='Value'>:</span>
+<pre> <span class='Value'>a</span> <span class='Function'>=</span><span class='Head'>:</span> <span class='Number'>3</span> <span class='Function'>+</span> <span class='Value'>b</span>
+ <span class='Value'>b</span> <span class='Function'>=</span><span class='Head'>:</span> <span class='Value'>a^</span><span class='Head'>:</span><span class='Paren'>(</span><span class='Number'>10</span><span class='Value'>&amp;</span><span class='Function'>&lt;</span><span class='Paren'>)</span> <span class='String'>@</span><span class='Head'>:</span> <span class='Function'>-</span><span class='Head'>:</span>
<span class='Value'>b</span> <span class='Number'>100</span>
<span class='Number'>15.25</span>
</pre>
<p>This feature allows tacit recursion and mutual recursion. You can't do this in BQN, because <code><span class='Function'>A</span> <span class='Gets'>←</span> <span class='Number'>3</span> <span class='Function'>+</span> <span class='Function'>B</span></code> with no <code><span class='Function'>B</span></code> defined is a reference to an undefined identifier. You have to use <code><span class='Brace'>{</span><span class='Function'>B</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> instead. So this is actually kind of nice. 'Cept it's broken:</p>
<pre> <span class='Value'>b</span> <span class='Value'>f.</span> <span class='Function'>NB</span><span class='Value'>.</span> <span class='Value'>impossible</span> <span class='Value'>to</span> <span class='Value'>fix</span> <span class='Value'>all</span> <span class='Value'>the</span> <span class='Value'>way</span>
-<span class='Paren'>(</span><span class='Number'>3</span> <span class='Function'>+</span> <span class='Value'>b</span><span class='Paren'>)</span><span class='Value'>^:</span><span class='Paren'>(</span><span class='Number'>10</span><span class='Value'>&amp;</span><span class='Function'>&lt;</span><span class='Paren'>)</span><span class='String'>@</span><span class='Value'>:</span><span class='Function'>-</span><span class='Value'>:</span>
+<span class='Paren'>(</span><span class='Number'>3</span> <span class='Function'>+</span> <span class='Value'>b</span><span class='Paren'>)</span><span class='Value'>^</span><span class='Head'>:</span><span class='Paren'>(</span><span class='Number'>10</span><span class='Value'>&amp;</span><span class='Function'>&lt;</span><span class='Paren'>)</span><span class='String'>@</span><span class='Head'>:</span><span class='Function'>-</span><span class='Head'>:</span>
<span class='Value'>b</span> <span class='Value'>f.</span><span class='Brace'>{{</span>
<span class='Value'>b</span> <span class='Function'>=</span><span class='Value'>.</span> <span class='Number'>2</span>
<span class='Value'>u</span> <span class='Number'>100</span>
<span class='Brace'>}}</span>
-<span class='Function'>|</span><span class='Value'>domain</span> <span class='Value'>error:</span> <span class='Value'>b</span>
+<span class='Function'>|</span><span class='Value'>domain</span> <span class='Value'>error</span><span class='Head'>:</span> <span class='Value'>b</span>
<span class='Function'>|</span> <span class='Value'>u</span> <span class='Number'>100</span>
</pre>
<p>A tacit-recursive function can't be called unless its definition is visible, period. We gained the ability to do this cool tacit recursion thing, and all it cost us was… the ability to reliably use functions as values at all, which should be one of the things tacit programming is <em>good</em> for.</p>
<p>It gets worse.</p>
-<pre> <span class='Value'>g</span> <span class='Function'>=</span><span class='Value'>:</span> <span class='Function'>-</span>
- <span class='Value'>f</span> <span class='Function'>=</span><span class='Value'>:</span> <span class='Value'>g</span>
- <span class='Value'>g</span> <span class='Function'>=</span><span class='Value'>:</span> <span class='Function'>|</span><span class='Value'>.</span>
+<pre> <span class='Value'>g</span> <span class='Function'>=</span><span class='Head'>:</span> <span class='Function'>-</span>
+ <span class='Value'>f</span> <span class='Function'>=</span><span class='Head'>:</span> <span class='Value'>g</span>
+ <span class='Value'>g</span> <span class='Function'>=</span><span class='Head'>:</span> <span class='Function'>|</span><span class='Value'>.</span>
<span class='Value'>f</span> <span class='Value'>i.</span> <span class='Number'>3</span>
<span class='Number'>2</span> <span class='Number'>1</span> <span class='Number'>0</span>
<span class='Function'>&lt;</span><span class='String'>@</span><span class='Value'>f</span> <span class='Value'>i.</span> <span class='Number'>3</span>
@@ -96,4 +96,4 @@
<span class='Value'>└─┴─┴─┘</span>
</pre>
<p>This should not be possible. <code><span class='Value'>f</span></code> here doesn't behave like <code><span class='Function'>+</span></code>, or quite like <code><span class='Function'>|</span><span class='Value'>.</span></code>: in fact there is no function that does what <code><span class='Value'>f</span></code> does. The result of <code><span class='Value'>f</span></code> depends on the entire argument, but <code><span class='Function'>&lt;</span><span class='String'>@</span><span class='Value'>f</span></code> encloses rank 0 components! How long would it take you to debug an issue like this? It's rare, but I've run into it in my own code and seen similar reports on the forums.</p>
-<p>The cause is that the value of <code><span class='Value'>f</span></code> here—a named <code><span class='Value'>g</span></code> function—is not just a name, but also comes with a function rank. The function rank is set by the assignment <code><span class='Value'>f</span> <span class='Function'>=</span><span class='Value'>:</span> <span class='Value'>g</span></code>, and doesn't change along with <code><span class='Value'>g</span></code>. Calling <code><span class='Value'>f</span></code> doesn't rely on the rank, but <code><span class='String'>@</span></code> does, so <code><span class='Function'>&lt;</span><span class='String'>@</span><span class='Value'>f</span></code> effectively becomes <code><span class='Function'>&lt;</span><span class='String'>@</span><span class='Function'>|</span><span class='Value'>.</span><span class='String'>&quot;</span><span class='Function'>-</span></code>, mixing the two versions of <code><span class='Value'>g</span></code>. The only explanation I have for this one is implementation convenience.</p>
+<p>The cause is that the value of <code><span class='Value'>f</span></code> here—a named <code><span class='Value'>g</span></code> function—is not just a name, but also comes with a function rank. The function rank is set by the assignment <code><span class='Value'>f</span> <span class='Function'>=</span><span class='Head'>:</span> <span class='Value'>g</span></code>, and doesn't change along with <code><span class='Value'>g</span></code>. Calling <code><span class='Value'>f</span></code> doesn't rely on the rank, but <code><span class='String'>@</span></code> does, so <code><span class='Function'>&lt;</span><span class='String'>@</span><span class='Value'>f</span></code> effectively becomes <code><span class='Function'>&lt;</span><span class='String'>@</span><span class='Function'>|</span><span class='Value'>.</span><span class='String'>&quot;</span><span class='Function'>-</span></code>, mixing the two versions of <code><span class='Value'>g</span></code>. The only explanation I have for this one is implementation convenience.</p>