aboutsummaryrefslogtreecommitdiff
path: root/docs/doc
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2021-10-09 21:58:01 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2021-10-09 22:01:06 -0400
commitafc086a54b9f37acd4d90ff6cc607ab3008c78f9 (patch)
treef37e312a60284a0f822a5bc0aaab028c57645a2b /docs/doc
parentf2cd25f1ab2b04007c1f112dfffd3590e60f2d3b (diff)
Predicate documentation
Diffstat (limited to 'docs/doc')
-rw-r--r--docs/doc/block.html29
-rw-r--r--docs/doc/control.html2
2 files changed, 30 insertions, 1 deletions
diff --git a/docs/doc/block.html b/docs/doc/block.html
index d3eb2bb8..9ae75ef7 100644
--- a/docs/doc/block.html
+++ b/docs/doc/block.html
@@ -213,6 +213,35 @@ ERROR
<span class='Brace'>}</span>
</pre>
<p>These case-style headers function exactly the same as if they were preceded by <code><span class='Function'>π•Š</span></code>, and can be mixed with other kinds of headers.</p>
+<h3 id="predicates"><a class="header" href="#predicates">Predicates</a></h3>
+<p>Destructuring with a header is quite limited, only allowing matching structure and data with exact equality. A predicate, written with <code><span class='Value'>?</span></code>, allows you to test an arbitrary property before evaluating the rest of the body, and also serves as a limited kind of control flow. It can be thought of as an extension to a header, so that for example the following function requires the argument to have a single element and for that element to be less than zero before using the first body <code><span class='Number'>1</span><span class='Function'>+</span><span class='Value'>𝕩</span></code>. Otherwise it moves to the next one, an unconditional <code><span class='Value'>𝕩</span></code>.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Q2hlY2tQYWlyIOKGkCB7IPCdlYrin6hhLGLin6k6IGE8Yj8gIm9rIiA7ICJub3Qgb2siIH0KCkNoZWNrUGFpciDin6gzLDjin6kgICAgIyBGYWlscyBkZXN0cnVjdHVyaW5nCkNoZWNrUGFpciDin6gxLDQsNeKfqSAgIyBOb3QgYSBwYWlyCkNoZWNrUGFpciDin6gzLMKvMeKfqSAgICMgTm90IGFzY2VuZGluZw==">↗️</a><pre> <span class='Function'>CheckPair</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Function'>π•Š</span><span class='Bracket'>⟨</span><span class='Value'>a</span><span class='Separator'>,</span><span class='Value'>b</span><span class='Bracket'>⟩</span><span class='Value'>:</span> <span class='Value'>a</span><span class='Function'>&lt;</span><span class='Value'>b?</span> <span class='String'>&quot;ok&quot;</span> <span class='Value'>;</span> <span class='String'>&quot;not ok&quot;</span> <span class='Brace'>}</span>
+
+ <span class='Function'>CheckPair</span> <span class='Bracket'>⟨</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>8</span><span class='Bracket'>⟩</span> <span class='Comment'># Fails destructuring
+</span>"ok"
+ <span class='Function'>CheckPair</span> <span class='Bracket'>⟨</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Number'>4</span><span class='Separator'>,</span><span class='Number'>5</span><span class='Bracket'>⟩</span> <span class='Comment'># Not a pair
+</span>"not ok"
+ <span class='Function'>CheckPair</span> <span class='Bracket'>⟨</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>¯1</span><span class='Bracket'>⟩</span> <span class='Comment'># Not ascending
+</span>"not ok"
+</pre>
+<p>The body where the predicate appears doesn't need to start with a header, and there can be other statements before it. In fact, <code><span class='Value'>?</span></code> functions just like a separator (like <code><span class='Separator'>β‹„</span></code> or <code><span class='Separator'>,</span></code>) with a side effect.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eyBy4oaQ4oy98J2VqSDii4QgJ3QnPeKKkXIgPyByIDsg8J2VqSB9wqggInRlc3Qi4oC/InRoaXMi">↗️</a><pre> <span class='Brace'>{</span> <span class='Value'>r</span><span class='Gets'>←</span><span class='Function'>⌽</span><span class='Value'>𝕩</span> <span class='Separator'>β‹„</span> <span class='String'>'t'</span><span class='Function'>=βŠ‘</span><span class='Value'>r</span> <span class='Value'>?</span> <span class='Value'>r</span> <span class='Value'>;</span> <span class='Value'>𝕩</span> <span class='Brace'>}</span><span class='Modifier'>Β¨</span> <span class='String'>&quot;test&quot;</span><span class='Ligature'>β€Ώ</span><span class='String'>&quot;this&quot;</span>
+⟨ "tset" "this" ⟩
+</pre>
+<p>So <code><span class='Value'>r</span></code> is the reversed argument, and if its first character (the last one in <code><span class='Value'>𝕩</span></code>) is <code><span class='String'>'t'</span></code> then it returns <code><span class='Value'>r</span></code>, and otherwise we abandon that line of reasoning and return <code><span class='Value'>𝕩</span></code>. This sounds a lot like an if statement. And <code><span class='Brace'>{</span> <span class='Value'>a</span><span class='Function'>&lt;</span><span class='Value'>b</span> <span class='Value'>?</span> <span class='Value'>a</span> <span class='Value'>;</span> <span class='Value'>b</span> <span class='Brace'>}</span></code>, which computes <code><span class='Value'>a</span><span class='Function'>⌊</span><span class='Value'>b</span></code> the hard way, shows how the syntax can be similar to a ternary operator. But <code><span class='Value'>?;</span></code> is more flexible than that. It can support any number of options, with multiple tests for each oneβ€”the structure below is &quot;if _ and _ then _; else if _ then _; else _&quot;.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=VGhpbmcg4oaQIHsg8J2VqeKJpTM/IPCdlaniiaQ4PyAyfPCdlakgOyDwnZWpPTA/IEAgOyDiiJ4gfQoKKOKKoiDiiY0gVGhpbmfCqCkg4oaVMTAgICMgVGFibGUgb2YgYXJndW1lbnRzIGFuZCByZXN1bHRz">↗️</a><pre> <span class='Function'>Thing</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Value'>𝕩</span><span class='Function'>β‰₯</span><span class='Number'>3</span><span class='Value'>?</span> <span class='Value'>𝕩</span><span class='Function'>≀</span><span class='Number'>8</span><span class='Value'>?</span> <span class='Number'>2</span><span class='Function'>|</span><span class='Value'>𝕩</span> <span class='Value'>;</span> <span class='Value'>𝕩</span><span class='Function'>=</span><span class='Number'>0</span><span class='Value'>?</span> <span class='String'>@</span> <span class='Value'>;</span> <span class='Number'>∞</span> <span class='Brace'>}</span>
+
+ <span class='Paren'>(</span><span class='Function'>⊒</span> <span class='Function'>≍</span> <span class='Function'>Thing</span><span class='Modifier'>Β¨</span><span class='Paren'>)</span> <span class='Function'>↕</span><span class='Number'>10</span> <span class='Comment'># Table of arguments and results
+</span>β”Œβ”€
+β•΅ 0 1 2 3 4 5 6 7 8 9
+ @ ∞ ∞ 1 0 1 0 1 0 ∞
+ β”˜
+</pre>
+<p>This structure is still constrained by the rules of block bodies: each instance of <code><span class='Value'>;</span></code> is a separate scope, so that variables defined before a <code><span class='Value'>?</span></code> don't survive past the <code><span class='Value'>;</span></code>.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eyAwPW7ihpDiiaDwnZWpID8g4oieIDsgbiB9ICJhYmMi">↗️</a><pre> <span class='Brace'>{</span> <span class='Number'>0</span><span class='Function'>=</span><span class='Value'>n</span><span class='Gets'>←</span><span class='Function'>β‰ </span><span class='Value'>𝕩</span> <span class='Value'>?</span> <span class='Number'>∞</span> <span class='Value'>;</span> <span class='Value'>n</span> <span class='Brace'>}</span> <span class='String'>&quot;abc&quot;</span>
+ERROR
+</pre>
+<p>This is the main drawback of predicates relative to guards in APL dfns (also written with <code><span class='Value'>?</span></code>), while the advantage is that it allows multiple expressions, or extra conditions, after a <code><span class='Value'>?</span></code>. It's not how I would have designed it if I just wanted to make a syntax for if statements, but it's a natural fit for the header system.</p>
<h2 id="returns"><a class="header" href="#returns">Returns</a></h2>
<p><em>This feature is not yet included in any BQN implementation.</em></p>
<p>The glyph <code><span class='Gets'>β†’</span></code> indicates an early return from a block. It must be preceded either by one of the self-reference special names <code><span class='Function'>π•Š</span></code> or <code><span class='Value'>𝕣</span></code> or by an internal name for a containing block. The combination of name and return tokenβ€”like <code><span class='Function'>F</span><span class='Gets'>β†’</span></code>, let's sayβ€”is a function that returns from the current instance of the indicated block. If that instance has already returned, then it instead results in an error.</p>
diff --git a/docs/doc/control.html b/docs/doc/control.html
index ae1ce1e4..3c3c2f1a 100644
--- a/docs/doc/control.html
+++ b/docs/doc/control.html
@@ -55,7 +55,7 @@
<p>There's no reason the condition in an if statement from the previous section has to be boolean: it could be any natural number, causing the action to be repeated that many times. If the action is never performed, the result is the statement's argument, and otherwise it's the result of the last time the action was performed.</p>
<p>Another option is to use a <a href="#for">for-each</a> statement with an argument of <code><span class='Function'>↕</span><span class='Value'>n</span></code>: in this case the result is the list of each action's result.</p>
<h2 id="if-else"><a class="header" href="#if-else">If-Else</a></h2>
-<p>In most cases, the easy way to write an if-else statement is with predicates:</p>
+<p>In most cases, the easy way to write an if-else statement is with <a href="block.html#predicates">predicates</a>:</p>
<pre><span class='Brace'>{</span>
<span class='Value'>threshold</span> <span class='Function'>&lt;</span> <span class='Number'>6</span> <span class='Value'>?</span>
<span class='Value'>a</span> <span class='Gets'>↩</span> <span class='Function'>Small</span> <span class='Value'>threshold</span> <span class='Value'>;</span> <span class='Comment'># If predicate was true