aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2021-02-02 16:24:24 -0500
committerMarshall Lochbaum <mwlochbaum@gmail.com>2021-02-02 16:24:24 -0500
commit168a106af8b2771d20a2662c1d13c16fa976a68d (patch)
tree402024d05278e0f0d4026689d83eba477a90c719
parent36037d57b46811084d076f20e79b87894e139671 (diff)
Add document on Assert
-rw-r--r--doc/README.md1
-rw-r--r--doc/assert.md25
-rw-r--r--doc/primitive.md2
-rw-r--r--docs/doc/assert.html32
-rw-r--r--docs/doc/index.html1
-rw-r--r--docs/doc/primitive.html4
6 files changed, 62 insertions, 3 deletions
diff --git a/doc/README.md b/doc/README.md
index 3a766abf..01e5bcb5 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -21,6 +21,7 @@ Concepts:
Primitives:
- [Array depth](depth.md) (`≡` and `⚇`)
+- [Assert](assert.md) (`!`)
- [Deshape and Reshape](reshape.md) (`⥊`)
- [Group](group.md) (`⊔`)
- [Join and Join To](join.md) (`∾`)
diff --git a/doc/assert.md b/doc/assert.md
new file mode 100644
index 00000000..7f4bee6d
--- /dev/null
+++ b/doc/assert.md
@@ -0,0 +1,25 @@
+*View this file with results and syntax highlighting [here](https://mlochbaum.github.io/BQN/doc/assert.html).*
+
+# Assert
+
+BQN takes the position that errors exist to indicate exceptional conditions that the developer of a given program didn't expect. However, the types of errors that BQN naturally checks for, such as mismatched shapes in Couple (`≍`), aren't always enough to detect exceptional conditions. Issues like numeric values that don't make physical sense will slip right through. BQN makes it easy for a programmer to check for these sorts of problems by building in the primitive Assert, written `!`. This function checks whether `𝕩` matches `1`: if it does, then it does nothing and returns `𝕩`, and otherwise it gives an error.
+
+ ! 2=2 # Passed
+ ! 2=3 # Failed
+
+To pass, the right argument must be exactly the number `1`; any other value causes an error. For example, an array of `1`s still causes an error; use `∧´⥊` to convert a boolean array to a single boolean that indicates whether all of its values are true.
+
+ ! (∧=∨⌾¬)⌜˜ ↕2
+ ! ∧´⥊ (∧=∨⌾¬)⌜˜ ↕2
+
+Assert can take a left argument, which gives a message to be associated with the error. It's typical to use a string for the left argument in order to display it to the programmer, but the left argument can be any value.
+
+ "Message" ! 0
+ ⟨∘,"abc",˜⟩ ! '0' # Okay this is not a very helpful printout
+
+### Computing the error message on demand
+
+Because the left argument to a function is always computed before the function is called, Assert [doesn't let you](../commentary/problems.md#assert-has-no-way-to-compute-the-error-message) compute the error message only if there's an error. This might be a problem if the error message computation is slow or has side effects. There are a few ways to work around the issue:
+- Handle errors with ordinary if-then logic (perhaps using [control structures](control.md)). This is probably the best path for user-facing applications where displaying an error goes through the user interface.
+- Write a function `Message` to compute the message, and call `𝕨 Message⊸!⍟(1⊸≢) 𝕩` or similar instead of `!`.
+- If the error will be caught elsewhere in the program, use a closure for the message and evaluate it when caught. With a function `Message` as above, `message ! 𝕩` works, and `{…}˙⊸! 𝕩` is a convenient syntax for block functions.
diff --git a/doc/primitive.md b/doc/primitive.md
index dfc03f01..9546ae9f 100644
--- a/doc/primitive.md
+++ b/doc/primitive.md
@@ -52,7 +52,7 @@ Functions that have significant differences from APL functions are marked with a
| `∊` | [Unique Mask](https://aplwiki.com/wiki/Nub_Sieve) | [Member of](https://aplwiki.com/wiki/Membership)
| `⍷` | [Deduplicate](https://aplwiki.com/wiki/Unique) | [Find](https://aplwiki.com/wiki/Find)
| `⊔` | [Group Indices](group.md)* | [Group](group.md)*
-| `!` | Assert* | Assert with Message*
+| `!` | [Assert](assert.md)* | [Assert with Message](assert.md)*
## Modifiers
diff --git a/docs/doc/assert.html b/docs/doc/assert.html
new file mode 100644
index 00000000..35ae159c
--- /dev/null
+++ b/docs/doc/assert.html
@@ -0,0 +1,32 @@
+<head>
+ <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/>
+ <link href="../style.css" rel="stylesheet"/>
+ <title>BQN: Assert</title>
+</head>
+<div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a> / <a href="../index.html">main</a> / <a href="index.html">doc</a></div>
+<h1 id="assert">Assert</h1>
+<p>BQN takes the position that errors exist to indicate exceptional conditions that the developer of a given program didn't expect. However, the types of errors that BQN naturally checks for, such as mismatched shapes in Couple (<code><span class='Function'>≍</span></code>), aren't always enough to detect exceptional conditions. Issues like numeric values that don't make physical sense will slip right through. BQN makes it easy for a programmer to check for these sorts of problems by building in the primitive Assert, written <code><span class='Function'>!</span></code>. This function checks whether <code><span class='Value'>𝕩</span></code> matches <code><span class='Number'>1</span></code>: if it does, then it does nothing and returns <code><span class='Value'>𝕩</span></code>, and otherwise it gives an error.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ISAyPTIgICMgUGFzc2VkCiEgMj0zICAjIEZhaWxlZA==">↗️</a><pre> <span class='Function'>!</span> <span class='Number'>2</span><span class='Function'>=</span><span class='Number'>2</span> <span class='Comment'># Passed
+</span>1
+ <span class='Function'>!</span> <span class='Number'>2</span><span class='Function'>=</span><span class='Number'>3</span> <span class='Comment'># Failed
+</span>ERROR
+</pre>
+<p>To pass, the right argument must be exactly the number <code><span class='Number'>1</span></code>; any other value causes an error. For example, an array of <code><span class='Number'>1</span></code>s still causes an error; use <code><span class='Function'>∧</span><span class='Modifier'>´</span><span class='Function'>⥊</span></code> to convert a boolean array to a single boolean that indicates whether all of its values are true.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ISAo4oinPeKIqOKMvsKsKeKMnMucIOKGlTIKISDiiKfCtOKliiAo4oinPeKIqOKMvsKsKeKMnMucIOKGlTI=">↗️</a><pre> <span class='Function'>!</span> <span class='Paren'>(</span><span class='Function'>∧=∨</span><span class='Modifier2'>⌾</span><span class='Function'>¬</span><span class='Paren'>)</span><span class='Modifier'>⌜˜</span> <span class='Function'>↕</span><span class='Number'>2</span>
+ERROR
+ <span class='Function'>!</span> <span class='Function'>∧</span><span class='Modifier'>´</span><span class='Function'>⥊</span> <span class='Paren'>(</span><span class='Function'>∧=∨</span><span class='Modifier2'>⌾</span><span class='Function'>¬</span><span class='Paren'>)</span><span class='Modifier'>⌜˜</span> <span class='Function'>↕</span><span class='Number'>2</span>
+1
+</pre>
+<p>Assert can take a left argument, which gives a message to be associated with the error. It's typical to use a string for the left argument in order to display it to the programmer, but the left argument can be any value.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Ik1lc3NhZ2UiICEgMArin6jiiJgsImFiYyIsy5zin6kgISAnMCcgICMgT2theSB0aGlzIGlzIG5vdCBhIHZlcnkgaGVscGZ1bCBwcmludG91dA==">↗️</a><pre> <span class='String'>&quot;Message&quot;</span> <span class='Function'>!</span> <span class='Number'>0</span>
+ERROR
+ <span class='Bracket'>⟨</span><span class='Modifier2'>∘</span><span class='Separator'>,</span><span class='String'>&quot;abc&quot;</span><span class='Separator'>,</span><span class='Modifier'>˜</span><span class='Bracket'>⟩</span> <span class='Function'>!</span> <span class='String'>'0'</span> <span class='Comment'># Okay this is not a very helpful printout
+</span>ERROR
+</pre>
+<h3 id="computing-the-error-message-on-demand">Computing the error message on demand</h3>
+<p>Because the left argument to a function is always computed before the function is called, Assert <a href="../commentary/problems.html#assert-has-no-way-to-compute-the-error-message">doesn't let you</a> compute the error message only if there's an error. This might be a problem if the error message computation is slow or has side effects. There are a few ways to work around the issue:</p>
+<ul>
+<li>Handle errors with ordinary if-then logic (perhaps using <a href="control.html">control structures</a>). This is probably the best path for user-facing applications where displaying an error goes through the user interface.</li>
+<li>Write a function <code><span class='Function'>Message</span></code> to compute the message, and call <code><span class='Value'>𝕨</span> <span class='Function'>Message</span><span class='Modifier2'>⊸</span><span class='Function'>!</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'>𝕩</span></code> or similar instead of <code><span class='Function'>!</span></code>.</li>
+<li>If the error will be caught elsewhere in the program, use a closure for the message and evaluate it when caught. With a function <code><span class='Function'>Message</span></code> as above, <code><span class='Value'>message</span> <span class='Function'>!</span> <span class='Value'>𝕩</span></code> works, and <code><span class='Brace'>{</span><span class='Value'>…</span><span class='Brace'>}</span><span class='Modifier'>˙</span><span class='Modifier2'>⊸</span><span class='Function'>!</span> <span class='Value'>𝕩</span></code> is a convenient syntax for block functions.</li>
+</ul>
diff --git a/docs/doc/index.html b/docs/doc/index.html
index 898d2793..52f09365 100644
--- a/docs/doc/index.html
+++ b/docs/doc/index.html
@@ -26,6 +26,7 @@
<p>Primitives:</p>
<ul>
<li><a href="depth.html">Array depth</a> (<code><span class='Function'>≡</span></code> and <code><span class='Modifier2'>⚇</span></code>)</li>
+<li><a href="assert.html">Assert</a> (<code><span class='Function'>!</span></code>)</li>
<li><a href="reshape.html">Deshape and Reshape</a> (<code><span class='Function'>⥊</span></code>)</li>
<li><a href="group.html">Group</a> (<code><span class='Function'>⊔</span></code>)</li>
<li><a href="join.html">Join and Join To</a> (<code><span class='Function'>∾</span></code>)</li>
diff --git a/docs/doc/primitive.html b/docs/doc/primitive.html
index e943a23c..b1ba12c5 100644
--- a/docs/doc/primitive.html
+++ b/docs/doc/primitive.html
@@ -229,8 +229,8 @@
</tr>
<tr>
<td><code><span class='Function'>!</span></code></td>
-<td>Assert*</td>
-<td>Assert with Message*</td>
+<td><a href="assert.html">Assert</a>*</td>
+<td><a href="assert.html">Assert with Message</a>*</td>
</tr>
</tbody>
</table>