aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2021-10-14 17:00:28 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2021-10-14 17:00:28 -0400
commit558804cbb1a365c3fae4c97b56e6603fe93cf028 (patch)
treee8e1987eb4e28cc0811a15c1221f447dafc23924
parentfa824e26ec41bc4795eae0e6e1f3cacb77118f62 (diff)
Remove indications that BQN might add tolerant comparison; it won't
-rw-r--r--commentary/problems.md10
-rw-r--r--doc/match.md2
-rw-r--r--docs/commentary/problems.html20
-rw-r--r--docs/doc/match.html4
-rw-r--r--spec/reference.bqn2
5 files changed, 8 insertions, 30 deletions
diff --git a/commentary/problems.md b/commentary/problems.md
index bf9ab494..4167ba27 100644
--- a/commentary/problems.md
+++ b/commentary/problems.md
@@ -44,13 +44,6 @@ Only `⍋⍒` use array ordering rather than just array equality or numeric orde
### Nothing (`Β·`) interacts strangely with Before and After
Since `𝕨F⊸G𝕩` is `(F𝕨)G𝕩` and `𝕨F⟜G𝕩` is `𝕨F G𝕩` in the dyadic case, we might expect these to devolve to `G𝕩` and `F G𝕩` when `𝕨` is not present. Not so: instead `𝕩` is substituted for the missing `𝕨`. And Before and After are also the main places where a programmer might try to use `𝕨` as an operand, which doesn't work either (the right way is the train `𝕨F⊒`). It's also a little strange that `v F˜·` is `Β·`, while `Β·F v` is `F v`.
-### Comparison tolerance
-Kind of necessary for practical programming, but how should it be invoked or controlled? A system variable like `βŽ•CT`? Per-primitive control? Both? Which primitives should use it?
-
-Definitely | Maybe | Definitely not
------------|------------|---------------
-`=≠≀β‰₯<>` | `β‰‘β‰’βŠβŠ’βˆŠβ·\|` | `⍋⍒`
-
### No access to fast high-precision sum
Fold has a specific order of application, which must be used for `` +` ``. 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.
@@ -74,6 +67,9 @@ In Choose, the selector goes on the left; in Repeat, the count goes on the right
### Group doesn't include trailing empty groups
A length can now be specified either in an extra element in any rank-1 component of `𝕨`, 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.
+### Tolerant comparison
+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.
+
### Index Of privileges the first match
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: `β‰ βˆ˜βŠ£-1+⌽⊸⊐`.
diff --git a/doc/match.md b/doc/match.md
index e85b8c59..14ff8ffb 100644
--- a/doc/match.md
+++ b/doc/match.md
@@ -27,7 +27,7 @@ Starting with the easiest rules, values with different types are never equal to
⟨'a', +, 3⟩ = ⟨-⟜», '+', 3Λ™βŸ©
-Two characters are equal when they have the same code point. Numeric equality depends on the number system in use, but probably works about how you expect. If you're coming from APL, note that current BQN implementations don't employ comparison tolerance. To see if two floats are roughly equal you'll need to write a tolerant comparison yourself, but how often do you really need to do this?
+Two characters are equal when they have the same code point. Numeric equality depends on the number system in use, but probably works about how you expect. If you're coming from APL, note that BQN doesn't use comparison tolerance. To see if two floats are roughly equal you'll need to write a tolerant comparison yourself, but how often do you really need to do this?
'x' = "wxyz"
diff --git a/docs/commentary/problems.html b/docs/commentary/problems.html
index 16bbcac4..e2feae77 100644
--- a/docs/commentary/problems.html
+++ b/docs/commentary/problems.html
@@ -32,24 +32,6 @@
<p>Only <code><span class='Function'>⍋⍒</span></code> use array ordering rather than just array equality or numeric ordering. Getting at the actual ordering to just compare two arrays is more difficult than it should be (but not <em>that</em> difficult: <code><span class='Function'>β₯Š</span><span class='Modifier2'>⊸</span><span class='Function'>⍋</span><span class='Modifier2'>⌾</span><span class='Function'>&lt;</span></code> is TAO <code><span class='Function'>≀</span></code>).</p>
<h3 id="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="comparison-tolerance"><a class="header" href="#comparison-tolerance">Comparison tolerance</a></h3>
-<p>Kind of necessary for practical programming, but how should it be invoked or controlled? A system variable like <code><span class='Value'>βŽ•</span><span class='Function'>CT</span></code>? Per-primitive control? Both? Which primitives should use it?</p>
-<table>
-<thead>
-<tr>
-<th>Definitely</th>
-<th>Maybe</th>
-<th>Definitely not</th>
-</tr>
-</thead>
-<tbody>
-<tr>
-<td><code><span class='Function'>=≠≀β‰₯&lt;&gt;</span></code></td>
-<td><code><span class='Function'>β‰‘β‰’βŠβŠ’βˆŠβ·|</span></code></td>
-<td><code><span class='Function'>⍋⍒</span></code></td>
-</tr>
-</tbody>
-</table>
<h3 id="no-access-to-fast-high-precision-sum"><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.</p>
<h3 id="high-rank-array-notation"><a class="header" href="#high-rank-array-notation">High-rank array notation</a></h3>
@@ -65,6 +47,8 @@
<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="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="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="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>.</p>
<h3 id="glyphs-that-arent-great"><a class="header" href="#glyphs-that-arent-great">Glyphs that aren't great</a></h3>
diff --git a/docs/doc/match.html b/docs/doc/match.html
index b162bd3b..1e73afb8 100644
--- a/docs/doc/match.html
+++ b/docs/doc/match.html
@@ -30,7 +30,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oJ2EnLCArLCAz4p+pID0g4p+oLeKfnMK7LCAnKycsIDPLmeKfqQ==">↗️</a><pre> <span class='Bracket'>⟨</span><span class='String'>'a'</span><span class='Separator'>,</span> <span class='Function'>+</span><span class='Separator'>,</span> <span class='Number'>3</span><span class='Bracket'>⟩</span> <span class='Function'>=</span> <span class='Bracket'>⟨</span><span class='Function'>-</span><span class='Modifier2'>⟜</span><span class='Function'>Β»</span><span class='Separator'>,</span> <span class='String'>'+'</span><span class='Separator'>,</span> <span class='Number'>3</span><span class='Modifier'>Λ™</span><span class='Bracket'>⟩</span>
⟨ 0 0 0 ⟩
</pre>
-<p>Two characters are equal when they have the same code point. Numeric equality depends on the number system in use, but probably works about how you expect. If you're coming from APL, note that current BQN implementations don't employ comparison tolerance. To see if two floats are roughly equal you'll need to write a tolerant comparison yourself, but how often do you really need to do this?</p>
+<p>Two characters are equal when they have the same code point. Numeric equality depends on the number system in use, but probably works about how you expect. If you're coming from APL, note that BQN doesn't use comparison tolerance. To see if two floats are roughly equal you'll need to write a tolerant comparison yourself, but how often do you really need to do this?</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=J3gnID0gInd4eXoiCgoxLjI1ID0gMSArIDAuMjU=">↗️</a><pre> <span class='String'>'x'</span> <span class='Function'>=</span> <span class='String'>&quot;wxyz&quot;</span>
⟨ 0 1 0 0 ⟩
@@ -57,7 +57,7 @@
<h3 id="block-equality"><a class="header" href="#block-equality">Block equality</a></h3>
<p>The final point above about block instances is subtler. An instance of a block function or modifier is mutable, meaning that its behavior can change over the course of a program. Consider the following two functions:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=RuKAv0cg4oaQIHsgYeKGkDEwIOKLhCB7YSvwnZWpfeKAv3th4oap8J2VqX0gfQoKRiA1ICAgIyBPbmUgcmVzdWx0CkcgOApGIDUgICAjIEFub3RoZXIgcmVzdWx04oCUdGhlIGRlZmluaXRpb24gb2YgaW5zYW5pdHkh">↗️</a><pre> <span class='Function'>F</span><span class='Ligature'>β€Ώ</span><span class='Function'>G</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Value'>a</span><span class='Gets'>←</span><span class='Number'>10</span> <span class='Separator'>β‹„</span> <span class='Brace'>{</span><span class='Value'>a</span><span class='Function'>+</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Ligature'>β€Ώ</span><span class='Brace'>{</span><span class='Value'>a</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Brace'>}</span> <span class='Brace'>}</span>
-⟨ *function* *function* ⟩
+⟨ (function block) (function block) ⟩
<span class='Function'>F</span> <span class='Number'>5</span> <span class='Comment'># One result
</span>15
diff --git a/spec/reference.bqn b/spec/reference.bqn
index ba0e0570..f37e184e 100644
--- a/spec/reference.bqn
+++ b/spec/reference.bqn
@@ -2,8 +2,6 @@
# limited initial functionality. Implementations are designed to be
# simple and not fast.
-# Not yet included: complex numbers or comparison tolerance.
-
# In some cases an operation is defined with limited functionality at
# first and later expanded. For convenience, rather than renaming these
# limited versions, every primitive use refers to the most recent