diff options
| -rw-r--r-- | doc/README.md | 1 | ||||
| -rw-r--r-- | doc/enclose.md | 5 | ||||
| -rw-r--r-- | doc/primitive.md | 2 | ||||
| -rw-r--r-- | doc/rank.md | 57 | ||||
| -rw-r--r-- | docs/doc/enclose.html | 7 | ||||
| -rw-r--r-- | docs/doc/index.html | 1 | ||||
| -rw-r--r-- | docs/doc/primitive.html | 2 | ||||
| -rw-r--r-- | docs/doc/rank.html | 94 |
8 files changed, 162 insertions, 7 deletions
diff --git a/doc/README.md b/doc/README.md index 110482f2..2e6dcec7 100644 --- a/doc/README.md +++ b/doc/README.md @@ -43,6 +43,7 @@ Primitives: - [Assert and Catch: `!` and `⎊`](assert.md) - [Atop and Over: `∘○`](compose.md) - [Before and After: `⊸⟜`](hook.md) +- [Cells and Rank: `˘⎉`](rank.md) - [Choose: `◶`](choose.md) - [Constant: `˙`](constant.md) - [Deshape and Reshape: `⥊`](reshape.md) diff --git a/doc/enclose.md b/doc/enclose.md index abefbc07..e43dffc3 100644 --- a/doc/enclose.md +++ b/doc/enclose.md @@ -31,9 +31,10 @@ Usually this is unwanted. You'd prefer to use `⊑` or `+´` in order to get an +˝˘ 3‿4⥊↕12 -In this case each call to `+˝` returns a cell of the result. The result is a list, so its cells are units! Here, Cells (`˘`) "hides" one axis from its operand, and the operand `+˝` reduces out an axis, leaving zero axes—until Cells assembles the results, putting its axis back. In this case, `+´` would also be tolerated. But it's wrong, because each result really should be a zero-axis array. We can reveal this by making an array whose elements aren't atoms. +In this case each call to `+˝` returns a cell of the result. The result is a list, so its cells are units! Here, [Cells](rank.md) (`˘`) "hides" one axis from its operand, and the operand `+˝` reduces out an axis, leaving zero axes—until Cells assembles the results, putting its axis back. In this case, `+´` would also be tolerated. But it's wrong, because each result really should be a zero-axis array. We can reveal this by making an array whose elements aren't atoms. +´˘ ⟨↕2,"ab"⟩≍⟨↕3,"ABC"⟩ + +˝˘ ⟨↕2,"ab"⟩≍⟨↕3,"ABC"⟩ The function `+´˘` tries to mix together the result elements into one big array, causing an error because they have different lengths, but `+˝˘` keeps them as elements. @@ -60,7 +61,7 @@ For this purpose `{⟨𝕩⟩}⊸∾`, which turns the left argument into a 1-el (=⌜˜↕4) ∾˘ ↕4 -Now Cells (`˘`) splits both arguments into cells. For the `𝕨`, a rank-2 array, these cells are lists; for the list `𝕩` they have to be units. Treating them as elements would work in this case, because `∾` would automatically enclose them, but would fail if `𝕩` contained non-atom elements such as strings. +Now [Cells](rank.md) (`˘`) splits both arguments into cells. For the `𝕨`, a rank-2 array, these cells are lists; for the list `𝕩` they have to be units. Treating them as elements would work in this case, because `∾` would automatically enclose them, but would fail if `𝕩` contained non-atom elements such as strings. The other use of `<` in the original example is `(<⟨⟩)`, which is the left argument to the function `<⊸∾⌜´`. Let's break that function down. We said `<⊸∾` joins `𝕨` as an element to the front of `𝕩`. With [Table](map.md#table) we have `<⊸∾⌜`, which takes two array arguments and does this for every pair of elements from them. diff --git a/doc/primitive.md b/doc/primitive.md index a48d6602..2cc034de 100644 --- a/doc/primitive.md +++ b/doc/primitive.md @@ -83,7 +83,7 @@ Other modifiers control array traversal and iteration. In three cases a simpler | 1-Modifier | Name | 2-Modifier | Name |------------|---------------------------------------|------------|-------- -| `˘` | Cells | `⎉` | [Rank](https://aplwiki.com/wiki/Rank_(operator)) +| `˘` | [Cells](rank.md) | `⎉` | [Rank](https://aplwiki.com/wiki/Rank_(operator)) | `¨` | [Each](map.md) | `⚇` | [Depth](depth.md#the-depth-modifier) | `⌜` | [Table](map.md) | | `⁼` | [Undo](undo.md) | `⍟` | [Repeat](repeat.md) diff --git a/doc/rank.md b/doc/rank.md new file mode 100644 index 00000000..0aa78bfa --- /dev/null +++ b/doc/rank.md @@ -0,0 +1,57 @@ +*View this file with results and syntax highlighting [here](https://mlochbaum.github.io/BQN/doc/rank.html).* + +# Cells and Rank + +The Cells modifier `˘` applies a function to major cells of its argument, much like [Each](map.md) applies to elements. Each result from `𝔽` becomes a major cell of the result, which means they must all have the same shape. + +The Rank modifier `⎉` generalizes this concept by allowing numbers provided by `𝔾` to specify a rank for each argument: non-negative to indicate the rank of each array passed to `𝔽`, or negative for the number of axes that are mapped over. Cells, which maps over one axis of each argument, is identical to `⎉¯1`. Rank is analogous to the [Depth modifier](depth.md#the-depth-modifier), but the homogeneous structure of an array eliminates some tricky edge cases found in Depth. + +## Cells + +The function Cells (`˘`) is named after *major cells* in an array. A major cell is a component of an array with dimension one smaller, so that the major cells of a list are [units](enclose.md#whats-a-unit), the major cells of a rank-2 table are its rows (which are lists), and the major cells of a rank-3 array are tables. + +The function `𝔽˘` applies `𝔽` to the major cells of `𝕩`. So, for example, where [Nudge](shift.md) (`»`) shifts an entire table, Nudge Cells shifts its major cells, or rows. + + a ← 'a' + 3‿∘ ⥊ ↕24 # A character array + + ⟨ a , »a , »˘a ⟩ + +What's it mean for Nudge to shift the "entire table"? The block above shows that is shifts downward, but what's really happening is that Nudge treats `𝕩` as a collection of major cells—its rows—and shifts these. So it adds an entire row and moves the rest of the rows downwards. Nudge Cells appears similar, but it's acting independently on each row, and the values that it moves around are major cells of the row, that is, rank-0 units. + +Here's an example showing how Cells can be used to shift each row independently, even though it's not possible to shift columns like this (in fact the best way to would be to [transpose](transpose.md) in order to work on rows). It uses the not-yet-introduced dyadic form of Cells, so you might want to come back to it after reading the next section. + + (↑"∘∘") ⊑⊸»˘ a + +You can also see how Cells splits its argument into rows using a less array-oriented primitive: [Enclose](enclose.md) just wraps each row up so that it appears as a separate element in the final result. + + <˘ a + +Enclose also comes in handy for the following task: join the rows in an array of lists, resulting in an array where each element is a joined row. The obvious guess would be "join cells", `∾˘`, but it doesn't work, because each `∾` can return a result with a different length. Cells tries to make each result of `∾` into a *cell*, when the problem was to use it as an *element*. But a 0-cell is an enclosed element, so we can close the gap by applying `<` to a joined list: `<∘∾`. + + ⊢ s ← "words"‿"go"‿"here" ≍ "some"‿"other"‿"words" + + ∾˘ s + + <∘∾˘ s + +This approach can apply to more complicated functions as well. And because the result of `<` always has the same shape, `⟨⟩`, the function `<∘𝔽˘` can never have a shape agreement error. So if `𝔽˘` fails, it can't hurt to check `<∘𝔽˘` and see what results `𝔽` is returning. + +### Two arguments + +When given two arguments, Cells tries to pair their cells together. Starting simple, a unit array on either side will be paired with every cell of the other argument (and an atom is converted to an array). + + '∘' »˘ a + +If you *want* to use this one-to-many behavior with an array, it'll take more work: since you're really only mapping over one argument, [bind](hook.md) the other inside Cells. + + "∘∘" »˘ a + + "∘∘"⊸»˘ a + +This is because the general case of Cells does one-to-one matching, pairing the first axis of one argument with the other. For this to work, the two arguments need to have the same length. + + ⟨ "012" »˘ a, (3‿∘⥊"UVWXYZ") »˘ a ⟩ + +The arguments might have different ranks: for example, `"012"` has rank 1 and `a` has rank 2 above. That's fine: it just means Cells will pass arguments of rank 0 and 1 to its operand. You can see these arguments using [Pair](pair.md) Cells, `⋈˘`, so that each cell of the result is just a list of the two arguments used for that call. + + "012" ⋈˘ a diff --git a/docs/doc/enclose.html b/docs/doc/enclose.html index 2a401603..82fbee31 100644 --- a/docs/doc/enclose.html +++ b/docs/doc/enclose.html @@ -37,9 +37,10 @@ <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=K8udy5ggM+KAvzTipYrihpUxMg==">↗️</a><pre> <span class='Function'>+</span><span class='Modifier'>˝˘</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Function'>⥊↕</span><span class='Number'>12</span> ⟨ 6 22 38 ⟩ </pre> -<p>In this case each call to <code><span class='Function'>+</span><span class='Modifier'>˝</span></code> returns a cell of the result. The result is a list, so its cells are units! Here, Cells (<code><span class='Modifier'>˘</span></code>) "hides" one axis from its operand, and the operand <code><span class='Function'>+</span><span class='Modifier'>˝</span></code> reduces out an axis, leaving zero axes—until Cells assembles the results, putting its axis back. In this case, <code><span class='Function'>+</span><span class='Modifier'>´</span></code> would also be tolerated. But it's wrong, because each result really should be a zero-axis array. We can reveal this by making an array whose elements aren't atoms.</p> -<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=K8K0y5gg4p+o4oaVMiwiYWIi4p+p4omN4p+o4oaVMywiQUJDIuKfqQory53LmCDin6jihpUyLCJhYiLin6niiY3in6jihpUzLCJBQkMi4p+p">↗️</a><pre> <span class='Function'>+</span><span class='Modifier'>´˘</span> <span class='Bracket'>⟨</span><span class='Function'>↕</span><span class='Number'>2</span><span class='Separator'>,</span><span class='String'>"ab"</span><span class='Bracket'>⟩</span><span class='Function'>≍</span><span class='Bracket'>⟨</span><span class='Function'>↕</span><span class='Number'>3</span><span class='Separator'>,</span><span class='String'>"ABC"</span><span class='Bracket'>⟩</span> +<p>In this case each call to <code><span class='Function'>+</span><span class='Modifier'>˝</span></code> returns a cell of the result. The result is a list, so its cells are units! Here, <a href="rank.html">Cells</a> (<code><span class='Modifier'>˘</span></code>) "hides" one axis from its operand, and the operand <code><span class='Function'>+</span><span class='Modifier'>˝</span></code> reduces out an axis, leaving zero axes—until Cells assembles the results, putting its axis back. In this case, <code><span class='Function'>+</span><span class='Modifier'>´</span></code> would also be tolerated. But it's wrong, because each result really should be a zero-axis array. We can reveal this by making an array whose elements aren't atoms.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=K8K0y5gg4p+o4oaVMiwiYWIi4p+p4omN4p+o4oaVMywiQUJDIuKfqQoKK8udy5gg4p+o4oaVMiwiYWIi4p+p4omN4p+o4oaVMywiQUJDIuKfqQ==">↗️</a><pre> <span class='Function'>+</span><span class='Modifier'>´˘</span> <span class='Bracket'>⟨</span><span class='Function'>↕</span><span class='Number'>2</span><span class='Separator'>,</span><span class='String'>"ab"</span><span class='Bracket'>⟩</span><span class='Function'>≍</span><span class='Bracket'>⟨</span><span class='Function'>↕</span><span class='Number'>3</span><span class='Separator'>,</span><span class='String'>"ABC"</span><span class='Bracket'>⟩</span> <span class='Error'>Error: >: Elements didn't have equal shapes (contained ⟨2⟩ and ⟨3⟩)</span> + <span class='Function'>+</span><span class='Modifier'>˝˘</span> <span class='Bracket'>⟨</span><span class='Function'>↕</span><span class='Number'>2</span><span class='Separator'>,</span><span class='String'>"ab"</span><span class='Bracket'>⟩</span><span class='Function'>≍</span><span class='Bracket'>⟨</span><span class='Function'>↕</span><span class='Number'>3</span><span class='Separator'>,</span><span class='String'>"ABC"</span><span class='Bracket'>⟩</span> ⟨ "ac" "ACE" ⟩ </pre> @@ -76,7 +77,7 @@ 0 0 0 1 3 ┘ </pre> -<p>Now Cells (<code><span class='Modifier'>˘</span></code>) splits both arguments into cells. For the <code><span class='Value'>𝕨</span></code>, a rank-2 array, these cells are lists; for the list <code><span class='Value'>𝕩</span></code> they have to be units. Treating them as elements would work in this case, because <code><span class='Function'>∾</span></code> would automatically enclose them, but would fail if <code><span class='Value'>𝕩</span></code> contained non-atom elements such as strings.</p> +<p>Now <a href="rank.html">Cells</a> (<code><span class='Modifier'>˘</span></code>) splits both arguments into cells. For the <code><span class='Value'>𝕨</span></code>, a rank-2 array, these cells are lists; for the list <code><span class='Value'>𝕩</span></code> they have to be units. Treating them as elements would work in this case, because <code><span class='Function'>∾</span></code> would automatically enclose them, but would fail if <code><span class='Value'>𝕩</span></code> contained non-atom elements such as strings.</p> <p>The other use of <code><span class='Function'><</span></code> in the original example is <code><span class='Paren'>(</span><span class='Function'><</span><span class='Bracket'>⟨⟩</span><span class='Paren'>)</span></code>, which is the left argument to the function <code><span class='Function'><</span><span class='Modifier2'>⊸</span><span class='Function'>∾</span><span class='Modifier'>⌜´</span></code>. Let's break that function down. We said <code><span class='Function'><</span><span class='Modifier2'>⊸</span><span class='Function'>∾</span></code> joins <code><span class='Value'>𝕨</span></code> as an element to the front of <code><span class='Value'>𝕩</span></code>. With <a href="map.html#table">Table</a> we have <code><span class='Function'><</span><span class='Modifier2'>⊸</span><span class='Function'>∾</span><span class='Modifier'>⌜</span></code>, which takes two array arguments and does this for every pair of elements from them.</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=InJlZCLigL8iYmx1ZSLigL8iZ3JlZW4iIDziirjiiL7ijJwg4p+oInVwIuKfqeKAv+KfqCJkb3duIuKfqQ==">↗️</a><pre> <span class='String'>"red"</span><span class='Ligature'>‿</span><span class='String'>"blue"</span><span class='Ligature'>‿</span><span class='String'>"green"</span> <span class='Function'><</span><span class='Modifier2'>⊸</span><span class='Function'>∾</span><span class='Modifier'>⌜</span> <span class='Bracket'>⟨</span><span class='String'>"up"</span><span class='Bracket'>⟩</span><span class='Ligature'>‿</span><span class='Bracket'>⟨</span><span class='String'>"down"</span><span class='Bracket'>⟩</span> ┌─ diff --git a/docs/doc/index.html b/docs/doc/index.html index f05f080b..5eea719e 100644 --- a/docs/doc/index.html +++ b/docs/doc/index.html @@ -49,6 +49,7 @@ <li><a href="assert.html">Assert and Catch: <code><span class='Function'>!</span></code> and <code><span class='Modifier2'>⎊</span></code></a></li> <li><a href="compose.html">Atop and Over: <code><span class='Modifier2'>∘○</span></code></a></li> <li><a href="hook.html">Before and After: <code><span class='Modifier2'>⊸⟜</span></code></a></li> +<li><a href="rank.html">Cells and Rank: <code><span class='Modifier'>˘</span><span class='Modifier2'>⎉</span></code></a></li> <li><a href="choose.html">Choose: <code><span class='Modifier2'>◶</span></code></a></li> <li><a href="constant.html">Constant: <code><span class='Modifier'>˙</span></code></a></li> <li><a href="reshape.html">Deshape and Reshape: <code><span class='Function'>⥊</span></code></a></li> diff --git a/docs/doc/primitive.html b/docs/doc/primitive.html index 84ee299e..157c05bc 100644 --- a/docs/doc/primitive.html +++ b/docs/doc/primitive.html @@ -493,7 +493,7 @@ <tbody> <tr> <td><code><span class='Modifier'>˘</span></code></td> -<td>Cells</td> +<td><a href="rank.html">Cells</a></td> <td><code><span class='Modifier2'>⎉</span></code></td> <td><a href="https://aplwiki.com/wiki/Rank_(operator)">Rank</a></td> </tr> diff --git a/docs/doc/rank.html b/docs/doc/rank.html new file mode 100644 index 00000000..fd618d93 --- /dev/null +++ b/docs/doc/rank.html @@ -0,0 +1,94 @@ +<head> + <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/> + <link href="../style.css" rel="stylesheet"/> + <title>BQN: Cells and Rank</title> +</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="cells-and-rank"><a class="header" href="#cells-and-rank">Cells and Rank</a></h1> +<p>The Cells modifier <code><span class='Modifier'>˘</span></code> applies a function to major cells of its argument, much like <a href="map.html">Each</a> applies to elements. Each result from <code><span class='Function'>𝔽</span></code> becomes a major cell of the result, which means they must all have the same shape.</p> +<p>The Rank modifier <code><span class='Modifier2'>⎉</span></code> generalizes this concept by allowing numbers provided by <code><span class='Function'>𝔾</span></code> to specify a rank for each argument: non-negative to indicate the rank of each array passed to <code><span class='Function'>𝔽</span></code>, or negative for the number of axes that are mapped over. Cells, which maps over one axis of each argument, is identical to <code><span class='Modifier2'>⎉</span><span class='Number'>¯1</span></code>. Rank is analogous to the <a href="depth.html#the-depth-modifier">Depth modifier</a>, but the homogeneous structure of an array eliminates some tricky edge cases found in Depth.</p> +<h2 id="cells"><a class="header" href="#cells">Cells</a></h2> +<p>The function Cells (<code><span class='Modifier'>˘</span></code>) is named after <em>major cells</em> in an array. A major cell is a component of an array with dimension one smaller, so that the major cells of a list are <a href="enclose.html#whats-a-unit">units</a>, the major cells of a rank-2 table are its rows (which are lists), and the major cells of a rank-3 array are tables.</p> +<p>The function <code><span class='Function'>𝔽</span><span class='Modifier'>˘</span></code> applies <code><span class='Function'>𝔽</span></code> to the major cells of <code><span class='Value'>𝕩</span></code>. So, for example, where <a href="shift.html">Nudge</a> (<code><span class='Function'>»</span></code>) shifts an entire table, Nudge Cells shifts its major cells, or rows.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=YSDihpAgJ2EnICsgM+KAv+KImCDipYog4oaVMjQgICMgQSBjaGFyYWN0ZXIgYXJyYXkKCuKfqCAgYSAgICAgICwgICAgIMK7YSAgICAgLCAgICDCu8uYYSDin6k=">↗️</a><pre> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='String'>'a'</span> <span class='Function'>+</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Modifier2'>∘</span> <span class='Function'>⥊</span> <span class='Function'>↕</span><span class='Number'>24</span> <span class='Comment'># A character array +</span> + <span class='Bracket'>⟨</span> <span class='Value'>a</span> <span class='Separator'>,</span> <span class='Function'>»</span><span class='Value'>a</span> <span class='Separator'>,</span> <span class='Function'>»</span><span class='Modifier'>˘</span><span class='Value'>a</span> <span class='Bracket'>⟩</span> +┌─ +· ┌─ ┌─ ┌─ + ╵"abcdefgh ╵" ╵" abcdefg + ijklmnop abcdefgh ijklmno + qrstuvwx" ijklmnop" qrstuvw" + ┘ ┘ ┘ + ┘ +</pre> +<p>What's it mean for Nudge to shift the "entire table"? The block above shows that is shifts downward, but what's really happening is that Nudge treats <code><span class='Value'>𝕩</span></code> as a collection of major cells—its rows—and shifts these. So it adds an entire row and moves the rest of the rows downwards. Nudge Cells appears similar, but it's acting independently on each row, and the values that it moves around are major cells of the row, that is, rank-0 units.</p> +<p>Here's an example showing how Cells can be used to shift each row independently, even though it's not possible to shift columns like this (in fact the best way to would be to <a href="transpose.html">transpose</a> in order to work on rows). It uses the not-yet-introduced dyadic form of Cells, so you might want to come back to it after reading the next section.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKGkSLiiJjiiJgiKSDiipHiirjCu8uYIGE=">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>↑</span><span class='String'>"∘∘"</span><span class='Paren'>)</span> <span class='Function'>⊑</span><span class='Modifier2'>⊸</span><span class='Function'>»</span><span class='Modifier'>˘</span> <span class='Value'>a</span> +┌─ +╵"abcdefgh + ∘ijklmno + ∘∘qrstuv" + ┘ +</pre> +<p>You can also see how Cells splits its argument into rows using a less array-oriented primitive: <a href="enclose.html">Enclose</a> just wraps each row up so that it appears as a separate element in the final result.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=PMuYIGE=">↗️</a><pre> <span class='Function'><</span><span class='Modifier'>˘</span> <span class='Value'>a</span> +⟨ "abcdefgh" "ijklmnop" "qrstuvwx" ⟩ +</pre> +<p>Enclose also comes in handy for the following task: join the rows in an array of lists, resulting in an array where each element is a joined row. The obvious guess would be "join cells", <code><span class='Function'>∾</span><span class='Modifier'>˘</span></code>, but it doesn't work, because each <code><span class='Function'>∾</span></code> can return a result with a different length. Cells tries to make each result of <code><span class='Function'>∾</span></code> into a <em>cell</em>, when the problem was to use it as an <em>element</em>. But a 0-cell is an enclosed element, so we can close the gap by applying <code><span class='Function'><</span></code> to a joined list: <code><span class='Function'><</span><span class='Modifier2'>∘</span><span class='Function'>∾</span></code>.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIHMg4oaQICJ3b3JkcyLigL8iZ28i4oC/ImhlcmUiIOKJjSAic29tZSLigL8ib3RoZXIi4oC/IndvcmRzIgoK4oi+y5ggcwoKPOKImOKIvsuYIHM=">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>s</span> <span class='Gets'>←</span> <span class='String'>"words"</span><span class='Ligature'>‿</span><span class='String'>"go"</span><span class='Ligature'>‿</span><span class='String'>"here"</span> <span class='Function'>≍</span> <span class='String'>"some"</span><span class='Ligature'>‿</span><span class='String'>"other"</span><span class='Ligature'>‿</span><span class='String'>"words"</span> +┌─ +╵ "words" "go" "here" + "some" "other" "words" + ┘ + + <span class='Function'>∾</span><span class='Modifier'>˘</span> <span class='Value'>s</span> +<span class='Error'>Error: >: Elements didn't have equal shapes (contained ⟨11⟩ and ⟨14⟩)</span> + + <span class='Function'><</span><span class='Modifier2'>∘</span><span class='Function'>∾</span><span class='Modifier'>˘</span> <span class='Value'>s</span> +⟨ "wordsgohere" "someotherwords" ⟩ +</pre> +<p>This approach can apply to more complicated functions as well. And because the result of <code><span class='Function'><</span></code> always has the same shape, <code><span class='Bracket'>⟨⟩</span></code>, the function <code><span class='Function'><</span><span class='Modifier2'>∘</span><span class='Function'>𝔽</span><span class='Modifier'>˘</span></code> can never have a shape agreement error. So if <code><span class='Function'>𝔽</span><span class='Modifier'>˘</span></code> fails, it can't hurt to check <code><span class='Function'><</span><span class='Modifier2'>∘</span><span class='Function'>𝔽</span><span class='Modifier'>˘</span></code> and see what results <code><span class='Function'>𝔽</span></code> is returning.</p> +<h3 id="two-arguments"><a class="header" href="#two-arguments">Two arguments</a></h3> +<p>When given two arguments, Cells tries to pair their cells together. Starting simple, a unit array on either side will be paired with every cell of the other argument (and an atom is converted to an array).</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=J+KImCcgwrvLmCBh">↗️</a><pre> <span class='String'>'∘'</span> <span class='Function'>»</span><span class='Modifier'>˘</span> <span class='Value'>a</span> +┌─ +╵"∘abcdefg + ∘ijklmno + ∘qrstuvw" + ┘ +</pre> +<p>If you <em>want</em> to use this one-to-many behavior with an array, it'll take more work: since you're really only mapping over one argument, <a href="hook.html">bind</a> the other inside Cells.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IuKImOKImCIgwrvLmCBhCgoi4oiY4oiYIuKKuMK7y5ggYQ==">↗️</a><pre> <span class='String'>"∘∘"</span> <span class='Function'>»</span><span class='Modifier'>˘</span> <span class='Value'>a</span> +<span class='Error'>Error: ˘: Leading axis of arguments not equal (⟨2⟩ ≡ ≢𝕨, 3‿8 ≡ ≢𝕩)</span> + + <span class='String'>"∘∘"</span><span class='Modifier2'>⊸</span><span class='Function'>»</span><span class='Modifier'>˘</span> <span class='Value'>a</span> +┌─ +╵"∘∘abcdef + ∘∘ijklmn + ∘∘qrstuv" + ┘ +</pre> +<p>This is because the general case of Cells does one-to-one matching, pairing the first axis of one argument with the other. For this to work, the two arguments need to have the same length.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oICIwMTIiIMK7y5ggYSwgICgz4oC/4oiY4qWKIlVWV1hZWiIpIMK7y5ggYSDin6k=">↗️</a><pre> <span class='Bracket'>⟨</span> <span class='String'>"012"</span> <span class='Function'>»</span><span class='Modifier'>˘</span> <span class='Value'>a</span><span class='Separator'>,</span> <span class='Paren'>(</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Modifier2'>∘</span><span class='Function'>⥊</span><span class='String'>"UVWXYZ"</span><span class='Paren'>)</span> <span class='Function'>»</span><span class='Modifier'>˘</span> <span class='Value'>a</span> <span class='Bracket'>⟩</span> +┌─ +· ┌─ ┌─ + ╵"0abcdefg ╵"UVabcdef + 1ijklmno WXijklmn + 2qrstuvw" YZqrstuv" + ┘ ┘ + ┘ +</pre> +<p>The arguments might have different ranks: for example, <code><span class='String'>"012"</span></code> has rank 1 and <code><span class='Value'>a</span></code> has rank 2 above. That's fine: it just means Cells will pass arguments of rank 0 and 1 to its operand. You can see these arguments using <a href="pair.html">Pair</a> Cells, <code><span class='Function'>⋈</span><span class='Modifier'>˘</span></code>, so that each cell of the result is just a list of the two arguments used for that call.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=IjAxMiIg4ouIy5ggYQ==">↗️</a><pre> <span class='String'>"012"</span> <span class='Function'>⋈</span><span class='Modifier'>˘</span> <span class='Value'>a</span> +┌─ +╵ ┌· "abcdefgh" + ·'0' + ┘ + ┌· "ijklmnop" + ·'1' + ┘ + ┌· "qrstuvwx" + ·'2' + ┘ + ┘ +</pre> |
