diff options
Diffstat (limited to 'docs/doc/block.html')
| -rw-r--r-- | docs/doc/block.html | 58 |
1 files changed, 29 insertions, 29 deletions
diff --git a/docs/doc/block.html b/docs/doc/block.html index 64643e7d..40de8ab2 100644 --- a/docs/doc/block.html +++ b/docs/doc/block.html @@ -135,26 +135,26 @@ </pre> <p>Because <code><span class='Value'>π£</span></code> only ever refers to a 1-modifier or 2-modifer, it can never make sense to refer to it as a function, and the uppercase letter <code><span class='Value'>β</span></code> is not recognized by BQN. In order to allow <code><span class='Value'>π£</span></code> to be spelled as a 1-modifier <code><span class='Modifier'>_π£</span></code> or 2-modifier <code><span class='Modifier2'>_π£_</span></code>, it is treated as an ordinary identifier character, so it must be separated from letters or numbers by spaces.</p> <h2 id="block-headers"><a class="header" href="#block-headers">Block headers</a></h2> -<p>As a program becomes larger, it often becomes necessary to name inputs to blocks rather than just using special names. It can also become difficult to identify what kind of block is being defined, as it requires scanning through the block for special names. A <em>block header</em>, which is separated from the body of a block by a colon <code><span class='Value'>:</span></code>, specifies the kind of block and can declare names for the block and its inputs.</p> -<pre><span class='Function'>Fact</span> <span class='Gets'>β</span> <span class='Brace'>{</span> <span class='Function'>F</span> <span class='Value'>n:</span> +<p>As a program becomes larger, it often becomes necessary to name inputs to blocks rather than just using special names. It can also become difficult to identify what kind of block is being defined, as it requires scanning through the block for special names. A <em>block header</em>, which is separated from the body of a block by a colon <code><span class='Head'>:</span></code>, specifies the kind of block and can declare names for the block and its inputs.</p> +<pre><span class='Function'>Fact</span> <span class='Gets'>β</span> <span class='Brace'>{</span> <span class='Function'>F</span> <span class='Value'>n</span><span class='Head'>:</span> <span class='Value'>n</span> <span class='Function'>Γ</span> <span class='Paren'>(</span><span class='Number'>0</span><span class='Modifier2'>βΈ</span><span class='Function'><</span><span class='Paren'>)</span><span class='Modifier2'>βΆ</span><span class='Number'>1</span><span class='Ligature'>βΏ</span><span class='Function'>F</span> <span class='Value'>n</span><span class='Function'>-</span><span class='Number'>1</span> <span class='Brace'>}</span> </pre> <p>Its syntax mirrors an application of the block. As suggested by the positioning, the names given in a header apply only inside the block: for example <code><span class='Function'>F</span></code> above is only defined inside the <code><span class='Brace'>{}</span></code> braces while <code><span class='Function'>Fact</span></code> could be used either outside or inside. Some other possibilites are given below.</p> <pre><span class='Comment'># A dyadic function that refers to itself as Func -</span><span class='Brace'>{</span> <span class='Value'>l</span> <span class='Function'>Func</span> <span class='Value'>r:</span> +</span><span class='Brace'>{</span> <span class='Value'>l</span> <span class='Function'>Func</span> <span class='Value'>r</span><span class='Head'>:</span> <span class='Value'>β¦</span> <span class='Comment'># A deferred 1-modifier with a list argument -</span><span class='Brace'>{</span> <span class='Function'>Fn</span> <span class='Modifier'>_apply</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><span class='Brace'>{</span> <span class='Function'>Fn</span> <span class='Modifier'>_apply</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='Head'>:</span> <span class='Value'>β¦</span> <span class='Comment'># A monadic function with no names given -</span><span class='Brace'>{</span> <span class='Function'>π</span><span class='Value'>π©:</span> +</span><span class='Brace'>{</span> <span class='Function'>π</span><span class='Value'>π©</span><span class='Head'>:</span> <span class='Value'>β¦</span> <span class='Comment'># An immediate or deferred 2-modifier -</span><span class='Brace'>{</span> <span class='Function'>F</span> <span class='Modifier2'>_op_</span> <span class='Value'>val:</span> +</span><span class='Brace'>{</span> <span class='Function'>F</span> <span class='Modifier2'>_op_</span> <span class='Value'>val</span><span class='Head'>:</span> <span class='Value'>β¦</span> </pre> <p>In all cases special names still work just like in a headerless function. In this respect the effect of the header is the same as a series of assignments at the beginning of a function, such as the following translation of the second header above:</p> @@ -167,31 +167,31 @@ <p>Unlike these assignments, the header also constrains what inputs the block can take: a monadic 1-modifier like the one above can't take a right operand or left argument, and consequently its body can't contain <code><span class='Function'>πΎ</span></code> or <code><span class='Value'>π¨</span></code>. Calling it with a left argument, or a right argument that isn't a two-element list, will result in an error.</p> <h3 id="destructuring"><a class="header" href="#destructuring">Destructuring</a></h3> <p>Arguments, but not operands, allow destructuring like assignment does. While assignment only tolerates lists of variables, header destructuring also allows constants. The argument must match the given structure, including the constants where they appear, or an error results.</p> -<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=RGVzdHJ1Y3Qg4oaQIHsg8J2ViiBh4oC/MeKAv+KfqGIsMuKfqTogYeKJjWIgfQpEZXN0cnVjdCAgICAgICA14oC/MeKAv+KfqDcsMuKfqQ==">βοΈ</a><pre> <span class='Function'>Destruct</span> <span class='Gets'>β</span> <span class='Brace'>{</span> <span class='Function'>π</span> <span class='Value'>a</span><span class='Ligature'>βΏ</span><span class='Number'>1</span><span class='Ligature'>βΏ</span><span class='Bracket'>β¨</span><span class='Value'>b</span><span class='Separator'>,</span><span class='Number'>2</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='Brace'>}</span> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=RGVzdHJ1Y3Qg4oaQIHsg8J2ViiBh4oC/MeKAv+KfqGIsMuKfqTogYeKJjWIgfQpEZXN0cnVjdCAgICAgICA14oC/MeKAv+KfqDcsMuKfqQ==">βοΈ</a><pre> <span class='Function'>Destruct</span> <span class='Gets'>β</span> <span class='Brace'>{</span> <span class='Function'>π</span> <span class='Value'>a</span><span class='Ligature'>βΏ</span><span class='Number'>1</span><span class='Ligature'>βΏ</span><span class='Bracket'>β¨</span><span class='Value'>b</span><span class='Separator'>,</span><span class='Number'>2</span><span class='Bracket'>β©</span><span class='Head'>:</span> <span class='Value'>a</span><span class='Function'>β</span><span class='Value'>b</span> <span class='Brace'>}</span> <span class='Function'>Destruct</span> <span class='Number'>5</span><span class='Ligature'>βΏ</span><span class='Number'>1</span><span class='Ligature'>βΏ</span><span class='Bracket'>β¨</span><span class='Number'>7</span><span class='Separator'>,</span><span class='Number'>2</span><span class='Bracket'>β©</span> β¨ 5 7 β© </pre> <h3 id="special-names-in-headers"><a class="header" href="#special-names-in-headers">Special names in headers</a></h3> -<p>Any element of a function or modifier header can be left nameless by using the corresponding special name in that position, instead of an identifier. For example, the header <code><span class='Value'>π¨</span> <span class='Function'>π½</span><span class='Modifier2'>_π£_</span><span class='Function'>πΎ</span> <span class='Value'>π©:</span></code> incorporates as much vagueness as possible. It indicates a deferred 2-modifier, but provides no other information.</p> +<p>Any element of a function or modifier header can be left nameless by using the corresponding special name in that position, instead of an identifier. For example, the header <code><span class='Value'>π¨</span> <span class='Function'>π½</span><span class='Modifier2'>_π£_</span><span class='Function'>πΎ</span> <span class='Value'>π©</span><span class='Head'>:</span></code> incorporates as much vagueness as possible. It indicates a deferred 2-modifier, but provides no other information.</p> <p>The name <code><span class='Value'>π¨</span></code> in this context can refer to either a left argument or no left argument, allowing a header with arguments to be used even for an ambiguous function. Recall that <code><span class='Value'>π¨</span></code> is the only token other than <code><span class='Nothing'>Β·</span></code> that can have no value. If an identifier or list is given as the left argument, then the function must be called with a left argument.</p> <h3 id="short-headers"><a class="header" href="#short-headers">Short headers</a></h3> -<p>A header does not need to include all inputs, as shown by the <code><span class='Function'>F</span> <span class='Modifier2'>_op_</span> <span class='Value'>val:</span></code> header above. The simplest case, when no inputs are given, is called a <em>label</em>. While it doesn't restrict the inputs, a label specifies the type of the block and gives an internal name that can be used to refer to it.</p> -<pre><span class='Brace'>{</span> <span class='Value'>b:</span> <span class='Comment'># Block -</span><span class='Brace'>{</span> <span class='Function'>π</span><span class='Value'>:</span> <span class='Comment'># Function -</span><span class='Brace'>{</span> <span class='Modifier'>_π£</span><span class='Value'>:</span> <span class='Comment'># 1-Modifier -</span><span class='Brace'>{</span> <span class='Modifier2'>_π£_</span><span class='Value'>:</span> <span class='Comment'># 2-Modifier +<p>A header does not need to include all inputs, as shown by the <code><span class='Function'>F</span> <span class='Modifier2'>_op_</span> <span class='Value'>val</span><span class='Head'>:</span></code> header above. The simplest case, when no inputs are given, is called a <em>label</em>. While it doesn't restrict the inputs, a label specifies the type of the block and gives an internal name that can be used to refer to it.</p> +<pre><span class='Brace'>{</span> <span class='Value'>b</span><span class='Head'>:</span> <span class='Comment'># Block +</span><span class='Brace'>{</span> <span class='Function'>π</span><span class='Head'>:</span> <span class='Comment'># Function +</span><span class='Brace'>{</span> <span class='Modifier'>_π£</span><span class='Head'>:</span> <span class='Comment'># 1-Modifier +</span><span class='Brace'>{</span> <span class='Modifier2'>_π£_</span><span class='Head'>:</span> <span class='Comment'># 2-Modifier </span></pre> <p>For immediate blocks, this is the only type of header possible, and it must use an identifier as there is no applicable special name. However, the name can't be used: it doesn't make sense to refer to a value while it is still being computed!</p> <h2 id="multiple-bodies"><a class="header" href="#multiple-bodies">Multiple bodies</a></h2> -<p>Blocks that define functions and deferred modifiers can include more than one body, separated by semicolons <code><span class='Value'>;</span></code>. The body used for a particular evaluation is chosen based on the arguments the the block. One special case applies when there are exactly two bodies either without headers or with labels only: in this case, the first applies when there is one argument and the second when there are two.</p> -<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=QW1iaXYg4oaQIHsg4p+oMSzwnZWp4p+pIDsg4p+oMizwnZWoLPCdlanin6kgfQpBbWJpdiAnYScKJ2EnIEFtYml2ICdiJw==">βοΈ</a><pre> <span class='Function'>Ambiv</span> <span class='Gets'>β</span> <span class='Brace'>{</span> <span class='Bracket'>β¨</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Value'>π©</span><span class='Bracket'>β©</span> <span class='Value'>;</span> <span class='Bracket'>β¨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Value'>π¨</span><span class='Separator'>,</span><span class='Value'>π©</span><span class='Bracket'>β©</span> <span class='Brace'>}</span> +<p>Blocks that define functions and deferred modifiers can include more than one body, separated by semicolons <code><span class='Head'>;</span></code>. The body used for a particular evaluation is chosen based on the arguments the the block. One special case applies when there are exactly two bodies either without headers or with labels only: in this case, the first applies when there is one argument and the second when there are two.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=QW1iaXYg4oaQIHsg4p+oMSzwnZWp4p+pIDsg4p+oMizwnZWoLPCdlanin6kgfQpBbWJpdiAnYScKJ2EnIEFtYml2ICdiJw==">βοΈ</a><pre> <span class='Function'>Ambiv</span> <span class='Gets'>β</span> <span class='Brace'>{</span> <span class='Bracket'>β¨</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Value'>π©</span><span class='Bracket'>β©</span> <span class='Head'>;</span> <span class='Bracket'>β¨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Value'>π¨</span><span class='Separator'>,</span><span class='Value'>π©</span><span class='Bracket'>β©</span> <span class='Brace'>}</span> <span class='Function'>Ambiv</span> <span class='String'>'a'</span> β¨ 1 'a' β© <span class='String'>'a'</span> <span class='Function'>Ambiv</span> <span class='String'>'b'</span> β¨ 2 'a' 'b' β© </pre> <p>Bodies before the last two must have headers that include arguments. When a block that includes this type of header is called, its headers are checked in order for compatibility with the arguments. The first body with a compatible header is used.</p> -<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Q2FzZUFkZCDihpAgeyAy8J2VijM6MOKAvzUgOyAy8J2VivCdlak64p+oMSwyK/Cdlanin6kgOyDwnZWK8J2VqToy4oC/8J2VqSB9CjIgQ2FzZUFkZCAzCjIgQ2FzZUFkZCA0CiAgQ2FzZUFkZCA0">βοΈ</a><pre> <span class='Function'>CaseAdd</span> <span class='Gets'>β</span> <span class='Brace'>{</span> <span class='Number'>2</span><span class='Function'>π</span><span class='Number'>3</span><span class='Value'>:</span><span class='Number'>0</span><span class='Ligature'>βΏ</span><span class='Number'>5</span> <span class='Value'>;</span> <span class='Number'>2</span><span class='Function'>π</span><span class='Value'>π©:</span><span class='Bracket'>β¨</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Number'>2</span><span class='Function'>+</span><span class='Value'>π©</span><span class='Bracket'>β©</span> <span class='Value'>;</span> <span class='Function'>π</span><span class='Value'>π©:</span><span class='Number'>2</span><span class='Ligature'>βΏ</span><span class='Value'>π©</span> <span class='Brace'>}</span> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Q2FzZUFkZCDihpAgeyAy8J2VijM6MOKAvzUgOyAy8J2VivCdlak64p+oMSwyK/Cdlanin6kgOyDwnZWK8J2VqToy4oC/8J2VqSB9CjIgQ2FzZUFkZCAzCjIgQ2FzZUFkZCA0CiAgQ2FzZUFkZCA0">βοΈ</a><pre> <span class='Function'>CaseAdd</span> <span class='Gets'>β</span> <span class='Brace'>{</span> <span class='Number'>2</span><span class='Function'>π</span><span class='Number'>3</span><span class='Head'>:</span><span class='Number'>0</span><span class='Ligature'>βΏ</span><span class='Number'>5</span> <span class='Head'>;</span> <span class='Number'>2</span><span class='Function'>π</span><span class='Value'>π©</span><span class='Head'>:</span><span class='Bracket'>β¨</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Number'>2</span><span class='Function'>+</span><span class='Value'>π©</span><span class='Bracket'>β©</span> <span class='Head'>;</span> <span class='Function'>π</span><span class='Value'>π©</span><span class='Head'>:</span><span class='Number'>2</span><span class='Ligature'>βΏ</span><span class='Value'>π©</span> <span class='Brace'>}</span> <span class='Number'>2</span> <span class='Function'>CaseAdd</span> <span class='Number'>3</span> β¨ 0 5 β© <span class='Number'>2</span> <span class='Function'>CaseAdd</span> <span class='Number'>4</span> @@ -206,16 +206,16 @@ <h3 id="case-headers"><a class="header" href="#case-headers">Case headers</a></h3> <p>A special rule allows for convenient case-matching syntax for one-argument functions. In any function header with one argument, the function name can be omitted as long as the argument is <em>not</em> a plain identifierβit must be <code><span class='Value'>π©</span></code> or a compound value like a list to distinguish it from an immediate block label.</p> <pre><span class='Function'>Test</span> <span class='Gets'>β</span> <span class='Brace'>{</span> - <span class='String'>"abc"</span><span class='Value'>:</span> <span class='String'>"string"</span> <span class='Value'>;</span> - <span class='Bracket'>β¨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Value'>b</span><span class='Bracket'>β©</span><span class='Value'>:</span> <span class='Function'>β½</span><span class='Value'>π©</span> <span class='Value'>;</span> - <span class='Number'>5</span><span class='Value'>:</span> <span class='String'>"number"</span> <span class='Value'>;</span> - <span class='Value'>π©:</span> <span class='String'>"default"</span> + <span class='String'>"abc"</span><span class='Head'>:</span> <span class='String'>"string"</span> <span class='Head'>;</span> + <span class='Bracket'>β¨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Value'>b</span><span class='Bracket'>β©</span><span class='Head'>:</span> <span class='Function'>β½</span><span class='Value'>π©</span> <span class='Head'>;</span> + <span class='Number'>5</span><span class='Head'>:</span> <span class='String'>"number"</span> <span class='Head'>;</span> + <span class='Value'>π©</span><span class='Head'>:</span> <span class='String'>"default"</span> <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 two elements and for the first to be less than the second before using the first body. Otherwise it moves to the next body, which is unconditional.</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> +<p>Destructuring with a header is quite limited, only allowing matching structure and data with exact equality. A predicate, written with <code><span class='Head'>?</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 two elements and for the first to be less than the second before using the first body. Otherwise it moves to the next body, which is unconditional.</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='Head'>:</span> <span class='Value'>a</span><span class='Function'><</span><span class='Value'>b</span><span class='Head'>?</span> <span class='String'>"ok"</span> <span class='Head'>;</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" @@ -224,12 +224,12 @@ <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> +<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='Head'>?</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='Head'>?</span> <span class='Value'>r</span> <span class='Head'>;</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. This is an immediate block with multiple bodies, something that makes sense with predicates but not headers. But <code><span class='Value'>?;</span></code> offers more possibilities. 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> +<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='Head'>?</span> <span class='Value'>a</span> <span class='Head'>;</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. This is an immediate block with multiple bodies, something that makes sense with predicates but not headers. But <code><span class='Head'>?;</span></code> offers more possibilities. 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='Head'>?</span> <span class='Value'>π©</span><span class='Function'>β€</span><span class='Number'>8</span><span class='Head'>?</span> <span class='Number'>2</span><span class='Function'>|</span><span class='Value'>π©</span> <span class='Head'>;</span> <span class='Value'>π©</span><span class='Function'>=</span><span class='Number'>0</span><span class='Head'>?</span> <span class='String'>@</span> <span class='Head'>;</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>ββ @@ -237,8 +237,8 @@ @ β β 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> +<p>This structure is still constrained by the rules of block bodies: each instance of <code><span class='Head'>;</span></code> is a separate scope, so that variables defined before a <code><span class='Head'>?</span></code> don't survive past the <code><span class='Head'>;</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='Head'>?</span> <span class='Number'>β</span> <span class='Head'>;</span> <span class='Value'>n</span> <span class='Brace'>}</span> <span class='String'>"abc"</span> <span class='Error'>Error: Undefined identifier</span> </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> +<p>This is the main drawback of predicates relative to guards in APL dfns (also written with <code><span class='Head'>?</span></code>), while the advantage is that it allows multiple expressions, or extra conditions, after a <code><span class='Head'>?</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> |
