diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-07-08 22:06:05 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-07-08 22:06:05 -0400 |
| commit | 7fa325f583a59a1999cd8ce093a49f8048a3e05c (patch) | |
| tree | 5157b1cbd4af6318eb77b3fcf5d80420d0cba46d | |
| parent | 9ce4441a2fec2f6bd301f9cf5ad801c9534d34eb (diff) | |
Simplify and update Couple/Merge docs
| -rw-r--r-- | doc/arrayrepr.md | 2 | ||||
| -rw-r--r-- | doc/couple.md | 22 | ||||
| -rw-r--r-- | doc/rank.md | 2 | ||||
| -rw-r--r-- | doc/syntax.md | 2 | ||||
| -rw-r--r-- | docs/doc/arrayrepr.html | 2 | ||||
| -rw-r--r-- | docs/doc/couple.html | 15 | ||||
| -rw-r--r-- | docs/doc/rank.html | 2 | ||||
| -rw-r--r-- | docs/doc/syntax.html | 2 |
8 files changed, 26 insertions, 23 deletions
diff --git a/doc/arrayrepr.md b/doc/arrayrepr.md index 63dba983..1047c187 100644 --- a/doc/arrayrepr.md +++ b/doc/arrayrepr.md @@ -123,7 +123,7 @@ BQN's separator rules give list notation a very flexible structure. You can put #### High-rank arrays -Higher-rank arrays can be written with `[]`, an **array notation** that indicates each element is to be used as a [cell](array.md#cells) of its result. It's identical to forming a list and applying [Merge](couple.md#merge-and-array-theory) (`[…]` is the same as `>⟨…⟩`). +Higher-rank arrays can be written with `[]`, an **array notation** that indicates each element is to be used as a [cell](array.md#cells) of its result. It's identical to forming a list and applying [Merge](couple.md) (`[…]` is the same as `>⟨…⟩`). [2‿3, 4‿1, 0‿5] diff --git a/doc/couple.md b/doc/couple.md index e3823249..a360e693 100644 --- a/doc/couple.md +++ b/doc/couple.md @@ -25,7 +25,15 @@ Merge (`>`) takes one argument, but a nested one. `𝕩` is an array of arrays, ≢ a ≢ > a -Merge serves as a generalization of Solo and Couple, since Solo is `{>⟨𝕩⟩}` and Couple is `{>⟨𝕨,𝕩⟩}`. Since `≍` works on the "list" of arguments, it can only add one dimension, but `>` can take any number of dimensions as its input. +If `𝕩` is empty, but has a [fill](fill.md) element, then its shape is used for the inner shape. If it doesn't have a fill, the inner shape is assumed to be empty, so that the result is `𝕩` with no changes. + +Merge serves as a generalization of Solo and Couple, since Solo is `{>⟨𝕩⟩}` and Couple is `{>⟨𝕨,𝕩⟩}`. These can be combined with [Pair](pair.md), giving `>⋈` for both. Since the result of `⋈` has rank 1, it can only add one dimension, but `>` can take any number of dimensions as its input. + +## Coupling units + +A note on the topic of Solo and Couple applied to [units](enclose.md#whats-a-unit). As always, one axis will be added, so that the result is a list (strangely, J's [laminate](https://code.jsoftware.com/wiki/Vocabulary/commaco#dyadic) differs from Couple in this one case, as it adds an axis to get a shape `2‿1` result). Solo on a unit is interchangeable with [Deshape](reshape.md) (`⥊`), and either primitive might be chosen for stylistic reasons. Couple on units is equivalent to [Join-to](join.md) (`∾`), but this is an irregular form of Join-to because it is the only case where Join-to adds an axis to both arguments instead of just one. Couple should be preferred in this case. + +As a consequence, [Pair](pair.md) (`⋈`) can be written `≍○<`, while `≍` is `>∘⋈` as discussed above. This gives the neat (but not useful) identities `≍ ←→ >∘≍○<`, and `⋈ ←→ >∘⋈○<`, which have the same form because adding `○<` commutes with adding `>∘`. ## Merge and array theory @@ -36,7 +44,7 @@ In all cases, what these functions do is more like reinterpreting existing data ⥊ ⥊¨ a ∾ ⥊ ⥊¨ a -Somewhat like [Table](map.md#table) `⌜`, Merge might be considered a fundamental way to build up multidimensional arrays from lists. In both cases rank-0 or [unit](enclose.md#whats-a-unit) arrays are somewhat special. They are the [identity value](fold.md#identity-values) of a function with Table, and [Enclose](enclose.md) (`<`), which creates a unit, is a right inverse to Merge. Enclose is needed because Merge can't produce a rank 0 array on its own. Merge has another catch as well: it can't produce arrays with a 0 in the shape, except at the end, without relying on a [fill](fill.md) element. +Somewhat like [Table](map.md#table) `⌜`, Merge might be considered a fundamental way to build up multidimensional arrays from lists. In both cases rank-0 or [unit](enclose.md#whats-a-unit) arrays are somewhat special. They are the [identity value](fold.md#identity-values) of a function with Table, and [Enclose](enclose.md) (`<`), which creates a unit, is a right inverse to Merge. Enclose is needed because Merge can't produce a rank 0 array on its own. Merge has another catch as well: it can't produce arrays with a 0 in the shape, except at the end, without relying on a fill element. ⊢ e ← ⟨⟩¨ ↕3 ≢ > e @@ -44,14 +52,8 @@ Somewhat like [Table](map.md#table) `⌜`, Merge might be considered a fundament Above we start with a list of three empty arrays. After merging once we get a shape `3‿0` array, sure, but what happens next? The shape added by another merge is the shared shape of that array's elements—and there aren't any! If the nested list kept some type information around then we might know, but extra type information is essentially how lists pretend to be arrays. True dynamic lists simply can't represent multidimensional arrays with a 0 in the middle of the shape. In this sense, arrays are a richer model than nested lists. -## Coupling units - -A note on the topic of Solo and Couple applied to units. As always, one axis will be added, so that the result is a list (strangely, J's [laminate](https://code.jsoftware.com/wiki/Vocabulary/commaco#dyadic) differs from Couple in this one case, as it will add an axis to get a shape `2‿1` result). For Solo, this is interchangeable with [Deshape](reshape.md) (`⥊`), and either primitive might be chosen for stylistic reasons. For Couple, it is equivalent to [Join-to](join.md) (`∾`), but this is an irregular form of Join-to because it is the only case where Join-to adds an axis to both arguments instead of just one. Couple should be preferred in this case. - -The function [Pair](pair.md) (`⋈`) can be written `≍○<`, while `≍` in either valence is `>∘⋈`. As an interesting consequence, `≍ ←→ >∘≍○<`, and `⋈ ←→ >∘⋈○<`. These two identities have the same form because adding `○<` commutes with adding `>∘`. - ## Definitions -As discussed above, `≍` is equivalent to `>{⟨𝕩⟩;⟨𝕨,𝕩⟩}` or `>⋈`. To complete the picture we should describe Merge fully. Merge is defined on an array argument `𝕩` such that there's some shape `s` satisfying `∧´⥊(s≡≢)¨𝕩`. If `𝕩` is empty then any shape satisfies this expression; `s` should be chosen based on known type information for `𝕩` or otherwise assumed to be `⟨⟩`. If `s` is empty then `𝕩` is allowed to contain atoms as well as unit arrays, and these will be implicitly promoted to arrays by the `⊑` indexing used later. We construct the result by combining the outer and inner axes of the argument with Table; since the outer axes come first they must correspond to the left argument and the inner axes must correspond to the right argument. `𝕩` is a natural choice of left argument, and because no concrete array can be used, the right argument will be `↕s`, the array of indices into any element of `𝕩`. To get the appropriate element corresponding to a particular choice of index and element of `𝕩` we should select using that index. The result of Merge is `𝕩⊑˜⌜↕s`. +We can define `≍` as `>⋈`. To complete the picture we should describe Merge fully. Merge is defined on an array argument `𝕩` such that there's some shape `s` satisfying `∧´⥊(s≡≢)¨𝕩`. If `𝕩` is empty then any shape satisfies this expression; `s` is then the shape of the [fill](fill.md) if there is one, or otherwise `⟨⟩`. -Given this definition we can also describe Rank (`⎉`) in terms of Each (`¨`) and the simpler monadic function Enclose-Rank `<⎉k`. We assume effective ranks `j` for `𝕨` (if present) and `k` for `𝕩` have been computed. Then the correspondence is `𝕨F⎉k𝕩 ←→ >(<⎉j𝕨)F¨(<⎉k𝕩)`. +Then the result of Merge is `𝕩⊑˜⌜↕s`. Here, [Table](map.md#table) is a nice way of combining outer and inner axes to produce the result; since the outer axes come first they should go on the left and the inner axes on the right. `𝕩` is a natural choice of left argument, and because no concrete array can be used, the right argument is `↕s`, the array of indices into any element of `𝕩`. Then [Pick](pick.md) selects all the elements. If `s` is empty, then `𝕩` is allowed to contain atoms as well as unit arrays. Pick will implicitly treat them as arrays. diff --git a/doc/rank.md b/doc/rank.md index 594156ce..0dfae645 100644 --- a/doc/rank.md +++ b/doc/rank.md @@ -147,7 +147,7 @@ Lets look at things more systematically. Suppose `x` has shape `4‿3‿2‿1‿ ≢ ⊑ <⎉2 ↕4‿3‿2‿1‿0 -We can build a frame array using `<⎉2`, as shown above. In the general case, the frame remains conceptual: the actual array `<⎉2 x` is never created, and the result might also not have the shape `4‿3‿2`. But the result shape does always have `4‿3‿2` as a prefix. Rank maps over these axes, leaving them intact. And it can be defined in terms of the cell-splitting function `<⎉k`, and its inverse [Merge](couple.md#merge-and-array-theory) (`>`). +We can build a frame array using `<⎉2`, as shown above. In the general case, the frame remains conceptual: the actual array `<⎉2 x` is never created, and the result might also not have the shape `4‿3‿2`. But the result shape does always have `4‿3‿2` as a prefix. Rank maps over these axes, leaving them intact. And it can be defined in terms of the cell-splitting function `<⎉k`, and its inverse [Merge](couple.md) (`>`). F⎉k x ←→ >F¨<⎉k x diff --git a/doc/syntax.md b/doc/syntax.md index fc63ffe6..292e6cc9 100644 --- a/doc/syntax.md +++ b/doc/syntax.md @@ -92,7 +92,7 @@ Arrays and code blocks can both be represented as sequences of expressions in so Lists (1-dimensional arrays) are enclosed in angle brackets `⟨⟩`, with the results of the expressions in between being the list's elements. Lists of two elements or more can also be written with the ligature character `‿`. This character has higher binding strength than any part of an expression except `.` for namespace field access. If one of the elements is a compound expression, then it will need to be enclosed in parentheses. -Arrays, or at least non-empty ones with rank 1 or more, can be written with square brackets `[]`. These work just like angle brackets but [merge](couple.md#merge-and-array-theory) the elements so that they form cells of the result. +Arrays, or at least non-empty ones with rank 1 or more, can be written with square brackets `[]`. These work just like angle brackets but [merge](couple.md) the elements so that they form cells of the result. ### Blocks diff --git a/docs/doc/arrayrepr.html b/docs/doc/arrayrepr.html index 5218009e..b2335438 100644 --- a/docs/doc/arrayrepr.html +++ b/docs/doc/arrayrepr.html @@ -193,7 +193,7 @@ <span class='Bracket'>⟩</span> </pre> <h4 id="high-rank-arrays"><a class="header" href="#high-rank-arrays">High-rank arrays</a></h4> -<p>Higher-rank arrays can be written with <code><span class='Bracket'>[]</span></code>, an <strong>array notation</strong> that indicates each element is to be used as a <a href="array.html#cells">cell</a> of its result. It's identical to forming a list and applying <a href="couple.html#merge-and-array-theory">Merge</a> (<code><span class='Bracket'>[</span><span class='Value'>…</span><span class='Bracket'>]</span></code> is the same as <code><span class='Function'>></span><span class='Bracket'>⟨</span><span class='Value'>…</span><span class='Bracket'>⟩</span></code>).</p> +<p>Higher-rank arrays can be written with <code><span class='Bracket'>[]</span></code>, an <strong>array notation</strong> that indicates each element is to be used as a <a href="array.html#cells">cell</a> of its result. It's identical to forming a list and applying <a href="couple.html">Merge</a> (<code><span class='Bracket'>[</span><span class='Value'>…</span><span class='Bracket'>]</span></code> is the same as <code><span class='Function'>></span><span class='Bracket'>⟨</span><span class='Value'>…</span><span class='Bracket'>⟩</span></code>).</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=WzLigL8zLCA04oC/MSwgMOKAvzVd">↗️</a><pre> <span class='Bracket'>[</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Separator'>,</span> <span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Separator'>,</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>5</span><span class='Bracket'>]</span> ┌─ ╵ 2 3 diff --git a/docs/doc/couple.html b/docs/doc/couple.html index d5325de5..86d8434a 100644 --- a/docs/doc/couple.html +++ b/docs/doc/couple.html @@ -59,7 +59,11 @@ <span class='Function'>≢</span> <span class='Function'>></span> <span class='Value'>a</span> ⟨ 2 3 5 ⟩ </pre> -<p>Merge serves as a generalization of Solo and Couple, since Solo is <code><span class='Brace'>{</span><span class='Function'>></span><span class='Bracket'>⟨</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span><span class='Brace'>}</span></code> and Couple is <code><span class='Brace'>{</span><span class='Function'>></span><span class='Bracket'>⟨</span><span class='Value'>𝕨</span><span class='Separator'>,</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span><span class='Brace'>}</span></code>. Since <code><span class='Function'>≍</span></code> works on the "list" of arguments, it can only add one dimension, but <code><span class='Function'>></span></code> can take any number of dimensions as its input.</p> +<p>If <code><span class='Value'>𝕩</span></code> is empty, but has a <a href="fill.html">fill</a> element, then its shape is used for the inner shape. If it doesn't have a fill, the inner shape is assumed to be empty, so that the result is <code><span class='Value'>𝕩</span></code> with no changes.</p> +<p>Merge serves as a generalization of Solo and Couple, since Solo is <code><span class='Brace'>{</span><span class='Function'>></span><span class='Bracket'>⟨</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span><span class='Brace'>}</span></code> and Couple is <code><span class='Brace'>{</span><span class='Function'>></span><span class='Bracket'>⟨</span><span class='Value'>𝕨</span><span class='Separator'>,</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span><span class='Brace'>}</span></code>. These can be combined with <a href="pair.html">Pair</a>, giving <code><span class='Function'>>⋈</span></code> for both. Since the result of <code><span class='Function'>⋈</span></code> has rank 1, it can only add one dimension, but <code><span class='Function'>></span></code> can take any number of dimensions as its input.</p> +<h2 id="coupling-units"><a class="header" href="#coupling-units">Coupling units</a></h2> +<p>A note on the topic of Solo and Couple applied to <a href="enclose.html#whats-a-unit">units</a>. As always, one axis will be added, so that the result is a list (strangely, J's <a href="https://code.jsoftware.com/wiki/Vocabulary/commaco#dyadic">laminate</a> differs from Couple in this one case, as it adds an axis to get a shape <code><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span></code> result). Solo on a unit is interchangeable with <a href="reshape.html">Deshape</a> (<code><span class='Function'>⥊</span></code>), and either primitive might be chosen for stylistic reasons. Couple on units is equivalent to <a href="join.html">Join-to</a> (<code><span class='Function'>∾</span></code>), but this is an irregular form of Join-to because it is the only case where Join-to adds an axis to both arguments instead of just one. Couple should be preferred in this case.</p> +<p>As a consequence, <a href="pair.html">Pair</a> (<code><span class='Function'>⋈</span></code>) can be written <code><span class='Function'>≍</span><span class='Modifier2'>○</span><span class='Function'><</span></code>, while <code><span class='Function'>≍</span></code> is <code><span class='Function'>></span><span class='Modifier2'>∘</span><span class='Function'>⋈</span></code> as discussed above. This gives the neat (but not useful) identities <code><span class='Function'>≍</span> <span class='Gets'>←→</span> <span class='Function'>></span><span class='Modifier2'>∘</span><span class='Function'>≍</span><span class='Modifier2'>○</span><span class='Function'><</span></code>, and <code><span class='Function'>⋈</span> <span class='Gets'>←→</span> <span class='Function'>></span><span class='Modifier2'>∘</span><span class='Function'>⋈</span><span class='Modifier2'>○</span><span class='Function'><</span></code>, which have the same form because adding <code><span class='Modifier2'>○</span><span class='Function'><</span></code> commutes with adding <code><span class='Function'>></span><span class='Modifier2'>∘</span></code>.</p> <h2 id="merge-and-array-theory"><a class="header" href="#merge-and-array-theory">Merge and array theory</a></h2> <p>In all cases, what these functions do is more like reinterpreting existing data than creating new information. In fact, if we ignore the shape and look at the deshaped arrays involved in a call to Merge, we find that it just <a href="join.html">joins</a> them together. Essentially, Merge is a request to ensure that the inner arrays make up a homogeneous (not "ragged") array, and then to consider them to be such an array. It's the same thing <a href="rank.html">Rank</a> does to combine the result cells from its operand into a single array.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4qWKID4gYQoK4qWKIOKlisKoIGEK4oi+IOKliiDipYrCqCBh">↗️</a><pre> <span class='Function'>⥊</span> <span class='Function'>></span> <span class='Value'>a</span> @@ -70,7 +74,7 @@ <span class='Function'>∾</span> <span class='Function'>⥊</span> <span class='Function'>⥊</span><span class='Modifier'>¨</span> <span class='Value'>a</span> "ABrstABuvwABxyzCDrstCDuvwCDxyz" </pre> -<p>Somewhat like <a href="map.html#table">Table</a> <code><span class='Modifier'>⌜</span></code>, Merge might be considered a fundamental way to build up multidimensional arrays from lists. In both cases rank-0 or <a href="enclose.html#whats-a-unit">unit</a> arrays are somewhat special. They are the <a href="fold.html#identity-values">identity value</a> of a function with Table, and <a href="enclose.html">Enclose</a> (<code><span class='Function'><</span></code>), which creates a unit, is a right inverse to Merge. Enclose is needed because Merge can't produce a rank 0 array on its own. Merge has another catch as well: it can't produce arrays with a 0 in the shape, except at the end, without relying on a <a href="fill.html">fill</a> element.</p> +<p>Somewhat like <a href="map.html#table">Table</a> <code><span class='Modifier'>⌜</span></code>, Merge might be considered a fundamental way to build up multidimensional arrays from lists. In both cases rank-0 or <a href="enclose.html#whats-a-unit">unit</a> arrays are somewhat special. They are the <a href="fold.html#identity-values">identity value</a> of a function with Table, and <a href="enclose.html">Enclose</a> (<code><span class='Function'><</span></code>), which creates a unit, is a right inverse to Merge. Enclose is needed because Merge can't produce a rank 0 array on its own. Merge has another catch as well: it can't produce arrays with a 0 in the shape, except at the end, without relying on a fill element.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGUg4oaQIOKfqOKfqcKoIOKGlTMK4omiID4gZQriiaIgPiA+IGU=">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>e</span> <span class='Gets'>←</span> <span class='Bracket'>⟨⟩</span><span class='Modifier'>¨</span> <span class='Function'>↕</span><span class='Number'>3</span> ⟨ ⟨⟩ ⟨⟩ ⟨⟩ ⟩ <span class='Function'>≢</span> <span class='Function'>></span> <span class='Value'>e</span> @@ -79,9 +83,6 @@ ⟨ 3 0 ⟩ </pre> <p>Above we start with a list of three empty arrays. After merging once we get a shape <code><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>0</span></code> array, sure, but what happens next? The shape added by another merge is the shared shape of that array's elements—and there aren't any! If the nested list kept some type information around then we might know, but extra type information is essentially how lists pretend to be arrays. True dynamic lists simply can't represent multidimensional arrays with a 0 in the middle of the shape. In this sense, arrays are a richer model than nested lists.</p> -<h2 id="coupling-units"><a class="header" href="#coupling-units">Coupling units</a></h2> -<p>A note on the topic of Solo and Couple applied to units. As always, one axis will be added, so that the result is a list (strangely, J's <a href="https://code.jsoftware.com/wiki/Vocabulary/commaco#dyadic">laminate</a> differs from Couple in this one case, as it will add an axis to get a shape <code><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span></code> result). For Solo, this is interchangeable with <a href="reshape.html">Deshape</a> (<code><span class='Function'>⥊</span></code>), and either primitive might be chosen for stylistic reasons. For Couple, it is equivalent to <a href="join.html">Join-to</a> (<code><span class='Function'>∾</span></code>), but this is an irregular form of Join-to because it is the only case where Join-to adds an axis to both arguments instead of just one. Couple should be preferred in this case.</p> -<p>The function <a href="pair.html">Pair</a> (<code><span class='Function'>⋈</span></code>) can be written <code><span class='Function'>≍</span><span class='Modifier2'>○</span><span class='Function'><</span></code>, while <code><span class='Function'>≍</span></code> in either valence is <code><span class='Function'>></span><span class='Modifier2'>∘</span><span class='Function'>⋈</span></code>. As an interesting consequence, <code><span class='Function'>≍</span> <span class='Gets'>←→</span> <span class='Function'>></span><span class='Modifier2'>∘</span><span class='Function'>≍</span><span class='Modifier2'>○</span><span class='Function'><</span></code>, and <code><span class='Function'>⋈</span> <span class='Gets'>←→</span> <span class='Function'>></span><span class='Modifier2'>∘</span><span class='Function'>⋈</span><span class='Modifier2'>○</span><span class='Function'><</span></code>. These two identities have the same form because adding <code><span class='Modifier2'>○</span><span class='Function'><</span></code> commutes with adding <code><span class='Function'>></span><span class='Modifier2'>∘</span></code>.</p> <h2 id="definitions"><a class="header" href="#definitions">Definitions</a></h2> -<p>As discussed above, <code><span class='Function'>≍</span></code> is equivalent to <code><span class='Function'>></span><span class='Brace'>{</span><span class='Bracket'>⟨</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span><span class='Head'>;</span><span class='Bracket'>⟨</span><span class='Value'>𝕨</span><span class='Separator'>,</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span><span class='Brace'>}</span></code> or <code><span class='Function'>>⋈</span></code>. To complete the picture we should describe Merge fully. Merge is defined on an array argument <code><span class='Value'>𝕩</span></code> such that there's some shape <code><span class='Value'>s</span></code> satisfying <code><span class='Function'>∧</span><span class='Modifier'>´</span><span class='Function'>⥊</span><span class='Paren'>(</span><span class='Value'>s</span><span class='Function'>≡≢</span><span class='Paren'>)</span><span class='Modifier'>¨</span><span class='Value'>𝕩</span></code>. If <code><span class='Value'>𝕩</span></code> is empty then any shape satisfies this expression; <code><span class='Value'>s</span></code> should be chosen based on known type information for <code><span class='Value'>𝕩</span></code> or otherwise assumed to be <code><span class='Bracket'>⟨⟩</span></code>. If <code><span class='Value'>s</span></code> is empty then <code><span class='Value'>𝕩</span></code> is allowed to contain atoms as well as unit arrays, and these will be implicitly promoted to arrays by the <code><span class='Function'>⊑</span></code> indexing used later. We construct the result by combining the outer and inner axes of the argument with Table; since the outer axes come first they must correspond to the left argument and the inner axes must correspond to the right argument. <code><span class='Value'>𝕩</span></code> is a natural choice of left argument, and because no concrete array can be used, the right argument will be <code><span class='Function'>↕</span><span class='Value'>s</span></code>, the array of indices into any element of <code><span class='Value'>𝕩</span></code>. To get the appropriate element corresponding to a particular choice of index and element of <code><span class='Value'>𝕩</span></code> we should select using that index. The result of Merge is <code><span class='Value'>𝕩</span><span class='Function'>⊑</span><span class='Modifier'>˜⌜</span><span class='Function'>↕</span><span class='Value'>s</span></code>.</p> -<p>Given this definition we can also describe Rank (<code><span class='Modifier2'>⎉</span></code>) in terms of Each (<code><span class='Modifier'>¨</span></code>) and the simpler monadic function Enclose-Rank <code><span class='Function'><</span><span class='Modifier2'>⎉</span><span class='Value'>k</span></code>. We assume effective ranks <code><span class='Value'>j</span></code> for <code><span class='Value'>𝕨</span></code> (if present) and <code><span class='Value'>k</span></code> for <code><span class='Value'>𝕩</span></code> have been computed. Then the correspondence is <code><span class='Value'>𝕨</span><span class='Function'>F</span><span class='Modifier2'>⎉</span><span class='Value'>k𝕩</span> <span class='Gets'>←→</span> <span class='Function'>></span><span class='Paren'>(</span><span class='Function'><</span><span class='Modifier2'>⎉</span><span class='Value'>j𝕨</span><span class='Paren'>)</span><span class='Function'>F</span><span class='Modifier'>¨</span><span class='Paren'>(</span><span class='Function'><</span><span class='Modifier2'>⎉</span><span class='Value'>k𝕩</span><span class='Paren'>)</span></code>.</p> +<p>We can define <code><span class='Function'>≍</span></code> as <code><span class='Function'>>⋈</span></code>. To complete the picture we should describe Merge fully. Merge is defined on an array argument <code><span class='Value'>𝕩</span></code> such that there's some shape <code><span class='Value'>s</span></code> satisfying <code><span class='Function'>∧</span><span class='Modifier'>´</span><span class='Function'>⥊</span><span class='Paren'>(</span><span class='Value'>s</span><span class='Function'>≡≢</span><span class='Paren'>)</span><span class='Modifier'>¨</span><span class='Value'>𝕩</span></code>. If <code><span class='Value'>𝕩</span></code> is empty then any shape satisfies this expression; <code><span class='Value'>s</span></code> is then the shape of the <a href="fill.html">fill</a> if there is one, or otherwise <code><span class='Bracket'>⟨⟩</span></code>.</p> +<p>Then the result of Merge is <code><span class='Value'>𝕩</span><span class='Function'>⊑</span><span class='Modifier'>˜⌜</span><span class='Function'>↕</span><span class='Value'>s</span></code>. Here, <a href="map.html#table">Table</a> is a nice way of combining outer and inner axes to produce the result; since the outer axes come first they should go on the left and the inner axes on the right. <code><span class='Value'>𝕩</span></code> is a natural choice of left argument, and because no concrete array can be used, the right argument is <code><span class='Function'>↕</span><span class='Value'>s</span></code>, the array of indices into any element of <code><span class='Value'>𝕩</span></code>. Then <a href="pick.html">Pick</a> selects all the elements. If <code><span class='Value'>s</span></code> is empty, then <code><span class='Value'>𝕩</span></code> is allowed to contain atoms as well as unit arrays. Pick will implicitly treat them as arrays.</p> diff --git a/docs/doc/rank.html b/docs/doc/rank.html index 8cf63ad2..631693cf 100644 --- a/docs/doc/rank.html +++ b/docs/doc/rank.html @@ -219,7 +219,7 @@ <span class='Function'>≢</span> <span class='Function'>⊑</span> <span class='Function'><</span><span class='Modifier2'>⎉</span><span class='Number'>2</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='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span> ⟨ 1 0 ⟩ </pre> -<p>We can build a frame array using <code><span class='Function'><</span><span class='Modifier2'>⎉</span><span class='Number'>2</span></code>, as shown above. In the general case, the frame remains conceptual: the actual array <code><span class='Function'><</span><span class='Modifier2'>⎉</span><span class='Number'>2</span> <span class='Value'>x</span></code> is never created, and the result might also not have the shape <code><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span></code>. But the result shape does always have <code><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span></code> as a prefix. Rank maps over these axes, leaving them intact. And it can be defined in terms of the cell-splitting function <code><span class='Function'><</span><span class='Modifier2'>⎉</span><span class='Value'>k</span></code>, and its inverse <a href="couple.html#merge-and-array-theory">Merge</a> (<code><span class='Function'>></span></code>).</p> +<p>We can build a frame array using <code><span class='Function'><</span><span class='Modifier2'>⎉</span><span class='Number'>2</span></code>, as shown above. In the general case, the frame remains conceptual: the actual array <code><span class='Function'><</span><span class='Modifier2'>⎉</span><span class='Number'>2</span> <span class='Value'>x</span></code> is never created, and the result might also not have the shape <code><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span></code>. But the result shape does always have <code><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span></code> as a prefix. Rank maps over these axes, leaving them intact. And it can be defined in terms of the cell-splitting function <code><span class='Function'><</span><span class='Modifier2'>⎉</span><span class='Value'>k</span></code>, and its inverse <a href="couple.html">Merge</a> (<code><span class='Function'>></span></code>).</p> <pre><span class='Function'>F</span><span class='Modifier2'>⎉</span><span class='Value'>k</span> <span class='Value'>x</span> <span class='Gets'>←→</span> <span class='Function'>>F</span><span class='Modifier'>¨</span><span class='Function'><</span><span class='Modifier2'>⎉</span><span class='Value'>k</span> <span class='Value'>x</span> </pre> <p>That is, <code><span class='Function'>F</span><span class='Modifier2'>⎉</span><span class='Value'>k</span></code> splits its argument into <code><span class='Value'>k</span></code>-cells, applies <code><span class='Function'>F</span></code> to each of these (in index order, of course), then merges the results into a single array.</p> diff --git a/docs/doc/syntax.html b/docs/doc/syntax.html index 26af7c42..23f1a3a2 100644 --- a/docs/doc/syntax.html +++ b/docs/doc/syntax.html @@ -258,7 +258,7 @@ <h3 id="list-and-array-notation"><a class="header" href="#list-and-array-notation">List and array notation</a></h3> <p><em><a href="arrayrepr.html#array-literals">Full documentation</a></em></p> <p>Lists (1-dimensional arrays) are enclosed in angle brackets <code><span class='Bracket'>⟨⟩</span></code>, with the results of the expressions in between being the list's elements. Lists of two elements or more can also be written with the ligature character <code><span class='Ligature'>‿</span></code>. This character has higher binding strength than any part of an expression except <code><span class='Value'>.</span></code> for namespace field access. If one of the elements is a compound expression, then it will need to be enclosed in parentheses.</p> -<p>Arrays, or at least non-empty ones with rank 1 or more, can be written with square brackets <code><span class='Bracket'>[]</span></code>. These work just like angle brackets but <a href="couple.html#merge-and-array-theory">merge</a> the elements so that they form cells of the result.</p> +<p>Arrays, or at least non-empty ones with rank 1 or more, can be written with square brackets <code><span class='Bracket'>[]</span></code>. These work just like angle brackets but <a href="couple.html">merge</a> the elements so that they form cells of the result.</p> <h3 id="blocks"><a class="header" href="#blocks">Blocks</a></h3> <p><em><a href="block.html">Full documentation</a></em></p> <p>Blocks are written with curly braces <code><span class='Brace'>{}</span></code> and can have a subject, function, or modifier role. The contents are any number of bodies separated by <code><span class='Head'>;</span></code>. Each body is a sequence of expressions to be evaluated in order, possibly with a header, followed by <code><span class='Head'>:</span></code>, that sets the type and describes expected inputs. A body runs in its own environment according to the rules of <a href="lexical.html">lexical scoping</a>. The result is either a <a href="namespace.html">namespace</a>, if the body used <code><span class='Gets'>⇐</span></code>, or the result of the last expression.</p> |
