diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-06-26 21:00:25 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-06-26 21:00:25 -0400 |
| commit | b6185d5029e2adcc721c0cc2097f591d9a09f135 (patch) | |
| tree | bf777353ed2a9b28d8b1577c5f36b68605240375 /docs | |
| parent | c618ade174cc2b4e428457751ad8dd01130c2239 (diff) | |
I am in editing stepped in so far that, should I wade no more, returning were as tedious as go o'er.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/doc/arithmetic.html | 23 | ||||
| -rw-r--r-- | docs/doc/array.html | 18 | ||||
| -rw-r--r-- | docs/doc/arrayrepr.html | 20 | ||||
| -rw-r--r-- | docs/doc/assert.html | 19 | ||||
| -rw-r--r-- | docs/doc/based.html | 2 | ||||
| -rw-r--r-- | docs/doc/birds.html | 2 | ||||
| -rw-r--r-- | docs/doc/block.html | 60 | ||||
| -rw-r--r-- | docs/doc/choose.html | 8 | ||||
| -rw-r--r-- | docs/doc/compose.html | 6 |
9 files changed, 92 insertions, 66 deletions
diff --git a/docs/doc/arithmetic.html b/docs/doc/arithmetic.html index 46831cad..9e511044 100644 --- a/docs/doc/arithmetic.html +++ b/docs/doc/arithmetic.html @@ -22,6 +22,7 @@ <th>Symbol</th> <th>Dyad</th> <th>Monad</th> +<th align="center">default <code><span class='Value'>π¨</span></code></th> </tr> </thead> <tbody> @@ -29,35 +30,41 @@ <td><code><span class='Function'>+</span></code></td> <td>Add</td> <td><em>(Conjugate)</em></td> +<td align="center">β</td> </tr> <tr> <td><code><span class='Function'>-</span></code></td> <td>Subtract</td> <td>Negate</td> +<td align="center">0</td> </tr> <tr> <td><code><span class='Function'>Γ</span></code></td> <td>Multiply</td> <td>Sign</td> +<td align="center">β</td> </tr> <tr> <td><code><span class='Function'>Γ·</span></code></td> <td>Divide</td> <td>Reciprocal</td> +<td align="center">1</td> </tr> <tr> <td><code><span class='Function'>β</span></code></td> <td>Power</td> <td>Exponential</td> +<td align="center"><em>e</em></td> </tr> <tr> <td><code><span class='Function'>β</span></code></td> <td>Root</td> <td>Square root</td> +<td align="center">2</td> </tr> </tbody> </table> -<p>The dyadic functions should all be familiar operations, and most likely you are familiar with the symbols <code><span class='Function'>+-ΓΓ·β</span></code>. In fact the large <code><span class='Function'>Γ</span></code> and <code><span class='Function'>Γ·</span></code> might strike you as a regression to early school years, before division was written vertically and multiplication with a simple dot or no symbol at all (BQN reserves the distinction of having no symbol for application and composition). Like these, raising to a power or exponentiation is made regular by giving it the symbol <code><span class='Function'>β</span></code>βa true Unicode star and <em>not</em> an asterisk. The Root function <code><span class='Function'>β</span></code> is also modified to be a binary function, which raises <code><span class='Value'>π©</span></code> to the power <code><span class='Function'>Γ·</span><span class='Value'>π¨</span></code>. In ASCII programming languages <code><span class='Function'>Γ</span></code>, <code><span class='Function'>Γ·</span></code>, and <code><span class='Function'>β</span></code> are often written <code><span class='Value'>*</span></code>, <code><span class='Function'>/</span></code>, and <code><span class='Value'>^</span></code> or <code><span class='Value'>**</span></code>.</p> +<p>The dyadic (two-argument) functions should all be familiar operations, and most likely you know the symbols <code><span class='Function'>+-ΓΓ·β</span></code>. In fact the large <code><span class='Function'>Γ</span></code> and <code><span class='Function'>Γ·</span></code> might strike you as a regression to early school years, before division was written vertically and multiplication with a simple dot or no symbol at all. Like these, raising to a power or exponentiation is made regular by giving it the symbol <code><span class='Function'>β</span></code>βa true Unicode star and <em>not</em> an asterisk. The Root function <code><span class='Function'>β</span></code> is also modified to be a binary function, which raises <code><span class='Value'>π©</span></code> to the power <code><span class='Function'>Γ·</span><span class='Value'>π¨</span></code>. In ASCII programming languages <code><span class='Function'>Γ</span></code>, <code><span class='Function'>Γ·</span></code>, and <code><span class='Function'>β</span></code> are often written <code><span class='Value'>*</span></code>, <code><span class='Function'>/</span></code>, and <code><span class='Value'>^</span></code> or <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=MiArIDPigL8x4oC/MOKAvzUKCjLigL81IC0gMeKAvzkKCjEuNeKAvzLigL8wLjUgw5cgMgoKM+KAvzTigL8xIMO3IDIKCjMg4ouGIDDigL8x4oC/MgoKNCDiiJogODE=">βοΈ</a><pre> <span class='Number'>2</span> <span class='Function'>+</span> <span class='Number'>3</span><span class='Ligature'>βΏ</span><span class='Number'>1</span><span class='Ligature'>βΏ</span><span class='Number'>0</span><span class='Ligature'>βΏ</span><span class='Number'>5</span> β¨ 5 3 2 7 β© @@ -76,7 +83,7 @@ <span class='Number'>4</span> <span class='Function'>β</span> <span class='Number'>81</span> 3 </pre> -<p>Each of these functions also has a meaning with only one argument, although in mathematics only <code><span class='Function'>-</span></code> does. The relationship of negation to addition is extended to division (relative to multiplication) as well, so that <code><span class='Function'>Γ·</span><span class='Value'>π©</span></code> gives the reciprocal <code><span class='Number'>1</span><span class='Function'>Γ·</span><span class='Value'>π©</span></code> of its argument. Power (<code><span class='Function'>β</span></code>) is also extended with a default left argument of <a href="https://en.wikipedia.org/wiki/E_(mathematical_constant)">Euler's number</a> <em>e</em>. The default left argument for Root is 2, giving the well-known Square Root.</p> +<p>Each of these functions also has a meaning with only one argument, although mathematics only defines <code><span class='Function'>-</span></code> in this way. The relationship of negation to addition is extended to division (relative to multiplication) as well, so that <code><span class='Function'>Γ·</span><span class='Value'>π©</span></code> gives the reciprocal <code><span class='Number'>1</span><span class='Function'>Γ·</span><span class='Value'>π©</span></code> of its argument. Power (<code><span class='Function'>β</span></code>) is also extended with a default left argument of <a href="https://en.wikipedia.org/wiki/E_(mathematical_constant)">Euler's number</a> <em>e</em>. The default left argument for Root is 2, giving the well-known Square Root.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=LSA2CgrDtyAw4oC/MeKAvzIKCuKLhiAw4oC/MeKAvzIKCuKImiAw4oC/MeKAvzLigL80">βοΈ</a><pre> <span class='Function'>-</span> <span class='Number'>6</span> Β―6 @@ -90,7 +97,7 @@ β¨ 0 1 1.414213562373095 2 β© </pre> <p>Take note of the difference between the function <code><span class='Function'>-</span></code>, and the "high minus" character <code><span class='Number'>Β―</span></code>, which is a part of <a href="syntax.html#constants">numeric notation</a>. Also shown is the number <code><span class='Number'>β</span></code>, which BQN supports along with <code><span class='Number'>Β―β</span></code> (but depending on implementation BQN may or may not keep track of <code><span class='Number'>Β―0</span></code>. Integer optimization loses the distinction so it's best not to rely on it).</p> -<p>The logarithm is written with Undo: <code><span class='Function'>β</span><span class='Modifier'>βΌ</span></code>. As with Power, the default base is <em>e</em>, giving a natural logarithm.</p> +<p>The logarithm is written with <a href="undo.html">Undo</a>: <code><span class='Function'>β</span><span class='Modifier'>βΌ</span></code>. As with Power, the default base is <em>e</em>, giving a natural logarithm.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4ouG4oG8IDEwCgoyIOKLhuKBvCAxMDI0">βοΈ</a><pre> <span class='Function'>β</span><span class='Modifier'>βΌ</span> <span class='Number'>10</span> 2.302585092994046 @@ -186,7 +193,7 @@ <span class='Function'>|</span> <span class='Number'>Β―β</span><span class='Ligature'>βΏ</span><span class='Number'>Β―6</span><span class='Ligature'>βΏ</span><span class='Number'>0</span><span class='Ligature'>βΏ</span><span class='Number'>2</span> β¨ β 6 0 2 β© </pre> -<p>Floor (<code><span class='Function'>β</span></code>) returns the largest integer less than or equal to the argument, and Ceiling (<code><span class='Function'>β</span></code>) returns the smallest one greater than or equal to it. For this purpose <code><span class='Number'>Β―β</span></code> and <code><span class='Number'>β</span></code> are treated as integers, so that the floor or ceiling of an infinity is itself. Absolute value removes the argument's sign by negating it if it is less than 0, so that its result is always non-negative.</p> +<p>Floor (<code><span class='Function'>β</span></code>) returns the largest integer less than or equal to the argument, and Ceiling (<code><span class='Function'>β</span></code>) returns the smallest one greater than or equal to it. For this purpose <code><span class='Number'>Β―β</span></code> and <code><span class='Number'>β</span></code> are treated as integers, so that the floor or ceiling of an infinity is itself. Absolute value removes the sign of <code><span class='Value'>π©</span></code> by negating it if it's less than 0, so that its result is always non-negative.</p> <p>Minimum (<code><span class='Function'>β</span></code>) returns the smaller of its two arguments, and Maximum (<code><span class='Function'>β</span></code>) returns the larger. These functions are loosely related to Floor and Ceiling in their use of comparison, and can be defined similarly: for example, the minimum of two numbers is the largest number less than or equal to both of them. To take the minimum or maximum of an entire list, use a <a href="fold.html">fold</a>.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyDijIog4oaVOAoK4oy94oq44oyIIOKGlTg=">βοΈ</a><pre> <span class='Number'>3</span> <span class='Function'>β</span> <span class='Function'>β</span><span class='Number'>8</span> β¨ 0 1 2 3 3 3 3 3 β© @@ -194,7 +201,7 @@ <span class='Function'>β½</span><span class='Modifier2'>βΈ</span><span class='Function'>β</span> <span class='Function'>β</span><span class='Number'>8</span> β¨ 7 6 5 4 4 5 6 7 β© </pre> -<p>Modulus (<code><span class='Function'>|</span></code>) is similar to the modular division operation written <code><span class='Value'>%</span></code> in C-like languages, but it takes the arguments in the opposite order, and differs in its handling of negative arguments. It's defined to be <code><span class='Brace'>{</span><span class='Value'>π©</span><span class='Function'>-</span><span class='Value'>π¨</span><span class='Function'>Γβ</span><span class='Value'>π©</span><span class='Function'>Γ·</span><span class='Value'>π¨</span><span class='Brace'>}</span></code>, except that the multiplication should always return 0 if its right argument is 0, even if <code><span class='Value'>π¨</span></code> is infinite.</p> +<p>Modulus (<code><span class='Function'>|</span></code>) is similar to the modular division operation written <code><span class='Value'>%</span></code> in C-like languages, but it takes the arguments in the opposite order, and differs in its handling of negative arguments. It's the same computation as <code><span class='Brace'>{</span><span class='Value'>π©</span><span class='Function'>-</span><span class='Value'>π¨</span><span class='Function'>Γβ</span><span class='Value'>π©</span><span class='Function'>Γ·</span><span class='Value'>π¨</span><span class='Brace'>}</span></code> but probably has better precision.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyB8IOKGlTgKCjMgfCDCrzU=">βοΈ</a><pre> <span class='Number'>3</span> <span class='Function'>|</span> <span class='Function'>β</span><span class='Number'>8</span> β¨ 0 1 2 0 1 2 0 1 β© @@ -291,11 +298,11 @@ β¨ β¨ 1 0 β© 1 1 β© β </pre> -<p>With two arguments many combinations are possible. Arrays of equal shape are matched element-wise, and an atom is matched to every element of an array.</p> -<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MTDigL8yMOKAvzMwICsgNeKAvzbigL83CgoxMCDDlyA04oC/M+KAvzLiiY024oC/N+KAvzg=">βοΈ</a><pre> <span class='Number'>10</span><span class='Ligature'>βΏ</span><span class='Number'>20</span><span class='Ligature'>βΏ</span><span class='Number'>30</span> <span class='Function'>+</span> <span class='Number'>5</span><span class='Ligature'>βΏ</span><span class='Number'>6</span><span class='Ligature'>βΏ</span><span class='Number'>7</span> +<p>With two arguments, many combinations are possible. Arrays of equal shape are matched element-wise, and an atom is matched to every element of an array.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MTDigL8yMOKAvzMwICsgNeKAvzbigL83CgoxMCDDlyBbNOKAvzPigL8yLDbigL834oC/OF0=">βοΈ</a><pre> <span class='Number'>10</span><span class='Ligature'>βΏ</span><span class='Number'>20</span><span class='Ligature'>βΏ</span><span class='Number'>30</span> <span class='Function'>+</span> <span class='Number'>5</span><span class='Ligature'>βΏ</span><span class='Number'>6</span><span class='Ligature'>βΏ</span><span class='Number'>7</span> β¨ 15 26 37 β© - <span class='Number'>10</span> <span class='Function'>Γ</span> <span class='Number'>4</span><span class='Ligature'>βΏ</span><span class='Number'>3</span><span class='Ligature'>βΏ</span><span class='Number'>2</span><span class='Function'>β</span><span class='Number'>6</span><span class='Ligature'>βΏ</span><span class='Number'>7</span><span class='Ligature'>βΏ</span><span class='Number'>8</span> + <span class='Number'>10</span> <span class='Function'>Γ</span> <span class='Bracket'>[</span><span class='Number'>4</span><span class='Ligature'>βΏ</span><span class='Number'>3</span><span class='Ligature'>βΏ</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Number'>6</span><span class='Ligature'>βΏ</span><span class='Number'>7</span><span class='Ligature'>βΏ</span><span class='Number'>8</span><span class='Bracket'>]</span> ββ β΅ 40 30 20 60 70 80 diff --git a/docs/doc/array.html b/docs/doc/array.html index 827f05c0..f675b171 100644 --- a/docs/doc/array.html +++ b/docs/doc/array.html @@ -7,8 +7,8 @@ <h1 id="the-array"><a class="header" href="#the-array">The array</a></h1> <p>As BQN is an array language, it's often helpful to understand what an array is when writing BQN programs. Fully describing the concept is sometimes <a href="https://www.jsoftware.com/papers/array.htm">held to be tricky</a>; here we'll see definitions, examples, and metaphors.</p> <p>In BQN, as in APL, arrays are multidimensional, instead of strictly linear. Languages like Python, Javascript, or Haskell offer only one-dimensional arrays with <code><span class='Bracket'>[]</span></code> syntax, and typically represent multidimensional data with nested arrays. Multidimensional arrays have fundamental differences relative to this model.</p> -<p>BQN's arrays are immutable, meaning that an array is entirely defined by its attributes, and there is no way to modify an existing array, only to produce another array that has changes relative to it. As a result, an array can never contain itself, and arrays form an inductive type. BQN's <a href="lexical.html#mutation">mutable</a> types are operations and namespaces.</p> -<p>An array might also have a <a href="fill.html">fill element</a> that captures some structural information about its elements and is used by a few operations. The fill, as an inferred property, isn't considered to truly be part of the array but is instead some information about the array that the interpreter keeps track of. So it's out of scope here.</p> +<p>BQN's arrays are immutable, meaning that an array is entirely defined by its attributes, and there's no way to modify an existing array, only to produce another array that has changes relative to it. As a result, an array can never contain itself. BQN's <a href="lexical.html#mutation">mutable</a> types are operations and namespaces.</p> +<p>An array might also have a <a href="fill.html">fill element</a> that captures some structural information about its elements and is used by a few operations. As an inferred property, the fill isn't considered to truly be part of the array, but is instead some information about it that the interpreter keeps track of. So it's out of scope here.</p> <svg viewBox='-36 -15 544 426'> <g fill='currentColor' stroke-linecap='round' text-anchor='middle' font-size='14' font-family='BQN,monospace'> <rect class='code' stroke-width='1.5' rx='12' x='-4' y='0' width='480' height='396'/> @@ -106,7 +106,7 @@ <p>The axes of an array must be independent, that is, the positions present in one axis are fixed for the entire array and don't depend on other axes. This is a difference relative to a nested list model. When storing data in nested lists, the outer axis comes first and later axes are subordinate to it. The length of the second axis depends completely on the position in the first. A programmer might choose the lengths so it doesn't in a particular case, but in a BQN array differing lengths simply aren't representable.</p> <p>The array also needs to be complete. Every elementβevery combination of positionsβmust have a value. This value could be a placeholder like <code><span class='String'>@</span></code>, but it has to be <em>something</em> (in the spending example, everyone spends some amount at each store, even if it's zero). And of course, there are no extra elements that don't fit into the positioning systemβthe <a href="fill.html">fill</a> isn't really part of the array, but extra information about it.</p> <h2 id="ordering-and-indices"><a class="header" href="#ordering-and-indices">Ordering and indices</a></h2> -<p>To finish this definition of an array we also need to nail down the idea of a position. The positions along one dimension can't be labelled in any way, but they have a linear ordering (mathematically speaking, a <a href="https://en.wikipedia.org/wiki/Total_order">total order</a>: out of any two different positions one comes earlier and the other later). BQN keeps track of this order: for example, when we <a href="join.html">join</a> two arrays it places positions in <code><span class='Value'>π¨</span></code> before those of <code><span class='Value'>π©</span></code> and otherwise maintains the original ordering.</p> +<p>To finish this definition of an array we also need to nail down the idea of a position. The positions along one dimension can't have labels attached to them, but they have a linear ordering (mathematically speaking, a <a href="https://en.wikipedia.org/wiki/Total_order">total order</a>: out of any two different positions one comes earlier and the other later). BQN keeps track of this order: for example, when we <a href="join.html">join</a> two arrays it places positions in <code><span class='Value'>π¨</span></code> before those of <code><span class='Value'>π©</span></code> and otherwise maintains the original orderings.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ImJlZm9yZSIg4oi+ICJhZnRlciI=">βοΈ</a><pre> <span class='String'>"before"</span> <span class='Function'>βΎ</span> <span class='String'>"after"</span> "beforeafter" </pre> @@ -116,10 +116,10 @@ <p>The number of axes in an array is called its <strong>rank</strong>. The number of positions along an axis is called its <strong>length</strong>, and the length of an array means its length along the first axis, or <code><span class='Number'>1</span></code> if there are no axes. The list of the lengths along each axis is the array's <strong>shape</strong>, and describes the possible element locations completely. In BQN they're exposed as the <a href="shape.html">functions</a> Rank (<code><span class='Function'>=</span></code>), Length (<code><span class='Function'>β </span></code>), and Shape (<code><span class='Function'>β’</span></code>).</p> <p>The total number of elements in an array is its <strong>bound</strong>, and can be found using <a href="reshape.html">Deshape</a> with <code><span class='Function'>β </span><span class='Modifier2'>β</span><span class='Function'>β₯</span></code>, or by multiplying all the lengths in the shape. An array of rank 0, which always contains exactly one element, is called a <a href="enclose.html#whats-a-unit"><strong>unit</strong></a>, while an array of rank 1 is called a <strong>list</strong> and an array of rank 2 is called a <strong>table</strong>.</p> <h2 id="elements"><a class="header" href="#elements">Elements</a></h2> -<p>Any BQN value can be used as an array element, including another array (BQN, as a dynamically-typed language, doesn't restrict the types that can be used in one context without a good reason). However, BQN arrays are restricted relative to other array models. Frameworks like NumPy or Julia have mutable arrays, so that the value of an element can be changed after the array is created. This allows an array to be its own element, by creating an array and then inserting it into itself. This would be unnatural in BQN, where an array can only be formed from elements that already exist. In BQN only operations and namespaces are <a href="lexical.html#mutation">mutable</a>.</p> -<p>An array with no elements (a bound of 0) is called <strong>empty</strong>. These arrays can cause problems when a property should be computed from the elements of an array, like the sum <code><span class='Function'>+</span><span class='Modifier'>Β΄</span><span class='Value'>π©</span></code> or shape of the <a href="couple.html#merge-and-array-theory">merged</a> array <code><span class='Function'>></span><span class='Value'>π©</span></code>. BQN has two mechanisms to make these cases work better. First, reductions like <code><span class='Function'>+</span><span class='Modifier'>Β΄</span></code> have <a href="fold.html#identity-values">identity values</a> for certain functions, so that <code><span class='Function'>+</span><span class='Modifier'>Β΄</span><span class='Bracket'>β¨β©</span></code> is <code><span class='Number'>0</span></code> for example. Second, every array might have a <a href="fill.html">fill element</a>, a special "typical element" for the array. Functions like Merge use this element's structure to determine the result shape when there are no actual elements to be used.</p> +<p>Any BQN value can be used as an array element, including another array (BQN, as a dynamically-typed language, doesn't restrict the types that can be used in one context without a good reason). However, BQN arrays are in some sense restricted relative to other array models. Frameworks like NumPy or Julia have mutable arrays, so that the value of an element can be changed after the array is created. This allows an array to be its own element, by creating an array and then inserting it into itself. This would be unnatural in BQN, where an array can only be formed from elements that already exist. In BQN only operations and namespaces are <a href="lexical.html#mutation">mutable</a>.</p> +<p>An array with no elements (a bound of 0) is called <strong>empty</strong>. These arrays can cause problems when a property should be computed from the elements of an array, like the sum <code><span class='Function'>+</span><span class='Modifier'>Β΄</span><span class='Value'>π©</span></code> or shape of the <a href="couple.html#merge-and-array-theory">merged</a> array <code><span class='Function'>></span><span class='Value'>π©</span></code>. BQN has two mechanisms to make these cases work better. First, Fold (<code><span class='Modifier'>Β΄</span></code>) and Insert (<code><span class='Modifier'>Λ</span></code>) have <a href="fold.html#identity-values">identity values</a> for certain functions, so that <code><span class='Function'>+</span><span class='Modifier'>Β΄</span><span class='Bracket'>β¨β©</span></code> is <code><span class='Number'>0</span></code> for example. Second, every array might have a <a href="fill.html">fill element</a>, a special "typical element" for the array. Functions like Merge use this element's structure to determine the result shape when there are no actual elements to be used.</p> <h2 id="cells"><a class="header" href="#cells">Cells</a></h2> -<p>The contents of an array are its elements, but it also makes sense to split up an array into subarrays of elements called cells. The most important kind of cell, a <strong>major cell</strong> consists of all the elements that have indices beginning with some particular index <code><span class='Value'>i</span></code>. For this to make sense, <code><span class='Value'>i</span></code> must be between <code><span class='Number'>0</span></code> and the length <code><span class='Value'>l</span></code> of the array's first axis, so that there are <code><span class='Value'>l</span></code> major cells each identified by an index.</p> +<p>The contents of an array are its elements, but it also makes sense to split up an array into subarrays of elements called cells. The most important kind of cell, a <strong>major cell</strong>, consists of all the elements whose indices begin with some particular index <code><span class='Value'>i</span></code>. For this to make sense, <code><span class='Value'>i</span></code> must be between <code><span class='Number'>0</span></code> and the length <code><span class='Value'>n</span></code> of the array's first axis, so that there are <code><span class='Value'>n</span></code> major cells each identified by an index.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MuKAvzPigL80IMOX4oycIDHigL814oC/OOKAvzExCgoxIOKKjyAy4oC/M+KAvzQgw5fijJwgMeKAvzXigL844oC/MTEgICMgTWFqb3IgY2VsbCAx">βοΈ</a><pre> <span class='Number'>2</span><span class='Ligature'>βΏ</span><span class='Number'>3</span><span class='Ligature'>βΏ</span><span class='Number'>4</span> <span class='Function'>Γ</span><span class='Modifier'>β</span> <span class='Number'>1</span><span class='Ligature'>βΏ</span><span class='Number'>5</span><span class='Ligature'>βΏ</span><span class='Number'>8</span><span class='Ligature'>βΏ</span><span class='Number'>11</span> ββ β΅ 2 10 16 22 @@ -130,12 +130,12 @@ <span class='Number'>1</span> <span class='Function'>β</span> <span class='Number'>2</span><span class='Ligature'>βΏ</span><span class='Number'>3</span><span class='Ligature'>βΏ</span><span class='Number'>4</span> <span class='Function'>Γ</span><span class='Modifier'>β</span> <span class='Number'>1</span><span class='Ligature'>βΏ</span><span class='Number'>5</span><span class='Ligature'>βΏ</span><span class='Number'>8</span><span class='Ligature'>βΏ</span><span class='Number'>11</span> <span class='Comment'># Major cell 1 </span>β¨ 3 15 24 33 β© </pre> -<p>A major cell still has an array structure: it retains all the axes of the original array other than the first. So it has its own major cells, identified by the index <code><span class='Value'>i</span></code> of the original major cell and <code><span class='Value'>j</span></code> within it. These are also cells of the original array. Generalizing, a <strong>cell</strong> with index list <code><span class='Value'>l</span></code> is defined to be the array of all elements whose indices begin with <code><span class='Value'>l</span></code>. In an array with rank <code><span class='Value'>n</span></code>, the cell rank is <code><span class='Value'>n</span><span class='Function'>-β </span><span class='Value'>l</span></code>, and cells grouped using this rank. An <code><span class='Value'>n</span></code>-cell mst have an empty cell index, so that it includes all elementsβit's the entire array! An <code><span class='Value'>n</span><span class='Function'>-</span><span class='Number'>1</span></code> cell, also called a Β―1-cell, is a major cell. A 0-cell has an index of length <code><span class='Value'>n</span></code>, and contains a single element.</p> +<p>A major cell still has an array structure: it retains all the axes of the original array other than the first. So it has its own major cells, identified by the index <code><span class='Value'>i</span></code> of the original major cell and <code><span class='Value'>j</span></code> within it. These are also cells of the original array. Generalizing, a <strong>cell</strong> with index list <code><span class='Value'>l</span></code> is defined to be the array of all elements whose indices begin with <code><span class='Value'>l</span></code>. In an array with rank <code><span class='Value'>r</span></code>, the cell rank is <code><span class='Value'>r</span><span class='Function'>-β </span><span class='Value'>l</span></code>, and cells grouped using this rank. An <code><span class='Value'>r</span></code>-cell must have an empty cell index, so that it includes all elementsβit's the entire array! An <code><span class='Value'>r</span><span class='Function'>-</span><span class='Number'>1</span></code> cell, also called a Β―1-cell, is a major cell. A 0-cell has an index of length <code><span class='Value'>r</span></code>, and contains a single element.</p> <p>Cells are the center of the <a href="leading.html">leading axis model</a> used to structure many array primitives.</p> <h2 id="properties"><a class="header" href="#properties">Properties</a></h2> <p>Summarizing, the values needed to define an array are its rank (the number of axes), its shape (the number of positions along each axis), and the value of each element (that is, at each combination of positions). Two arrays <a href="match.html">match</a> when all these values match.</p> -<p>If the rank is considered to be part of the shape, as it is when the shape is a BQN list, then the array is defined by its shape and element listβfrom <a href="reshape.html">deshape</a>.</p> -<p>Here's a somewhat informal mathematical take. Given a set of possible element values <code><span class='Function'>T</span></code>, a <em>list</em> of <code><span class='Function'>T</span></code> of length <code><span class='Value'>l</span></code> is a map from natural numbers less than <code><span class='Value'>l</span></code> to <code><span class='Function'>T</span></code>. An array is a rank <code><span class='Value'>r</span></code>, along with a list <code><span class='Value'>s</span></code> of natural numbers of length <code><span class='Value'>r</span></code>, and a map from lists of natural numbers <code><span class='Value'>i</span></code> that satisfy <code><span class='Value'>i</span><span class='Paren'>(</span><span class='Value'>j</span><span class='Paren'>)</span> <span class='Function'><</span> <span class='Value'>s</span><span class='Paren'>(</span><span class='Value'>j</span><span class='Paren'>)</span></code> for all natural numbers <code><span class='Value'>j</span><span class='Function'><</span><span class='Value'>r</span></code> to BQN values. Arrays are an inductive type, so that an array can only be defined using elements that already exist. As a result an array's elements are always values of lesser complexity and selecting one element of an array, then an element of that element, and so on, must eventually reach a non-array.</p> +<p>If the rank is considered to be part of the shape, as it is when the shape is a BQN list, then the array is defined by its shape, and element list as returned by <a href="reshape.html">deshape</a>.</p> +<p>Here's a somewhat informal mathematical take. Given a set of possible element values <code><span class='Function'>T</span></code>, a <em>list</em> of <code><span class='Function'>T</span></code> of length <code><span class='Value'>l</span></code> is a map from natural numbers less than <code><span class='Value'>l</span></code> to <code><span class='Function'>T</span></code>. An array is a rank <code><span class='Value'>r</span></code>, along with a list <code><span class='Value'>s</span></code> of natural numbers of length <code><span class='Value'>r</span></code>, and a map from lists of natural numbers <code><span class='Value'>i</span></code> that satisfy <code><span class='Value'>i</span><span class='Paren'>(</span><span class='Value'>j</span><span class='Paren'>)</span> <span class='Function'><</span> <span class='Value'>s</span><span class='Paren'>(</span><span class='Value'>j</span><span class='Paren'>)</span></code> for all natural numbers <code><span class='Value'>j</span><span class='Function'><</span><span class='Value'>r</span></code> to BQN values. Arrays are an inductive type, so that an array can only be defined using elements that already exist. As a result, an array's elements are always values of lesser complexity than it: selecting one element of an array, then an element of that element, and so on, must eventually reach a non-array.</p> <h2 id="why-arrays"><a class="header" href="#why-arrays">Why arrays?</a></h2> <p>The multidimensional array is a fairly simple structure, but there are simpler ones like pairs, lists, sets, and dictionaries. Why does BQN choose the array for its central type? I don't think arrays are always the best data structure (or that BQN is always the best language), but I do think they're one of several good choices and have unique advantages.</p> <p>Arrays offer a lot of flexibility since they generalize lists. This also means that they can be used to represent pairs or sets. Two lists, or an array with a length-2 axis, can represent a map, although it could be hard to use with good performance.</p> diff --git a/docs/doc/arrayrepr.html b/docs/doc/arrayrepr.html index 06a55f82..159bb8f7 100644 --- a/docs/doc/arrayrepr.html +++ b/docs/doc/arrayrepr.html @@ -5,10 +5,10 @@ </head> <div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div> <h1 id="array-notation-and-display"><a class="header" href="#array-notation-and-display">Array notation and display</a></h1> -<p>This page documents ways arrays are represented in BQN: the notation you can use to write them and the way the REPL displays them.</p> +<p>This page documents ways <a href="array.html">arrays</a> are represented in BQN: the notation you can use to write them and the way the REPL displays them.</p> <p>Array display is a feature of a BQN environment such as a REPL. You can also access it with <code><span class='Function'>β’Fmt</span></code>, which takes a value and returns a string indicating how it would be formatted. Array notation is of course part of BQN source code, but you can also go from an array to one possible source code for it using the similar system function <code><span class='Function'>β’Repr</span></code>.</p> <h2 id="array-display"><a class="header" href="#array-display">Array display</a></h2> -<p>Although it's really part of the language environment and not BQN itself, let's look at display first so it's clear what arrays we're talking about later on. The BQN REPL prints arrays in a way that's meant to unambiguously show the structure and data, but doesn't correspond to BQN source code. A few examples are given below; of course, displays like this appear all over the documentation.</p> +<p>Although it's really part of the language environment and not BQN itself, let's look at display first so it's clear what arrays we're talking about later on. A BQN session prints arrays in a way that's meant to unambiguously show the structure and data, but doesn't correspond to BQN source code. A few examples are given below; of course, displays like this appear all over the documentation.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oaVIDPigL80ICAgICAgICAgICAgICMgQXJyYXkgb2YgbGlzdHMKCjxAICAgICAgICAgICAgICAgICMgRW5jbG9zZWQgbnVsbAoK4p+o4oaVMywgInh5Iiwg4oaVMuKAvzDin6kgICMgQSBsaXN0IG9mIHRocmVlIGFycmF5cw==">βοΈ</a><pre> <span class='Function'>β</span> <span class='Number'>3</span><span class='Ligature'>βΏ</span><span class='Number'>4</span> <span class='Comment'># Array of lists </span>ββ β΅ β¨ 0 0 β© β¨ 0 1 β© β¨ 0 2 β© β¨ 0 3 β© @@ -42,7 +42,7 @@ β β </pre> -<p>The lack of extra separation is to make it clear that the corners enclose the array rather than any of its elements (elements are still distinguishable becase an individual element won't contain whitespace except maybe between quotes). Now every set of corners indicates one array. This is a good fit for the <a href="based.html">based array model</a>, where data doesn't have to be in an array.</p> +<p>The lack of extra separation is to make it clear that the corners enclose the whole array rather than any of its elements (elements are still distinguishable becase an individual element won't contain whitespace, except maybe between quotes). Every set of corners indicates one array. This is a good fit for the <a href="based.html">based array model</a>, where data doesn't have to be in an array.</p> <h4 id="rank-indicator"><a class="header" href="#rank-indicator">Rank indicator</a></h4> <p>The top left corner indicates the rank of an array. Here's a neat way using <a href="fold.html">Fold</a> (<code><span class='Modifier'>Β΄</span></code>) and <a href="prefixes.html">Prefixes</a> (<code><span class='Function'>β</span></code>) to nest ranks 0 through 6 together:</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MCDipYrin5w8wrQg4oaRNuKlijE=">βοΈ</a><pre> <span class='Number'>0</span> <span class='Function'>β₯</span><span class='Modifier2'>β</span><span class='Function'><</span><span class='Modifier'>Β΄</span> <span class='Function'>β</span><span class='Number'>6</span><span class='Function'>β₯</span><span class='Number'>1</span> @@ -121,7 +121,7 @@ β </pre> <h4 id="empty-arrays"><a class="header" href="#empty-arrays">Empty arrays</a></h4> -<p>The top-left corner can show the rank of an array but not its shape; the shape must be seen from the data. An empty array has no data, and it's hard to tell shape from a bunch of blank space. In general, an empty array is printed as <code><span class='Function'>β</span><span class='Value'>shape</span></code>. An empty list is shown using brackets <code><span class='Bracket'>β¨β©</span></code>, which are discussed in the next section.</p> +<p>The top-left corner can show the rank of an array but not its shape; the shape must be seen from the data. An empty array has no data, and it can be impossible to tell shape from a bunch of blank space. So an empty array is usually printed as <code><span class='Function'>β</span><span class='Value'>shape</span></code>. An empty list is shown using brackets <code><span class='Bracket'>β¨β©</span></code>, which are discussed in the next section.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oaVwqgg4p+oMOKAvzQsIDPigL8w4oC/MSwgMuKAvzDigL8wLCAw4p+p">βοΈ</a><pre> <span class='Function'>β</span><span class='Modifier'>Β¨</span> <span class='Bracket'>β¨</span><span class='Number'>0</span><span class='Ligature'>βΏ</span><span class='Number'>4</span><span class='Separator'>,</span> <span class='Number'>3</span><span class='Ligature'>βΏ</span><span class='Number'>0</span><span class='Ligature'>βΏ</span><span class='Number'>1</span><span class='Separator'>,</span> <span class='Number'>2</span><span class='Ligature'>βΏ</span><span class='Number'>0</span><span class='Ligature'>βΏ</span><span class='Number'>0</span><span class='Separator'>,</span> <span class='Number'>0</span><span class='Bracket'>β©</span> β¨ β0βΏ4 β3βΏ0βΏ1 β2βΏ0βΏ0 β¨β© β© </pre> @@ -157,10 +157,10 @@ <span class='String'>""</span> β¨β© </pre> -<p>This case also covers empty lists, which are shown as <code><span class='Bracket'>β¨β©</span></code>. This includes an empty string, as the only difference between an empty string and any other empty list is its fill element and array displays don't depend on the fill.</p> +<p>This case also covers empty lists, which are shown as <code><span class='Bracket'>β¨β©</span></code>. This includes an empty string: the only difference between an empty string and any other empty list is its fill element, and array displays don't depend on the fill.</p> <h2 id="array-literals"><a class="header" href="#array-literals">Array literals</a></h2> <p><em>The tutorial section <a href="../tutorial/list.html#list-notation">here</a> also covers this topic.</em></p> -<p>There are three kinds literal notation for lists: strings, list notation, and stranding. Strings indicate character lists (with space for the <a href="fill.html">fill</a>) and the other two can combine any sequence of elements. Additionally, there's a square bracket notation that can form higher-rank arrays.</p> +<p>Now it's time to discuss ways to write arrays in a BQN program. There are three kinds literal notation for lists: strings, list notation, and stranding. Strings indicate character lists (with space for the <a href="fill.html">fill</a>) and the other two can combine any sequence of elements. Additionally, there's a square bracket notation that can form higher-rank arrays.</p> <h3 id="strings"><a class="header" href="#strings">Strings</a></h3> <p>A <strong>string</strong> consists of a sequence of characters surrounded by double quotes <code><span class='String'>""</span></code>. The only rule for the characters inside is that any double quote must be escaped by repeating it twice; otherwise the string ends at that point.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Ii0nw5clIiIqIgoKIi0nw5clIioiICAjIEVzY2FwaW5nIGZhaWx1cmU=">βοΈ</a><pre> <span class='String'>"-'Γ%""*"</span> @@ -172,7 +172,7 @@ <p>Even special characters like a newline can appear in a string literal, so that string literals are automatically multi-line.</p> <h3 id="brackets"><a class="header" href="#brackets">Brackets</a></h3> <p><strong>List notation</strong> uses angle brackets <code><span class='Bracket'>β¨β©</span></code>. The contents are structurally identical to those of a <a href="block.html">block</a>, that is, a list of expressions <a href="syntax.html#separators">separated</a> by <code><span class='Separator'>,</span></code> or <code><span class='Separator'>β</span></code> or newlines. Unlike a block, a list doesn't need to have any expressions: <code><span class='Bracket'>β¨β©</span></code> or <code><span class='Bracket'>β¨</span><span class='Separator'>β</span><span class='Bracket'>β©</span></code> or <code><span class='Bracket'>β¨</span><span class='Separator'>,,β,</span><span class='Bracket'>β©</span></code> will create an empty list. Other differences are that a list doesn't introduce a new <a href="lexical.html">scope</a> and all of the expressions have to result in a value, not <a href="expression.html#nothing">Nothing</a> (<code><span class='Nothing'>Β·</span></code>).</p> -<p>Entries in a list are evaluated in source order, and the value will be the list of those results. The list has a subject role, even if it contains expressions with other roles. Any value can be an element.</p> +<p>Entries in a list are evaluated in source order, and the value will be the list of those results. The list has a subject <a href="expression.html#syntactic-role">role</a>, even if it contains expressions with other roles. Any value can be an element.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oQCwg4o2Jy5gsIOKJjSJhYmMi4p+p">βοΈ</a><pre> <span class='Bracket'>β¨</span><span class='String'>@</span><span class='Separator'>,</span> <span class='Function'>β</span><span class='Modifier'>Λ</span><span class='Separator'>,</span> <span class='Function'>β</span><span class='String'>"abc"</span><span class='Bracket'>β©</span> ββ Β· @ βΛ ββ @@ -180,7 +180,7 @@ β β </pre> -<p>BQN's separator rules give list notation a very flexible structure. You can put all the elements on one line or spread them across lines, with the option of adding blank lines between elements. A separator at the end of a line is never needed but leading and trailing separators are allowed.</p> +<p>BQN's separator rules give list notation a very flexible structure. You can put all the elements on one line or spread them across lines, with the option of adding blank lines between elements. A separator at the end of a line is never needed, but leading and trailing separators are allowed.</p> <pre><span class='Bracket'>β¨</span> <span class='String'>"e0"</span><span class='Separator'>,</span> <span class='String'>"e1"</span> <span class='Bracket'>β¨</span> @@ -201,9 +201,9 @@ 0 5 β </pre> -<p>This syntax doesn't work for creating rank 0 arraysβuse <a href="enclose.html">Enclose</a> <code><span class='Function'><</span></code> for theseβor empty arrays. The notation <code><span class='Bracket'>[]</span></code> would be ambiguous, so it's not allowed (although it can be used for destructuring, which works with an existing array). To create a specific empty array, <a href="reshape.html">Reshape</a> (<code><span class='Function'>β₯</span></code>) is probably the best approach.</p> +<p>This syntax doesn't work for creating rank 0 arraysβuse <a href="enclose.html">Enclose</a> <code><span class='Function'><</span></code> for theseβor empty arrays. The notation <code><span class='Bracket'>[]</span></code> would be ambiguous, so it's not allowed (although it can be used for destructuring, which works with an existing array). To create an empty array with a specific shape, <a href="reshape.html">Reshape</a> (<code><span class='Function'>β₯</span></code>) is probably the best approach.</p> <h3 id="strands"><a class="header" href="#strands">Strands</a></h3> -<p><strong>Strand notation</strong> is another way to write lists of length two or more. The elements are connected with the ligature character <code><span class='Ligature'>βΏ</span></code>. It has a precedence lower than the <a href="namespace.html">namespace</a> dot but higher than anything else other than paired brackets <code><span class='Paren'>()</span></code>, <code><span class='Brace'>{}</span></code>, and <code><span class='Bracket'>β¨β©</span></code>, so compound elements generally need to be placed in parentheses. Expressions joined by ligatures behave exactly the same as those in list notation: they are evaluated in order and placed in a list.</p> +<p><strong>Strand notation</strong> is another way to write lists of length two or more. The elements are connected with the ligature character <code><span class='Ligature'>βΏ</span></code>. It has a precedence higher than anything else other than the <a href="namespace.html">namespace</a> dot <code><span class='Value'>.</span></code> and of course paired brackets <code><span class='Paren'>()</span></code>, <code><span class='Brace'>{}</span></code>, and <code><span class='Bracket'>β¨β©</span></code>. This means complicated elements generally need to be placed in parentheses. Expressions joined by ligatures behave exactly the same as those in list notation: they are evaluated in order and placed in a list.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=K+KAv8K04oC/4oiY4oC/w5cKCivigL/CtOKAv+KImOKAv8OXICDiiaEgIOKfqCsswrQs4oiYLMOX4p+p">βοΈ</a><pre> <span class='Function'>+</span><span class='Ligature'>βΏ</span><span class='Modifier'>Β΄</span><span class='Ligature'>βΏ</span><span class='Modifier2'>β</span><span class='Ligature'>βΏ</span><span class='Function'>Γ</span> β¨ + Β΄ β Γ β© diff --git a/docs/doc/assert.html b/docs/doc/assert.html index ceccf72a..d800155f 100644 --- a/docs/doc/assert.html +++ b/docs/doc/assert.html @@ -8,28 +8,35 @@ <p>BQN provides some simple facilities for dealing with errors. Errors are an unusual sort of control flow; if possible, prefer to work with functions that return normally.</p> <h2 id="assert"><a class="header" href="#assert">Assert</a></h2> <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 +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ISAyPTIgICMgUGFzc2VkCgohIDI9MyAgIyBGYWlsZWQ=">βοΈ</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><span class='Error'>Error: Assertion error</span> </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> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ISAo4oinPeKIqOKMvsKsKeKMnMucIOKGlTIKCiEg4oinwrTipYogKOKIpz3iiKjijL7CrCnijJzLnCDihpUy">βοΈ</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> <span class='Error'>Error: 2βΏ2β₯1βΏ1βΏ1βΏ1</span> + <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=Ik1lc3NhZ2UiICEgMArin6jiiJgsImFiYyIsy5zin6kgISAnMCc=">βοΈ</a><pre> <span class='String'>"Message"</span> <span class='Function'>!</span> <span class='Number'>0</span> +<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 <code><span class='Value'>π¨</span></code> in order to display it to the programmer, but <code><span class='Value'>π¨</span></code> can be any value.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Ik1lc3NhZ2UiICEgMAoK4p+o4oiYLCJhYmMiLMuc4p+pICEgJzAn">βοΈ</a><pre> <span class='String'>"Message"</span> <span class='Function'>!</span> <span class='Number'>0</span> <span class='Error'>Error: Message</span> + <span class='Bracket'>β¨</span><span class='Modifier2'>β</span><span class='Separator'>,</span><span class='String'>"abc"</span><span class='Separator'>,</span><span class='Modifier'>Λ</span><span class='Bracket'>β©</span> <span class='Function'>!</span> <span class='String'>'0'</span> <span class='Error'>Error: β¨β,"abc",Λβ©</span> </pre> +<p>In the 1-argument case, <code><span class='Value'>π©</span></code> is used for the error message if it's not <code><span class='Number'>1</span></code>. So an unconditional error can also be written this way:</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ISAiTWVzc2FnZSI=">βοΈ</a><pre> <span class='Function'>!</span> <span class='String'>"Message"</span> +<span class='Error'>Error: Message</span> +</pre> <h3 id="computing-the-error-message-on-demand"><a class="header" href="#computing-the-error-message-on-demand">Computing the error message on demand</a></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>Handle bad inputs with ordinary if-then logic (perhaps using <a href="control.html">control structures</a>), not errors. This is probably the best path for user-facing applications where BQN's normal error display isn't wanted.</li> +<li>Write a function <code><span class='Function'>Message</span></code> to compute the message, and call <code><span class='Function'>!</span><span class='Modifier2'>β</span><span class='Function'>Message</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> <h2 id="catch"><a class="header" href="#catch">Catch</a></h2> diff --git a/docs/doc/based.html b/docs/doc/based.html index f03adf29..4aa345f9 100644 --- a/docs/doc/based.html +++ b/docs/doc/based.html @@ -11,7 +11,7 @@ <p>If you're an array programmer then I have bad news for you. My thesis here is that APL took a wrong turn around 1981 when it extrapolated the excellent, but limited, flat array model of APL\360 to the ill-founded nested array model and the rigorous but clumsy boxed array model. Make that two wrong turns, I guess. Simultaneously. Anyway, if you've been brought up in either of these array models, then the best thing to do when starting BQN is to throw out your existing ideas about array depth and nesting (but don't worry too much: the fundamental concept of an array as a rectangular collection of data still holds!). If you'd like to ponder the relationship of BQN to APL later, that's great, but trying to initially understand BQN in terms of APL or J will just cause confusion.</p> <h2 id="starting-from-atoms"><a class="header" href="#starting-from-atoms">Starting from atoms</a></h2> <p>APL tends to define its data by starting with the array and then looking downwards in depth at what it contains. The based array model, as the name suggests, starts at the foundations, which in BQN are called "atoms". There are six <a href="types.html">types</a> of atom, which together with the array type give the seven types a value can have in BQN. Based means being yourself, and an atom's <em>not</em> an array.</p> -<p>An atom has <a href="depth.html">depth</a> 0, and doesn't inherently have a shape. However, primitives that expect an array promote atoms by <a href="enclose.html">enclosing</a> them to get a rank-0, or <em>unit</em>, array that contains the atom (any value can be enclosed in this way, giving a unit array with higher depth, but it only happens automatically for atoms). <a href="shape.html">Rank and shape</a> both do this, so an atom can be considered to have the same dimensions as a unit array: rank 0 and shape <code><span class='Bracket'>β¨β©</span></code>. An atom is also considered a kind of unit, but it's not a unit array.</p> +<p>An atom has <a href="depth.html">depth</a> 0, and doesn't inherently have a shape. However, primitives that expect an array will promote an atom by <a href="enclose.html">enclosing</a> to get a rank-0, or <em>unit</em>, array that contains it (any value can be enclosed in this way, giving a unit array with higher depth, but it only happens automatically for atoms). <a href="shape.html">Rank and shape</a> both do this, so an atom can be considered to have the same dimensions as a unit array: rank 0 and shape <code><span class='Bracket'>β¨β©</span></code>. An atom is also considered a kind of unit, but it's not a unit array.</p> <p>Atoms are displayed as plain values, while enclosed atoms, that is, depth-1 unit arrays, are shown with an array display.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyAgICAjIEF0b20KPDMgICAjIEFycmF5CiczJyAgIyBBdG9t">βοΈ</a><pre> <span class='Number'>3</span> <span class='Comment'># Atom </span>3 diff --git a/docs/doc/birds.html b/docs/doc/birds.html index 09f70f84..18a1389a 100644 --- a/docs/doc/birds.html +++ b/docs/doc/birds.html @@ -5,7 +5,7 @@ </head> <div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div> <h1 id="bqn-for-birdwatchers"><a class="header" href="#bqn-for-birdwatchers">BQN for birdwatchers</a></h1> -<p>Some people consider it reasonable to name <a href="primitive.html#modifiers">combinators</a> after types of birds. <a href="https://blog.lahteenmaki.net/combinator-birds.html">Here's</a> one compendium of such names, and <a href="https://wiki.xxiivv.com/site/ornithodex.html">another</a> that lacks its obsessive completeness but makes up for it with rambling accounts of imagined forests. There is something wrong with these people. Some of these birds are not even real. "Quixotic bird"? Have you not heard of a quail? Nonetheless, I don't judge such afflicted souls (certainly not publicly), and have provided this translation table to explain BQN in terms they can understand.</p> +<p>Some people consider it reasonable to name <a href="primitive.html#modifiers">combinators</a> after types of birds. <a href="https://blog.lahteenmaki.net/combinator-birds.html">Here's</a> one compendium of such names, and <a href="https://wiki.xxiivv.com/site/ornithodex.html">another</a> that lacks its obsessive completeness but makes up for it with <a href="https://wiki.xxiivv.com/site/logic.html">rambling accounts</a> of imagined forests. There is something wrong with these people. Some of these birds are not even real. "Quixotic bird"? Have you not heard of a quail? Nonetheless, I don't judge such afflicted souls (certainly not publicly), and have provided this translation table to explain BQN in terms they can understand.</p> <table> <thead> <tr> diff --git a/docs/doc/block.html b/docs/doc/block.html index 31f59aed..a79791df 100644 --- a/docs/doc/block.html +++ b/docs/doc/block.html @@ -5,14 +5,15 @@ </head> <div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div> <h1 id="blocks"><a class="header" href="#blocks">Blocks</a></h1> -<p>In BQN, a <em>block</em> is any piece of code surrounded with curly braces <code><span class='Brace'>{}</span></code>. Blocks can be used simply to group statements, or can define functions or modifiers. They are the sole large-scale structure used to organize programs. An important aspect of organization is <a href="namespace.html">namespaces</a>, which are created with blocks but not discussed on this page.</p> +<p>In BQN, a <em>block</em> is any piece of code surrounded with curly braces <code><span class='Brace'>{}</span></code>. Blocks can be used simply to group statements, or can define functions or modifiers. They are the sole large-scale structure used to organize programs. One organizing tool not discussed here is <a href="namespace.html">namespaces</a>, which are created with blocks but have their own page. Programming without blocks (only recommended at the small scale) is called <a href="tacit.html">tacit</a> programming.</p> <p>Blocks are most commonly used to define functions by including one of the special names for arguments, <code><span class='Value'>π¨</span></code> or <code><span class='Value'>π©</span></code>. With the operands <code><span class='Function'>π½</span></code> or <code><span class='Function'>πΎ</span></code>, they can also define 1-modifiers or 2-modifiers.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=e/CdlakrMX0gMwrDl3vwnZWp8J2UvfCdlal9IDQ=">βοΈ</a><pre> <span class='Brace'>{</span><span class='Value'>π©</span><span class='Function'>+</span><span class='Number'>1</span><span class='Brace'>}</span> <span class='Number'>3</span> 4 <span class='Function'>Γ</span><span class='Brace'>{</span><span class='Value'>π©</span><span class='Function'>π½</span><span class='Value'>π©</span><span class='Brace'>}</span> <span class='Number'>4</span> 16 </pre> -<p>Because they use <a href="lexical.html">lexical scoping</a>, blocks can also be used to encapsulate code. If a block uses only variables that it initializes, then it has no dependence on its environment and would work the same way if defined anywhere. But it can also use external variables, defined in a containing block.</p> +<p>A block <a href="#block-headers">header</a> is written before a <code><span class='Head'>:</span></code> and describes the block type, and what inputs it accepts. A block can be split into <a href="#multiple-bodies">multiple bodies</a> using <code><span class='Head'>;</span></code>s, so that each handles different cases. A <a href="#predicates">predicate</a>, written with <code><span class='Head'>?</span></code>, can test an arbitrary condition to refine these cases.</p> +<p>Because they use <a href="lexical.html">lexical scoping</a>, blocks also encapsulate code. If a block uses only variables that it initializes, then it has no dependence on its environment and would work the same way if defined anywhere. But it can also use external variables, defined in a containing block.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=YeKGkGLihpAib3V0ZXIiCnsgYeKGkCJpbm5lciIg4ouEIGHigL9iIH0=">βοΈ</a><pre> <span class='Value'>a</span><span class='Gets'>β</span><span class='Value'>b</span><span class='Gets'>β</span><span class='String'>"outer"</span> <span class='Brace'>{</span> <span class='Value'>a</span><span class='Gets'>β</span><span class='String'>"inner"</span> <span class='Separator'>β</span> <span class='Value'>a</span><span class='Ligature'>βΏ</span><span class='Value'>b</span> <span class='Brace'>}</span> β¨ "inner" "outer" β© @@ -23,7 +24,7 @@ <span class='Value'>updown</span> β¨ 0 1 2 3 4 4 3 2 1 0 β© </pre> -<p>An immediate block is only ever evaluated once, and can't be used for control flow in a program. Including special names in a headerless block lets us define functions and modifiers, which have a broader range of uses. All special names are listed below:</p> +<p>An immediate block is only ever evaluated once, and can't be used for control flow in a program. Special names can be used to define <a href="ops.html">functions and modifiers</a>, which have a broader range of uses. All special names are listed below:</p> <table> <thead> <tr> @@ -65,14 +66,16 @@ </tr> </tbody> </table> -<p>Of these, <code><span class='Value'>π£</span></code> is sort of a "more special" character, as we'll discuss below. Except for <code><span class='Value'>π£</span></code>, every special name is a single character and can't have underscores added to spell it as a modifier. This allows a modifier to be applied to a special name with no spacing, as in <code><span class='Value'>π</span><span class='Modifier'>_m</span></code>, where it couldn't be with ordinary names.</p> +<p>Most special names have a lowercase form for a subject <a href="expression.html#syntactic-role">role</a> and uppercase for a function role. But <code><span class='Value'>π£</span></code> is sort of a "more special" character, as we'll discuss below. The special names other than <code><span class='Value'>π£</span></code> are single characters that don't attach to other letters, allowing <code><span class='Function'>π½</span><span class='Value'>π©</span></code> or <code><span class='Value'>π</span><span class='Modifier'>_m</span></code> to work without spaces; <code><span class='Value'>π£</span></code> is always modifier-valued, so it ought to attach to underscores.</p> <h3 id="arguments"><a class="header" href="#arguments">Arguments</a></h3> <p>The names <code><span class='Value'>π¨</span></code> and <code><span class='Value'>π©</span></code>, and their uppercase spellings, represent function arguments. As the argument to a function is typically data, it's more common to use the lowercase forms for these. Having either of these names turns an immediate block into a function (or an immediate modifier into a deferred one; see the next section). Instead of being evaluated as soon as it appears in the source, a function is evaluated when it's called, with the special names set to appropriate values. Their values can be changed like ordinary variables.</p> -<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eydjJz3wnZWpfSAiYWJjZCIKeyDwnZWpK+KGqTIg4ouEIDDiiY3wnZWpIH0gMwo0IHsg4p+o8J2VqeKLhC3wnZWo4p+pIH0gNQ==">βοΈ</a><pre> <span class='Brace'>{</span><span class='String'>'c'</span><span class='Function'>=</span><span class='Value'>π©</span><span class='Brace'>}</span> <span class='String'>"abcd"</span> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eydjJz3wnZWpfSAiYWJjZCIKCnsg8J2VqSvihqkyIOKLhCAw4omN8J2VqSB9IDMKCjQgeyDin6jwnZWpLC3wnZWo4p+pIH0gNQ==">βοΈ</a><pre> <span class='Brace'>{</span><span class='String'>'c'</span><span class='Function'>=</span><span class='Value'>π©</span><span class='Brace'>}</span> <span class='String'>"abcd"</span> β¨ 0 0 1 0 β© + <span class='Brace'>{</span> <span class='Value'>π©</span><span class='Function'>+</span><span class='Gets'>β©</span><span class='Number'>2</span> <span class='Separator'>β</span> <span class='Number'>0</span><span class='Function'>β</span><span class='Value'>π©</span> <span class='Brace'>}</span> <span class='Number'>3</span> β¨ 0 5 β© - <span class='Number'>4</span> <span class='Brace'>{</span> <span class='Bracket'>β¨</span><span class='Value'>π©</span><span class='Separator'>β</span><span class='Function'>-</span><span class='Value'>π¨</span><span class='Bracket'>β©</span> <span class='Brace'>}</span> <span class='Number'>5</span> + + <span class='Number'>4</span> <span class='Brace'>{</span> <span class='Bracket'>β¨</span><span class='Value'>π©</span><span class='Separator'>,</span><span class='Function'>-</span><span class='Value'>π¨</span><span class='Bracket'>β©</span> <span class='Brace'>}</span> <span class='Number'>5</span> β¨ 5 Β―4 β© </pre> <p>A function with <code><span class='Value'>π¨</span></code> in its definition doesn't have to be called with two arguments. If it has only one, then <code><span class='Value'>π¨</span></code> is given the special value <a href="expression.html#nothing">Nothing</a>, or <code><span class='Nothing'>Β·</span></code>. This is the only time a variable can ever be Nothing, as an assignment such as <code><span class='Value'>v</span><span class='Gets'>β</span><span class='Nothing'>Β·</span></code> is not allowed.</p> @@ -81,7 +84,7 @@ <span class='Brace'>{</span> <span class='Paren'>(</span><span class='Number'>2</span><span class='Function'>Γ</span><span class='Value'>π¨</span><span class='Paren'>)</span><span class='Function'>-</span><span class='Value'>π©</span> <span class='Brace'>}</span> <span class='Number'>1</span> Β―1 </pre> -<p>In the second function, <code><span class='Value'>π¨</span></code> behaves just like <code><span class='Nothing'>Β·</span></code>, so that the function <code><span class='Number'>2</span><span class='Function'>Γ</span><span class='Value'>π¨</span></code> is not evaluated and <code><span class='Function'>-</span></code> doesn't have a left argument. It has a similar effect when used as the left argument to a function in a train.</p> +<p>In the second function, <code><span class='Value'>π¨</span></code> behaves just like <code><span class='Nothing'>Β·</span></code>, so that the function <code><span class='Number'>2</span><span class='Function'>Γ</span><span class='Value'>π¨</span></code> is not evaluated and <code><span class='Function'>-</span></code> doesn't have a left argument. It has a similar effect when used as the left argument to a function in a <a href="train.html">train</a>.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ImFiYyIgeyAo8J2VqOKJjeKMvSkg8J2VqSB9ICJkZWYiCiAgICAgIHsgKPCdlajiiY3ijL0pIPCdlakgfSAiZGVmIg==">βοΈ</a><pre> <span class='String'>"abc"</span> <span class='Brace'>{</span> <span class='Paren'>(</span><span class='Value'>π¨</span><span class='Function'>ββ½</span><span class='Paren'>)</span> <span class='Value'>π©</span> <span class='Brace'>}</span> <span class='String'>"def"</span> ββ β΅"abc @@ -92,7 +95,7 @@ β΅"fed" β </pre> -<p>However, <code><span class='Nothing'>Β·</span></code> can only be used as an argument, and not a list element or operand. Don't use <code><span class='Value'>π¨</span></code> in these ways in a function that could be called monadically. Another potential issue is that <code><span class='Modifier2'>βΈ</span></code> and <code><span class='Modifier2'>β</span></code> don't work the way you might expect.</p> +<p>However, <code><span class='Nothing'>Β·</span></code> can only be used as an argument, and not a list element or operand. Don't use <code><span class='Value'>π¨</span></code> in these ways in a function that could be called monadically. Another <a href="../problems.html#nothing--interacts-strangely-with-before-and-after">potential issue</a> is that <code><span class='Modifier2'>βΈ</span></code> and <code><span class='Modifier2'>β</span></code> don't work the way you might expect.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eyDwnZWoIOKLhuKKuC0g8J2VqSB9IDU=">βοΈ</a><pre> <span class='Brace'>{</span> <span class='Value'>π¨</span> <span class='Function'>β</span><span class='Modifier2'>βΈ</span><span class='Function'>-</span> <span class='Value'>π©</span> <span class='Brace'>}</span> <span class='Number'>5</span> 143.4131591025766 </pre> @@ -117,23 +120,23 @@ </pre> <p>The distinction between an immediate and deferred modifier only matters inside the braces. Once defined, the object is simply a modifier that can be called on operands to return a result. For a deferred modifier this result will always be a function; for an immediate modifier it could be anything.</p> <h3 id="self-reference"><a class="header" href="#self-reference">Self-reference</a></h3> -<p>If a block is assigned a name after it is created, this name can be used for recursion:</p> +<p>If a block is assigned a name after it's created, this name can be used for recursion:</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=RmFjdCDihpAgeyDwnZWpIMOXICgw4oq4PCnil7Yx4oC/RmFjdCDwnZWpLTEgfQpGYWN0IDcKKMOXwrQxK+KGlSkgNyAgIyBUaGVyZSdzIG9mdGVuIGEgc2ltcGxlciBzb2x1dGlvbiB0aGFuIHJlY3Vyc2lvbg==">βοΈ</a><pre> <span class='Function'>Fact</span> <span class='Gets'>β</span> <span class='Brace'>{</span> <span class='Value'>π©</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'>Fact</span> <span class='Value'>π©</span><span class='Function'>-</span><span class='Number'>1</span> <span class='Brace'>}</span> <span class='Function'>Fact</span> <span class='Number'>7</span> 5040 <span class='Paren'>(</span><span class='Function'>Γ</span><span class='Modifier'>Β΄</span><span class='Number'>1</span><span class='Function'>+β</span><span class='Paren'>)</span> <span class='Number'>7</span> <span class='Comment'># There's often a simpler solution than recursion </span>5040 </pre> -<p>This is somewhat unsatisfying because it is external to the function being defined, even though it doesn't depend on outside information. Instead, the special name <code><span class='Function'>π</span></code> can be used to refer to the function it appears in. This allows anonymous recursive functions to be defined.</p> +<p>This is somewhat unsatisfying because the name is external to the function being defined, but the definition shouldn't depend on outside information. Instead, the special name <code><span class='Function'>π</span></code> can be used to refer to the function it appears in. This allows anonymous recursive functions to be defined.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eyDwnZWpIMOXICgw4oq4PCnil7Yx4oC/8J2ViiDwnZWpLTEgfSA3">βοΈ</a><pre> <span class='Brace'>{</span> <span class='Value'>π©</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'>π</span> <span class='Value'>π©</span><span class='Function'>-</span><span class='Number'>1</span> <span class='Brace'>}</span> <span class='Number'>7</span> 5040 </pre> -<p>For modifiers, <code><span class='Value'>π£</span></code> refers to the containing modifier. <code><span class='Function'>π</span></code> makes the modifier a deferred modifier like <code><span class='Value'>π¨</span></code> and <code><span class='Value'>π©</span></code> do, and refers to the derived function. For example, this tail-recursive factorial function uses the operand to accumulate a result, a task that is usually done with a second <code><span class='Value'>factorial_helper</span></code> function in elementary Scheme.</p> +<p>For modifiers, <code><span class='Value'>π£</span></code> refers to the containing modifier. <code><span class='Function'>π</span></code> makes the modifier a deferred modifier like <code><span class='Value'>π¨</span></code> and <code><span class='Value'>π©</span></code> do, and refers to the derived function. For example, this tail-recursive factorial function uses the operand to accumulate a result, a task that's usually done with a second <code><span class='Value'>factorial_helper</span></code> function in elementary Scheme (BQN doesn't optimize tail recursion though; it's just shown here as an example).</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=RmFjdF9tb2Qg4oaQIDEgeyAoMOKKuDwp4pe24p+o8J2VlywgKPCdlZfDl/CdlakpX/CdlaPin6kg8J2VqS0xIH0KRmFjdF9tb2QgNw==">βοΈ</a><pre> <span class='Function'>Fact_mod</span> <span class='Gets'>β</span> <span class='Number'>1</span> <span class='Brace'>{</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='Bracket'>β¨</span><span class='Value'>π</span><span class='Separator'>,</span> <span class='Paren'>(</span><span class='Value'>π</span><span class='Function'>Γ</span><span class='Value'>π©</span><span class='Paren'>)</span><span class='Modifier'>_π£</span><span class='Bracket'>β©</span> <span class='Value'>π©</span><span class='Function'>-</span><span class='Number'>1</span> <span class='Brace'>}</span> <span class='Function'>Fact_mod</span> <span class='Number'>7</span> 5040 </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> +<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. 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's tokenized as an ordinary identifier character, so it has to be separated from adjacent letters or numbers with a space.</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='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> @@ -157,20 +160,21 @@ </span><span class='Brace'>{</span> <span class='Function'>F</span> <span class='Modifier2'>_op_</span> <span class='Nothing'>Β·</span><span class='Ligature'>βΏ</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> +<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> <pre><span class='Brace'>{</span> <span class='Comment'># Fn _apply β¨a,bβ©: </span> <span class='Function'>Fn</span> <span class='Gets'>β</span> <span class='Function'>π½</span> <span class='Modifier'>_apply</span> <span class='Gets'>β</span> <span class='Modifier'>_π£</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='Gets'>β</span> <span class='Value'>π©</span> <span class='Value'>β¦</span> </pre> -<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> +<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, so 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 and operands allow <a href="expression.html#destructuring">destructuring</a> 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> +<p>Arguments and operands allow <a href="expression.html#destructuring">destructuring</a> like assignment does. While assignment only tolerates lists of variables, header destructuring also allows constants. For the header to match, the argument must share the given structure, including the constants where they appear.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=RGVzdHJ1Y3Qg4oaQIHsg8J2ViiBh4oC/MeKAv+KfqGIswrcsMuKfqTogYeKJjWIgfQpEZXN0cnVjdCAgICAgICA14oC/MeKAv+KfqDcsz4AsMuKfqQ==">βοΈ</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='Nothing'>Β·</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'>Ο</span><span class='Separator'>,</span><span class='Number'>2</span><span class='Bracket'>β©</span> β¨ 5 7 β© </pre> +<p>It's also worth noting here that <code><span class='Bracket'>[]</span></code> is a valid destructuring target, matching any length-0 array, even though it can't be used as a value since it's ambiguous. This syntax is also allowed in regular destructuring, but it's not very useful in that case.</p> <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><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> @@ -181,21 +185,26 @@ </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 in code: it doesn't make sense to refer to a value while it is still being computed!</p> +<p>For immediate blocks, this is the only type of header possible, and it must use an identifier as there's no applicable special name. However, the name can't be used in code: it doesn't make sense to refer to a value while it's still being computed!</p> <h2 id="multiple-bodies"><a class="header" href="#multiple-bodies">Multiple bodies</a></h2> -<p>Blocks 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 is that functions and deferred modifiers can have two headerless bodies (that is, no headers or predicatesβsee below): the first applies when there's 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> +<p>Blocks 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 inputs to the block. One special case is that functions and deferred modifiers can have two headerless bodies (that is, no headers or <a href="#predicates">predicates</a>): the first applies when there's 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+oMizwnZWoLPCdlanin6kgfQoKQW1iaXYgJ2EnCgonYScgQW1iaXYgJ2In">βοΈ</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 with headers come before any that don't have them. When a block is called, its headers are checked in order for compatibility with the arguments, and 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='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> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Q2FzZUFkZCDihpAgeyAy8J2VijM6MOKAvzUgOyAy8J2VivCdlak64p+oMSwyK/Cdlanin6kgOyDwnZWK8J2VqToy4oC/8J2VqSB9CgoyIENhc2VBZGQgMwoKMiBDYXNlQWRkIDQKCiAgQ2FzZUFkZCA0">βοΈ</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> β¨ 1 6 β© + <span class='Function'>CaseAdd</span> <span class='Number'>4</span> β¨ 2 4 β© </pre> @@ -214,21 +223,24 @@ </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='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> +<p>Destructuring with a header is limited, as it can only match a particular structure or value exactlyβnot, for example, a range of lengths. 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 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=Q2hlY2tQYWlyIOKGkCB7IPCdlYrin6hhLGLin6k6IGE8Yj8gIm9rIiA7ICJub3Qgb2siIH0KCkNoZWNrUGFpciDin6gzLDjin6kgICAgIyBGYWlscyBkZXN0cnVjdHVyaW5nCgpDaGVja1BhaXIg4p+oMSw0LDXin6kgICMgTm90IGEgcGFpcgoKQ2hlY2tQYWlyIOKfqDMswq8x4p+pICAgIyBOb3QgYXNjZW5kaW5n">βοΈ</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" + <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='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> +<p>The body where the predicate appears doesn't need to start with a header, and there can be other statements before it. Really, <code><span class='Head'>?</span></code> works 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='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> +<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>.</p> +<p>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 @@ -237,7 +249,7 @@ @ β β 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='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> +<p>This structure is still controlled 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> diff --git a/docs/doc/choose.html b/docs/doc/choose.html index 2bcaa223..d76da055 100644 --- a/docs/doc/choose.html +++ b/docs/doc/choose.html @@ -5,16 +5,16 @@ </head> <div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div> <h1 id="choose"><a class="header" href="#choose">Choose</a></h1> -<p>The 2-modifier Choose (<code><span class='Modifier2'>βΆ</span></code>) applies one function from a list <code><span class='Value'>π</span></code>, based on a selection function <code><span class='Function'>π½</span></code> that returns an index. It's a combinator form of <a href="pick.html">Pick</a> (<code><span class='Function'>β</span></code>), so that <code><span class='Brace'>{</span><span class='Value'>f</span><span class='Gets'>β</span><span class='Paren'>(</span><span class='Value'>π¨</span><span class='Function'>π½</span><span class='Value'>π©</span><span class='Paren'>)</span><span class='Function'>β</span><span class='Value'>π</span> <span class='Separator'>β</span> <span class='Value'>π¨</span><span class='Function'>F</span><span class='Value'>π©</span><span class='Brace'>}</span></code> is a complete definition. For example, the function below subtracts 1 from an argument if negative and adds 1 if positive.</p> +<p>The 2-modifier Choose (<code><span class='Modifier2'>βΆ</span></code>) applies one function from a list <code><span class='Value'>π</span></code>, based on the selecting index returned by a function <code><span class='Function'>π½</span></code>. It's a combinator form of <a href="pick.html">Pick</a> (<code><span class='Function'>β</span></code>), so that <code><span class='Brace'>{</span><span class='Value'>f</span><span class='Gets'>β</span><span class='Paren'>(</span><span class='Value'>π¨</span><span class='Function'>π½</span><span class='Value'>π©</span><span class='Paren'>)</span><span class='Function'>β</span><span class='Value'>π</span> <span class='Separator'>β</span> <span class='Value'>π¨</span><span class='Function'>F</span><span class='Value'>π©</span><span class='Brace'>}</span></code> is a complete definition. For example, the function below subtracts 1 from its argument if negative and adds 1 if positive.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MOKKuOKJpOKXtuKfqC3in5wxLCAr4p+cMeKfqcKoIDPigL/CrzHigL81">βοΈ</a><pre> <span class='Number'>0</span><span class='Modifier2'>βΈ</span><span class='Function'>β€</span><span class='Modifier2'>βΆ</span><span class='Bracket'>β¨</span><span class='Function'>-</span><span class='Modifier2'>β</span><span class='Number'>1</span><span class='Separator'>,</span> <span class='Function'>+</span><span class='Modifier2'>β</span><span class='Number'>1</span><span class='Bracket'>β©</span><span class='Modifier'>Β¨</span> <span class='Number'>3</span><span class='Ligature'>βΏ</span><span class='Number'>Β―1</span><span class='Ligature'>βΏ</span><span class='Number'>5</span> β¨ 4 Β―2 6 β© </pre> -<p>Here the selection function <code><span class='Function'>π½</span></code> is <code><span class='Number'>0</span><span class='Modifier2'>βΈ</span><span class='Function'>β€</span></code>, while <code><span class='Value'>π</span></code> is a list of two functions <code><span class='Bracket'>β¨</span><span class='Function'>-</span><span class='Modifier2'>β</span><span class='Number'>1</span><span class='Separator'>,</span> <span class='Function'>+</span><span class='Modifier2'>β</span><span class='Number'>1</span><span class='Bracket'>β©</span></code>. On the first argument, <code><span class='Number'>3</span></code>, <code><span class='Function'>π½</span><span class='Number'>3</span></code> is <code><span class='Number'>0</span><span class='Function'>β€</span><span class='Number'>3</span></code>, or <code><span class='Number'>1</span></code>, so the function <code><span class='Function'>+</span><span class='Modifier2'>β</span><span class='Number'>1</span></code> from <code><span class='Value'>π</span></code> is chosen. The use of array indices means "false" comes first in <code><span class='Value'>π</span></code> and "true" comes second, which is backwards relative to if-else constructs in most programming languages (including BQN's own predicates). When using a comparison for <code><span class='Function'>π½</span></code> I strongly prefer to phrase it as <code><span class='Value'>n</span><span class='Modifier2'>βΈ</span><span class='Function'><</span></code> or <code><span class='Value'>n</span><span class='Modifier2'>βΈ</span><span class='Function'>β€</span></code> so that smaller values go through the first one and larger functions go through the second. This doesn't apply so much when comparing two arguments since one is smaller but the other's larger, so I don't have an easy technique for that.</p> +<p>Here the selection function <code><span class='Function'>π½</span></code> is <code><span class='Number'>0</span><span class='Modifier2'>βΈ</span><span class='Function'>β€</span></code>, while <code><span class='Value'>π</span></code> is a list of two functions <code><span class='Bracket'>β¨</span><span class='Function'>-</span><span class='Modifier2'>β</span><span class='Number'>1</span><span class='Separator'>,</span> <span class='Function'>+</span><span class='Modifier2'>β</span><span class='Number'>1</span><span class='Bracket'>β©</span></code>. On the first argument, <code><span class='Number'>3</span></code>, <code><span class='Function'>π½</span><span class='Number'>3</span></code> is <code><span class='Number'>0</span><span class='Function'>β€</span><span class='Number'>3</span></code>, or <code><span class='Number'>1</span></code>, so the function <code><span class='Function'>+</span><span class='Modifier2'>β</span><span class='Number'>1</span></code> from <code><span class='Value'>π</span></code> is chosen. The use of array indices means "false" comes first in <code><span class='Value'>π</span></code> and "true" comes second, which is backwards relative to if-else constructs in most programming languages (including BQN's own <a href="block.html#predicates">predicates</a>). When using a comparison for <code><span class='Function'>π½</span></code> I strongly prefer to phrase it as <code><span class='Value'>n</span><span class='Modifier2'>βΈ</span><span class='Function'><</span></code> or <code><span class='Value'>n</span><span class='Modifier2'>βΈ</span><span class='Function'>β€</span></code> so that smaller values go through the first one and larger functions go through the second. This doesn't apply so much when comparing two arguments since one is smaller but the other's larger, so I don't have an easy answer for that.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MiA+4pe24oqj4oC/4oqiIDYgICMgQSBtaW5pbXVtIGZ1bmN0aW9uICjijIop">βοΈ</a><pre> <span class='Number'>2</span> <span class='Function'>></span><span class='Modifier2'>βΆ</span><span class='Function'>β£</span><span class='Ligature'>βΏ</span><span class='Function'>β’</span> <span class='Number'>6</span> <span class='Comment'># A minimum function (β) </span>2 </pre> <p>The advantage of using an index is that Choose works with any number of options.</p> -<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Rm4g4oaQICjiipEicnRkIuKKkuKKjynil7bin6jijL0sIDHiirjihpEsIDHiirjihpMsIOKKouKfqSAgIyBSZXZlcnNlLCB0YWtlIDEsIGRyb3AgMQoKRm4gInIxMjMiCgpGbiAiZDEyMyIKCkZuICIxMjMiICAjIERlZmF1bHQ=">βοΈ</a><pre> <span class='Function'>Fn</span> <span class='Gets'>β</span> <span class='Paren'>(</span><span class='Function'>β</span><span class='String'>"rtd"</span><span class='Function'>ββ</span><span class='Paren'>)</span><span class='Modifier2'>βΆ</span><span class='Bracket'>β¨</span><span class='Function'>β½</span><span class='Separator'>,</span> <span class='Number'>1</span><span class='Modifier2'>βΈ</span><span class='Function'>β</span><span class='Separator'>,</span> <span class='Number'>1</span><span class='Modifier2'>βΈ</span><span class='Function'>β</span><span class='Separator'>,</span> <span class='Function'>β’</span><span class='Bracket'>β©</span> <span class='Comment'># Reverse, take 1, drop 1 +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Rm4g4oaQICjiipEicnRkIuKKkOKKjynil7bin6jijL0sIDHiirjihpEsIDHiirjihpMsIOKKouKfqSAgIyBSZXZlcnNlLCB0YWtlIDEsIGRyb3AgMQoKRm4gInIxMjMiCgpGbiAiZDEyMyIKCkZuICIxMjMiICAjIERlZmF1bHQ=">βοΈ</a><pre> <span class='Function'>Fn</span> <span class='Gets'>β</span> <span class='Paren'>(</span><span class='Function'>β</span><span class='String'>"rtd"</span><span class='Function'>ββ</span><span class='Paren'>)</span><span class='Modifier2'>βΆ</span><span class='Bracket'>β¨</span><span class='Function'>β½</span><span class='Separator'>,</span> <span class='Number'>1</span><span class='Modifier2'>βΈ</span><span class='Function'>β</span><span class='Separator'>,</span> <span class='Number'>1</span><span class='Modifier2'>βΈ</span><span class='Function'>β</span><span class='Separator'>,</span> <span class='Function'>β’</span><span class='Bracket'>β©</span> <span class='Comment'># Reverse, take 1, drop 1 </span> <span class='Function'>Fn</span> <span class='String'>"r123"</span> "321r" @@ -25,6 +25,6 @@ <span class='Function'>Fn</span> <span class='String'>"123"</span> <span class='Comment'># Default </span>"123" </pre> -<p>The selection function in <code><span class='Function'>Fn</span></code> uses <a href="search.html#index-of">Index of</a> (<code><span class='Function'>β</span></code>) to find the index of the first character in the list <code><span class='String'>"rtd"</span></code>. An extra value in <code><span class='Value'>π</span></code> serves as a default function if it's none of those, since the result of <code><span class='Function'>π½</span></code> is <code><span class='Number'>3</span></code> in that case. A similar function that's often useful is <a href="order.html#bins">Bins</a>, for grouping inputs into intervals rather than by exact matching.</p> +<p>The selection function in <code><span class='Function'>Fn</span></code> uses <a href="search.html#index-of">Index of</a> (<code><span class='Function'>β</span></code>) to find the index of the first character in the list <code><span class='String'>"rtd"</span></code>. An extra value in <code><span class='Value'>π</span></code> serves as a default function if it's none of those, since the result of <code><span class='Function'>π½</span></code> is <code><span class='Number'>3</span></code> in that case. A similar function that's often useful is <a href="order.html#bins">Bins</a>, for grouping inputs into intervals rather than by exact matching.</p> <p>Choose is necessary for <a href="tacit.html">tacit</a> programming, but tacit programming is not necessary to be an effective BQN programmer! Consider using block features like <a href="block.html#predicates">predicates</a> when Choose isn't working with your program's flow.</p> <p>Because Choose is based on <a href="pick.html">Pick</a>, it retains the features of negative, multidimensional, and multiple selection. Negative indexing might make sense if there's some special <code><span class='Number'>Β―1</span></code> value, and if the options naturally form an array, multidimensional indexing is pretty neat. Selecting multiple values from <code><span class='Value'>π</span></code>, which happens if the result of <code><span class='Function'>π½</span></code> is an array of arrays, is never useful because the array result from <code><span class='Function'>π½</span></code> acts as a constant function. It's much clearer to express it as <code><span class='Function'>π½β</span><span class='Value'>π</span><span class='Modifier'>Λ</span></code>.</p> diff --git a/docs/doc/compose.html b/docs/doc/compose.html index 7a8da224..eec1877e 100644 --- a/docs/doc/compose.html +++ b/docs/doc/compose.html @@ -69,7 +69,7 @@ </g> </svg> -<p>Atop and Over are 2-modifiers that extend the idea of "apply this, then that" in two different ways. They're modelled after the mathematical notation fβg to compose two functions, and both do the same thing when there's one argument: <code><span class='Function'>F</span><span class='Modifier2'>β</span><span class='Function'>G</span> <span class='Value'>x</span></code> or <code><span class='Function'>F</span><span class='Modifier2'>β</span><span class='Function'>G</span> <span class='Value'>x</span></code> is <code><span class='Function'>F</span> <span class='Function'>G</span> <span class='Value'>x</span></code>.</p> +<p>Atop and Over are 2-modifiers that extend the idea of "apply this, then that" in two different ways. They're modelled after the mathematical notation fβg to compose two functions, and both do the same thing when there's one argument: either <code><span class='Function'>F</span><span class='Modifier2'>β</span><span class='Function'>G</span> <span class='Value'>x</span></code> or <code><span class='Function'>F</span><span class='Modifier2'>β</span><span class='Function'>G</span> <span class='Value'>x</span></code> is <code><span class='Function'>F</span> <span class='Function'>G</span> <span class='Value'>x</span></code>.</p> <table> <thead> <tr> @@ -99,7 +99,7 @@ </table> <p>When there are two arguments, we might say Atop treats the right operand <code><span class='Function'>πΎ</span></code> as primary and Over treats <code><span class='Function'>π½</span></code> as primaryβthe primary operand becomes dyadic while the other is always monadic. Atop applies <code><span class='Function'>πΎ</span></code> directly, making it more like mathematical composition if we suppose that <code><span class='Function'>πΎ</span></code> is a function that can take a pair of arguments. Over instead makes two calls to apply <code><span class='Function'>πΎ</span></code> separately to both arguments, then passes the results to <code><span class='Function'>π½</span></code>.</p> <h2 id="atop"><a class="header" href="#atop">Atop</a></h2> -<p>Of the two modifiers on this page, Atop is more common but less impactful. The composition <code><span class='Function'>F</span><span class='Modifier2'>β</span><span class='Function'>G</span></code> is equivalent to the 2-<a href="train.html">train</a> <code><span class='Function'>F</span> <span class='Function'>G</span></code> (the trains page has hints on when you'd choose one or the other). Its definition <code><span class='Brace'>{</span><span class='Function'>F</span><span class='Value'>π¨</span><span class='Function'>G</span><span class='Value'>π©</span><span class='Brace'>}</span></code> means that <code><span class='Function'>G</span></code> is applied to one or two arguments and <code><span class='Function'>F</span></code> is applied monadically to the result. It could be considered a "default way" to compose two functions. Keeps <a href="tacit.html">tacit</a> programming syntax running smoothly, without making noise about it. Not like that busybody <code><span class='Modifier2'>βΈ</span></code>. Some examples:</p> +<p>Of the two modifiers on this page, Atop is more common but less impactful. The composition <code><span class='Function'>F</span><span class='Modifier2'>β</span><span class='Function'>G</span></code> is equivalent to the 2-<a href="train.html">train</a> <code><span class='Function'>F</span> <span class='Function'>G</span></code> (the trains page has hints on when you'd choose one or the other). Its definition <code><span class='Brace'>{</span><span class='Function'>F</span><span class='Value'>π¨</span><span class='Function'>G</span><span class='Value'>π©</span><span class='Brace'>}</span></code> means that <code><span class='Function'>G</span></code> is applied to one or two arguments and <code><span class='Function'>F</span></code> is applied monadically to the result. It's sort of a "default way" to compose two functions. Keeps <a href="tacit.html">tacit</a> programming syntax running smoothly, without making noise about it. Not like that busybody <code><span class='Modifier2'>βΈ</span></code>. Some examples:</p> <p><code><span class='Function'>β</span><span class='Modifier2'>β</span><span class='Function'>β </span></code> is useful with one argument: <code><span class='Function'>ββ </span><span class='Value'>l</span></code> is a list of indices for <code><span class='Value'>l</span></code>.</p> <p><code><span class='Function'>β</span><span class='Modifier2'>β</span><span class='Function'>Γ·</span></code> is useful with two arguments: <code><span class='Function'>β</span><span class='Value'>a</span><span class='Function'>Γ·</span><span class='Value'>b</span></code> is the integer part when dividing <code><span class='Value'>a</span></code> by <code><span class='Value'>b</span></code>, often paired with the <a href="arithmetic.html#additional-arithmetic">remainder</a> <code><span class='Value'>b</span><span class='Function'>|</span><span class='Value'>a</span></code>.</p> <p><code><span class='Function'>β</span><span class='Modifier2'>β</span><span class='Function'>β</span></code> is useful with one or two arguments. From right to left, we have <a href="selfcmp.html#classify">Classify</a>/<a href="search.html#index-of">Index-of</a> (<code><span class='Function'>β</span></code>) to convert values to indices, and <a href="group.html">Group Indices</a> to group the indices. Er, that sounds good but what it <em>actually</em> does is to group indices of Group's argument, which correspond to indices of the original <code><span class='Value'>π©</span></code>, according to their values as returned by <code><span class='Function'>β</span></code>. Without a left argument, this means indices of <code><span class='Value'>π©</span></code> are grouped corresponding to <code><span class='Function'>β·</span><span class='Value'>π©</span></code>, and if <code><span class='Value'>π¨</span></code> is provided the groups correspond to <code><span class='Value'>π¨</span></code> instead.</p> @@ -112,7 +112,7 @@ <h2 id="over"><a class="header" href="#over">Over</a></h2> <p>Once you get used to Over, it's painful to go without it. I'd use it all the time in C if I could.</p> <p>Usually Over is used just for the dyadic meaning. If you have a composition that only works with one argument it's typical to write it with Atop (<code><span class='Modifier2'>β</span></code>). And cases that work with one or two arguments do come up from time to time, but they're fairly rare, so the examples below are just for two arguments.</p> -<p>A classic is the function <code><span class='Function'>β‘</span><span class='Modifier2'>β</span><span class='Function'>β§</span></code>, which tests whether <code><span class='Value'>π¨</span></code> is a reordering of <code><span class='Value'>π©</span></code>. The idea is to sort both arrays with <code><span class='Function'>β§</span></code> to remove the ordering information</p> +<p>A classic is the function <code><span class='Function'>β‘</span><span class='Modifier2'>β</span><span class='Function'>β§</span></code>, which tests whether <code><span class='Value'>π¨</span></code> is a reordering of <code><span class='Value'>π©</span></code>. The idea is to sort both arrays with <code><span class='Function'>β§</span></code> to remove the ordering information, then see if they match.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IkJRTiIg4omh4peL4oinICJRTkIiCiJCUU4iIOKJoeKXi+KIpyAiQkJRIg==">βοΈ</a><pre> <span class='String'>"BQN"</span> <span class='Function'>β‘</span><span class='Modifier2'>β</span><span class='Function'>β§</span> <span class='String'>"QNB"</span> 1 <span class='String'>"BQN"</span> <span class='Function'>β‘</span><span class='Modifier2'>β</span><span class='Function'>β§</span> <span class='String'>"BBQ"</span> |
