diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/spec/index.html | 2 | ||||
| -rw-r--r-- | docs/spec/inferred.html | 51 |
2 files changed, 52 insertions, 1 deletions
diff --git a/docs/spec/index.html b/docs/spec/index.html index e75da3da..391d34b4 100644 --- a/docs/spec/index.html +++ b/docs/spec/index.html @@ -6,7 +6,7 @@ <div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a> / <a href="../index.html">main</a></div> <h1 id="bqn-specification">BQN specification</h1> <p>This directory gives a specification for BQN. The specification differs from the <a href="../doc/index.html">documentation</a> in that its purpose is only to describe the exact details of BQN's operation in the most quickly accessible way, rather than to explain the core ideas of BQN functionality and how it might be used.</p> -<p>All normative sections of the core BQN specification (that is, excluding system-provided values) are complete except for the behavior of fill elements. The non-normative commentary on primitive definitions is also not yet complete.</p> +<p>All normative sections of the core BQN specification (that is, excluding system-provided values) are now complete, but the non-normative commentary on primitive definitions is still missing a few sections.</p> <p>The BQN specification consists of the following documents:</p> <ul> <li><a href="types.html">Types</a></li> diff --git a/docs/spec/inferred.html b/docs/spec/inferred.html index 4e0ff4ae..34d4725d 100644 --- a/docs/spec/inferred.html +++ b/docs/spec/inferred.html @@ -68,6 +68,57 @@ </tbody> </table> <p>Additionally, the identity of <code><span class='Function'>βΎ</span><span class='Modifier'>Λ</span></code> must be recognized: if <code><span class='Number'>0</span><span class='Function'>=β </span><span class='Value'>π©</span></code> and <code><span class='Number'>1</span><span class='Function'><=</span><span class='Value'>π©</span></code>, then <code><span class='Function'>βΎ</span><span class='Modifier'>Λ</span><span class='Value'>π©</span></code> is <code><span class='Paren'>(</span><span class='Number'>0</span><span class='Function'>βΎ</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></code>. If <code><span class='Number'>1</span><span class='Function'>==</span><span class='Value'>π©</span></code>, then there is no identity element, as the result of <code><span class='Function'>βΎ</span></code> always has rank at least 1, but the cell rank is 0.</p> +<h2 id="fill-elements">Fill elements</h2> +<p>Any BQN array can have a <em>fill element</em>, which is a sort of "default" value for the array. The reference implementations use <code><span class='Function'>Fill</span></code> to access this element, and it is used primarily for Take (<code><span class='Function'>β</span></code>), First (<code><span class='Function'>β</span></code>), and Nudge (<code><span class='Function'>Β«</span></code>, <code><span class='Function'>Β»</span></code>). One way to extract the fill element of an array <code><span class='Value'>a</span></code> in BQN is <code><span class='Function'>β</span><span class='Number'>0</span><span class='Function'>β₯</span><span class='Value'>a</span></code>.</p> +<p>A fill element can be either <code><span class='Number'>0</span></code>, <code><span class='String'>' '</span></code>, or an array of valid fill elements. If the fill element is an array, then it may also have a fill element (since it is an ordinary BQN array). The fill element is meant to describe the shared structure of the elements of an array: for example, the fill element of an array of numbers should be <code><span class='Number'>0</span></code>, while the fill element for an array of variable-length lists should probably be <code><span class='Bracket'>β¨β©</span></code>. However, the fill element, unlike other inferred properties, does not satisfy any particular constraints that relate it to its array.</p> +<h3 id="required-functions">Required functions</h3> +<p>Combinators <code><span class='Function'>β£β’!</span><span class='Modifier'>ΛΛΒ΄Λ</span><span class='Modifier2'>βββΈβββΆβ</span></code> do not affect fill element computation: if the combinator calls a function that computes a fill element, then that fill element must be retained if the result is passed to other functions or returned. <code><span class='Modifier2'>β</span></code> constructs arrays if its right operand is or contains arrays, and the fill elements of these arrays are not specified; converting <code><span class='Value'>π©</span></code> to a fill element is a reasonable choice in some cases but not others.</p> +<p>Arithmetic primitivesβall valences of <code><span class='Function'>+-ΓΓ·ββββ|Β¬β§β¨</span></code> and dyadic <code><span class='Function'><>β =β€β₯</span></code>βobtain their fill elements by applying to the fill elements of the arguments. If this is an error, there is no fill element; otherwise, the fill element is the result, with all numbers in it changed to <code><span class='Number'>0</span></code> and all characters changed to <code><span class='String'>' '</span></code>.</p> +<p>Fill elements for many primitives are given in the table below. The "Fill" column indicates the strategy used to compute the result's fill. Fields <code><span class='Number'>0</span></code>, <code><span class='Number'>0</span><span class='Function'>β</span><span class='Value'>π©</span></code>, and <code><span class='Number'>0</span><span class='Modifier2'>β</span><span class='Number'>0</span><span class='Value'>π©</span></code> indicate the fill directly, while <code><span class='Function'>β’</span></code> and <code><span class='Value'>β©</span></code> indicate that the fill is to be computed from the argument fills (if not all arguments have fills, then the fill element is unspecified). For <code><span class='Function'>β’</span></code>, the fill element of the result is the fill element of <code><span class='Value'>π©</span></code>. For <code><span class='Value'>β©</span></code>, the fill is equal to the fill values for multiple arrays, provided that they are all equal (it's unspecified if they are not all equal). In the two argument case, these arrays are <code><span class='Value'>π¨</span></code> and <code><span class='Value'>π©</span></code>. In the one-argument case, they are the elements of <code><span class='Value'>π©</span></code>; however, if <code><span class='Value'>π©</span></code> is empty, then the result's fill is the fill of the fill of <code><span class='Value'>π©</span></code>.</p> +<table> +<thead> +<tr> +<th>Fill</th> +<th>Monads</th> +<th>Dyads</th> +<th>Modifiers</th> +</tr> +</thead> +<tbody> +<tr> +<td><code><span class='Function'>β’</span></code></td> +<td><code><span class='Function'>β₯β½ββββ§β¨</span></code></td> +<td><code><span class='Function'>β₯β½βββββ/β·</span></code></td> +<td><code><span class='Function'>π½</span><span class='Modifier'>`</span></code></td> +</tr> +<tr> +<td><code><span class='Number'>0</span></code></td> +<td><code><span class='Function'>β’/ββββ·ββ</span></code></td> +<td><code><span class='Function'>βββββ</span></code></td> +<td></td> +</tr> +<tr> +<td><code><span class='Value'>β©</span></code></td> +<td><code><span class='Function'>>βΎ</span></code></td> +<td><code><span class='Function'>βΎβ</span></code></td> +<td></td> +</tr> +<tr> +<td><code><span class='Number'>0</span><span class='Function'>β</span><span class='Value'>π©</span></code></td> +<td><code><span class='Function'>ββ</span></code></td> +<td></td> +<td></td> +</tr> +<tr> +<td><code><span class='Number'>0</span><span class='Modifier2'>β</span><span class='Number'>0</span><span class='Value'>π©</span></code></td> +<td><code><span class='Function'>β</span></code></td> +<td></td> +<td></td> +</tr> +</tbody> +</table> +<p>For Group and Group Indices (<code><span class='Function'>β</span></code>), the fill element of the result and its elements are both specified: the fill element of each element of the result is the same as that of <code><span class='Value'>π©</span></code> for Group, and is <code><span class='Number'>0</span></code> for Group Indices. The fill element of the result is <code><span class='Paren'>(</span><span class='Number'>0</span><span class='Modifier2'>β</span><span class='Number'>1</span><span class='Value'>π¨</span><span class='Paren'>)</span><span class='Function'>β</span><span class='Value'>π©</span></code> for Group, and <code><span class='Function'>β₯</span><span class='Modifier2'>β</span><span class='Function'><</span><span class='Number'>0</span><span class='Modifier2'>β</span><span class='Number'>1</span><span class='Value'>π©</span></code> for Group Indices.</p> +<p>Fill elements of iteration modifiers such as <code><span class='Modifier'>Β¨β</span></code> are not specified. It is reasonable to define the fill element of <code><span class='Function'>π½</span><span class='Modifier'>β</span></code> or <code><span class='Function'>π½</span><span class='Modifier'>Β¨</span></code> to be <code><span class='Function'>π½</span></code> applied to the fill elements of the arguments. Regardless of definition, computing the fill element cannot cause side effects or an error.</p> <h2 id="undo">Undo</h2> <p>The Undo 1-modifier <code><span class='Modifier'>βΌ</span></code>, given an operand <code><span class='Function'>π½</span></code> and argument <code><span class='Value'>π©</span></code>, and possibly a left argument <code><span class='Value'>π¨</span></code>, finds a value <code><span class='Value'>y</span></code> such that <code><span class='Value'>π©</span><span class='Function'>β‘</span><span class='Value'>π¨</span><span class='Function'>π½</span><span class='Value'>y</span></code>, that is, an element of the pre-image of <code><span class='Value'>π©</span></code> under <code><span class='Function'>π½</span></code> or <code><span class='Value'>π¨</span><span class='Function'>π½β’</span></code>. Thus it satisfies the constraint <code><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='Modifier'>βΌ</span><span class='Value'>π©</span></code> (<code><span class='Value'>π¨</span><span class='Function'>π½</span><span class='Modifier'>βΌ</span><span class='Function'>β’</span></code> is a <em>right inverse</em> of <code><span class='Value'>π¨</span><span class='Function'>π½β’</span></code>) provided <code><span class='Function'>π½</span><span class='Modifier'>βΌ</span></code> and <code><span class='Function'>π½</span></code> both complete without error. <code><span class='Function'>π½</span><span class='Modifier'>βΌ</span></code> should of course give an error if no inverse element exists, and can also fail if no inverse can be found. It is also preferred for <code><span class='Function'>π½</span><span class='Modifier'>βΌ</span></code> to give an error if there are many choices of inverse with no clear way to choose one of them: for example, <code><span class='Number'>0</span><span class='Ligature'>βΏ</span><span class='Number'>0</span><span class='Function'>β</span><span class='Value'>m</span></code> returns the diagonal of matrix <code><span class='Value'>m</span></code>; <code><span class='Number'>0</span><span class='Ligature'>βΏ</span><span class='Number'>0</span><span class='Function'>β</span><span class='Modifier'>βΌ</span><span class='Number'>2</span><span class='Ligature'>βΏ</span><span class='Number'>3</span></code> requires values to be chosen for the off-diagonal elements in its result. It is better to give an error, encouraging the programmer to use a fully-specified approach like <code><span class='Number'>2</span><span class='Ligature'>βΏ</span><span class='Number'>3</span><span class='Modifier2'>βΎ</span><span class='Paren'>(</span><span class='Number'>0</span><span class='Ligature'>βΏ</span><span class='Number'>0</span><span class='Modifier2'>βΈ</span><span class='Function'>β</span><span class='Paren'>)</span></code> applied to a matrix of initial elements, than to return a result that could be very different from other implementations.</p> <p>When working with limited-precision numbers, it may be difficult or impossible to exactly invert the operand function. Instead, it is generally acceptable to perform a computation that, if done with unlimited precision, would exactly invert <code><span class='Function'>π½</span></code> computed with unlimited precision. This principle is the basis for the numeric inverses specified below. It is also acceptable to find an inverse by numeric methods, provided that the error in the inverse value found relative to an unlimited-precision inverse can be kept close to the inherent error in the implementation's number format.</p> |
