aboutsummaryrefslogtreecommitdiff
path: root/docs/commentary/why.html
diff options
context:
space:
mode:
Diffstat (limited to 'docs/commentary/why.html')
-rw-r--r--docs/commentary/why.html2
1 files changed, 1 insertions, 1 deletions
diff --git a/docs/commentary/why.html b/docs/commentary/why.html
index 77048ae3..d559b8ef 100644
--- a/docs/commentary/why.html
+++ b/docs/commentary/why.html
@@ -42,7 +42,7 @@
<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>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.</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 behaves just like <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>Gerunds are J's answer to BQN's first-class functions. For example J's <code><span class='Paren'>(</span><span class='Function'>+</span><span class='Value'>&amp;</span><span class='Number'>3</span><span class='Paren'>)</span><span class='Modifier'>`</span><span class='Paren'>(</span><span class='Number'>2</span><span class='Value'>&amp;*</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'>3</span><span class='Separator'>,</span><span class='Number'>2</span><span class='Modifier2'>⊸</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>