diff options
Diffstat (limited to 'docs/doc/block.html')
| -rw-r--r-- | docs/doc/block.html | 29 |
1 files changed, 29 insertions, 0 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'><</span><span class='Value'>b?</span> <span class='String'>"ok"</span> <span class='Value'>;</span> <span class='String'>"not ok"</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'>"test"</span><span class='Ligature'>βΏ</span><span class='String'>"this"</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'><</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 "if _ and _ then _; else if _ then _; else _".</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'>"abc"</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> |
