aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2021-07-16 18:23:52 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2021-07-16 18:24:01 -0400
commit2010e8b2897a5741e211980c9f8ec9177299c939 (patch)
tree4b3476744be928724da2fd5d83b0bf2e9a8ba502 /doc
parente3366f9e18a8791c43110e080b9ea45cfceefed8 (diff)
Finish links and editing documentation pass
Diffstat (limited to 'doc')
-rw-r--r--doc/reverse.md10
-rw-r--r--doc/scan.md10
-rw-r--r--doc/select.md12
-rw-r--r--doc/selfcmp.md12
-rw-r--r--doc/shape.md6
-rw-r--r--doc/shift.md24
-rw-r--r--doc/train.md14
-rw-r--r--doc/transpose.md27
-rw-r--r--doc/types.md10
-rw-r--r--doc/windows.md19
10 files changed, 78 insertions, 66 deletions
diff --git a/doc/reverse.md b/doc/reverse.md
index 0ee7766d..e1e85d46 100644
--- a/doc/reverse.md
+++ b/doc/reverse.md
@@ -2,7 +2,7 @@
# Reverse and Rotate
-The symbol `⌽` indicates two different array transformations: with no left argument, it reverses the major cells of the array, but with a left argument, it rotates or cycles them around. These two possibilities, first put together in very early versions of APL, can't be considered restrictions or different views of some unifying function, but there are connections between them. Each returns an array with the same shape and all the same elements as `ð•©`, possibly in a different arrangement. And elements that start out next to each other in `ð•©` generally stay next to each other—always, if we consider an element on one edge to be next to the one opposite to it. One might think of them as [isometries](https://en.wikipedia.org/wiki/Isometry) preserving a discrete subgroup of the torus, if one were inclined to think such things. On major cells, the two functions decompose the [dihedral group](https://en.wikipedia.org/wiki/Dihedral_group) okay I'll stop.
+The symbol `⌽` indicates two different array transformations: with no left argument, it reverses the major cells of the array, but with a left argument, it rotates or cycles them around. These two possibilities, first put together in very early versions of APL, can't be considered restrictions or different views of some unifying function, but there are connections between them. Each returns an array with the same [shape](shape.md) and all the same elements as `ð•©`, possibly in a different arrangement. And elements that start out next to each other in `ð•©` generally stay next to each other—always, if we consider an element on one edge to be next to the one opposite to it. One might think of them as [isometries](https://en.wikipedia.org/wiki/Isometry) preserving a discrete subgroup of the torus, if one were inclined to think such things. On major cells, the two functions decompose the [dihedral group](https://en.wikipedia.org/wiki/Dihedral_group) okay I'll stop.
Many uses of Rotate in APL are better handled by [shift](shift.md) functions in BQN. If there's no reason to treat the data as cyclic or periodic, it's best to avoid Rotate.
@@ -36,7 +36,7 @@ Reverse is its own inverse `⌽â¼`. As a result, `ð”½âŒ¾âŒ½` reverses the argu
## Rotate
-Rotate moves elements in a list around cyclically. It can also rotate any number of axes of the argument array by different amounts at once. That's discussed in the next section; for now we'll stick to a single number in the left argument. It has to be an integer, and the right argument has to be an array with at least one axis.
+Rotate moves elements in a list around cyclically. It can also rotate any number of axes of the argument array by different amounts at once. That's discussed in the next section; for now we'll stick to a single number for `ð•¨`. It has to be an integer, and `ð•©` has to be an array with at least one axis.
2 ⌽ "rotate"
@@ -44,13 +44,13 @@ Rotate moves elements in a list around cyclically. It can also rotate any number
2 ⌽ 'c' # No axes to rotate
-Elements are always rotated to the left, so that entry `i` of the result is entry `ð•¨+i` of the argument—or rather, entry `(≠ð•©)|ð•¨+i` to enable elements to cycle around. This can be seen directly by using `↕n` as an argument: in this case, the value of `ð•©` at index `i` is just `i`.
+Elements are always rotated to the left, so that entry `i` of the result is entry `ð•¨+i` of the argument—or rather, entry `(≠ð•©)|ð•¨+i` to enable elements to cycle around. This can be seen directly by using the [range](range.md) `↕n` as an argument: then the value of `ð•©` at index `i` is just `i`.
2 ⌽ ↕6
-The rotation `(≠ð•©)⌽ð•©` moves each element the entire length of `ð•©`, which just places it back where it started. In fact, adding `≠ð•©` to the rotation amount never changes the behavior or the rotation. In terms of indices, this is because `(≠ð•©)|(≠ð•©)+a` is `a`.
+The rotation `(≠ð•©)⌽ð•©` moves each element the entire [length](shape.md) of `ð•©`, which just places it back where it started. In fact, adding `≠ð•©` to the rotation amount never changes the behavior or the rotation. In terms of indices, this is because `(≠ð•©)|(≠ð•©)+a` is `a`.
-To rotate the other way, use a negative left argument (so `-⊸⌽` is a simple way to write "reverse rotate"). This will always be the same as a leftwards rotation, since `(-r)⌽ð•©` is `((≠ð•©)-r)⌽ð•©`, but could be more convenient.
+To rotate the other way, use a negative left argument (so `-⊸⌽` is a simple way to write "reverse rotate"). This will always be the same as some leftwards rotation, since `(-r)⌽ð•©` is `((≠ð•©)-r)⌽ð•©`, but could be more convenient.
¯2 ⌽ "rotate"
diff --git a/doc/scan.md b/doc/scan.md
index c4e3a3ad..85758875 100644
--- a/doc/scan.md
+++ b/doc/scan.md
@@ -46,9 +46,9 @@ dim ↠⟨2.5+≠tx,0.75+1⊑ty⟩ ⋄ sh ↠¯2.3‿0
The 1-modifier Scan (`` ` ``) moves along the first axis of the array `ð•©`, building up an array of results by applying `ð”½` repeatedly beginning with `ð•¨` or `âŠð•©`. It's related to the fold modifiers, and most closely resembles the [APL2-style reduction](fold.md#apl2-reduction) `¨Ë`, but it traverses the array in forward rather than reverse index order, and includes all intermediate results of `ð”½` in its output instead of just the final one.
-BQN's Scan is ordered differently from Scan in APL. Both include one result for each non-empty prefix of `ð•©`. In BQN this is a left-to-right fold, so that each new result requires one application of `ð”½`. APL uses a right-to-left ordering, which matches with reduction, but requires starting over at the end for each new prefix, except in special cases. If needed, this definition can be obtained with a fold on each [prefix](prefixes.md) except the first (which is empty). In the particular case of `-â€`, that nested solution isn't needed: negate odd-indexed elements and then apply `` +` ``.
+BQN's Scan is ordered differently from Scan in APL. Both include one result for each non-empty prefix of `ð•©`. In BQN this is a left-to-right fold, so that each new result requires one application of `ð”½`. APL uses right-to-left folds, which matches with reduction, but requires starting over at the end for each new prefix, except in special cases. If needed, this definition can be obtained with a fold on each [prefix](prefixes.md) except the first (which is empty). In the particular case of `-â€`, that nested solution isn't needed: negate odd-indexed elements and then apply `` +` ``.
-Scan also differs from Fold or Insert in that it never depends on `ð”½`'s identity element, because scanning over an empty array simply returns that array.
+Scan also differs from Fold or Insert in that it never depends on `ð”½`'s [identity value](fold.md#identity-values), because scanning over an empty array simply returns that array.
## Lists
@@ -58,7 +58,7 @@ The best-known use of Scan is the [prefix sum](https://en.wikipedia.org/wiki/Pre
+`»2‿4‿3‿1 # Exclusive prefix sum
-The pattern is generalized to any function `ð”½`. With an operand of `×`, it can find the first *n* factorials. With `⌈`, it returns the largest element so far.
+The pattern is generalized to any function `ð”½`. With an operand of `×`, it can find the first *n* factorials. With [Maximum](arithmetic.md#additional-arithmetic) (`⌈`), it returns the largest element so far.
×` 1+↕6
@@ -80,7 +80,7 @@ The left argument in each result element is always the previous element, if ther
{c+↩1â‹„ð•¨+ð•©}` ↕10
c
-Some other useful scans apply to boolean lists. The function `` ∨` `` tests whether this or any previous element is 1, so that the result starts at 0 but permanently switches to 1 as soon as the first 1 is found. Similarly, `` ∧` `` turns all instances of 1 after the first 0 to 0.
+Some other useful scans apply to boolean lists. The function `` ∨` `` (with [Or](logic.md)) tests whether this or any previous element is 1, so that the result starts at 0 but permanently switches to 1 as soon as the first 1 is found. Similarly, `` ∧` `` turns all instances of 1 after the first 0 to 0.
∨` 0‿0‿1‿0‿0‿1‿0‿1
@@ -94,7 +94,7 @@ A more complicated boolean scan, which depends on the left-to-right ordering, is
## Reverse scan
-We've discussed how the scan moves forward along `ð•©`, so that each time `ð”½` takes an old result as `ð•¨` and a new value as `ð•©`. This means that results correspond to prefixes and go left to right on each one. Since the most important scans have associative, commutative operands, the left-to-right ordering often doesn't make a difference. But sometimes a suffix rather than prefix scan is wanted. For these cases, Scan Under [Reverse](reverse.md) (`` `⌾⌽ ``) does the trick.
+We've discussed how the scan moves forward along `ð•©`, so that each time `ð”½` takes an old result as `ð•¨` and a new value as `ð•©`. This means that results correspond to [prefixes](prefixes.md) and go left to right on each one. Since the most important scans have associative, commutative operands, the left-to-right ordering often doesn't make a difference. But sometimes a suffix rather than prefix scan is wanted. For these cases, Scan Under [Reverse](reverse.md) (`` `⌾⌽ ``) does the trick.
∨` 0‿0‿1‿0‿0‿1‿0
diff --git a/doc/select.md b/doc/select.md
index c9da2304..c9ed2765 100644
--- a/doc/select.md
+++ b/doc/select.md
@@ -32,7 +32,7 @@ tp ↠(1‿2/tx‿tw) â‰Â¨Â¨ y
⟩
-->
-The function Select (`âŠ`) reorganizes the array `ð•©` along one or more axes based on [indices](indices.md) given by `ð•¨`. The result has the same [depth](depth.md) as `ð•©`, since its elements are always elements of `ð•©`. This means it differs from Pick (`⊑`), which takes elements from `ð•©` but can arrange them in any nested structure, including returning an element directly.
+The function Select (`âŠ`) reorganizes the array `ð•©` along one or more axes based on [indices](indices.md) given by `ð•¨`. The result has the same [depth](depth.md) as `ð•©`, since its elements are always elements of `ð•©`. This means it differs from [Pick](pick.md) (`⊑`), which takes elements from `ð•©` but can arrange them in any nested structure, including returning an element directly.
The monadic form First Cell (`âŠ`) gets the major cell with index 0, so that `âŠð•©` is identical to `0âŠð•©`.
@@ -80,7 +80,9 @@ To find the first and last cells of `ð•©`, use `0‿¯1` for the left argument.
0‿¯1 ⊠m
-More generally, `ð•¨` can be an array of any rank. Each of its 0-cells—containing a single number—is replaced with a cell of `ð•©` in the result. The result's shape is then made up of the shape of `ð•¨` and the major cell shape of `ð•©`: it's `(≢ð•¨)∾1↓≢ð•©`. When `ð•©` is a list, the result has the same shape as `ð•¨`. Elements of `ð•¨` are replaced one-for-one with elements of `ð•©`.
+More generally, `ð•¨` can be an array of any rank. Each of its 0-cells—containing a single number—is replaced with a cell of `ð•©` in the result. The result's shape is then made up of the shape of `ð•¨` and the major cell shape of `ð•©`: it's `(≢ð•¨)∾1↓≢ð•©`.
+
+When `ð•©` is a list, the result has the same shape as `ð•¨`. Elements of `ð•¨` are replaced one-for-one with elements of `ð•©`.
2|m
@@ -102,9 +104,9 @@ Select also allows `ð•¨` to apply to multiple axes of `ð•©` simultaneously. Fo
⟨2‿1, 3‿0‿0⟩ ⊠↕3‿4
-Using a [range](range.md) for `ð•©` shows the structure of the selected elements more clearly, because each element is its own index. Each element of `ð•¨` acts independently, giving a structure like the Table modifier.
+Using a [range](range.md) for `ð•©` shows the structure of the selected elements more clearly, because each element is its own index. Each element of `ð•¨` acts independently, giving a structure like the [Table](map.md#table) modifier.
-While `ð•¨` must have rank one or less, its elements can have any rank. When the elements are units, the corresponding axis of `ð•©` disappears from the result. We can select a 0-cell of `ð•©` in this way, although the more common case or selecting an element is handled by Pick.
+While `ð•¨` must have rank one or less, its elements can have any rank. When the elements are units, the corresponding axis of `ð•©` disappears from the result. We can select a 0-cell of `ð•©` in this way, although the more common case of selecting an element is handled by [Pick](pick.md).
⟨<4,<5,<1⟩ ⊠(3⥊10)⥊↕1e3
⟨ 4, 5, 1⟩ ⊑ (3⥊10)⥊↕1e3
@@ -115,4 +117,4 @@ However, the `<¨⊸âŠ` construct can select a cell of any rank from `ð•©`, be
If an element of `ð•¨` has rank more than 1, it increases the rank of `ð•©` rather than decreasing it. The general rule is that in the result, one axis of `ð•©` is replaced by all the axes of the corresponding element of `ð•¨` (trailing axes are unchanged). So the final shape `≢ð•¨âŠð•©` is `(∾≢¨ð•¨)∾ð•¨â‰ âŠ¸â†“â‰¢ð•©`. But this shape doesn't affect the elements retrieved from `ð•©`. In all cases, using `⥊¨ð•¨` for the left argument and then [reshaping](reshape.md) the result would yield the same value.
-Selection only ever applies to leading axes of `ð•©`. But you can skip some leading axes using `˘` or `⎉`, to select on any contiguous set of axes. In particular, use the one-axis case `ð•¨âЏâŠâމ(-k) ð•©` to select along axis `k` of `ð•©`.
+Selection only ever applies to leading axes of `ð•©`. However, you can skip some leading axes using `˘` or `⎉`, to select on any contiguous set of axes. In particular, use the one-axis case `ð•¨âЏâŠâމ(-k) ð•©` to select along axis `k` of `ð•©`.
diff --git a/doc/selfcmp.md b/doc/selfcmp.md
index e4f1616c..e4330dd9 100644
--- a/doc/selfcmp.md
+++ b/doc/selfcmp.md
@@ -75,7 +75,7 @@ Classify is also related to [Deduplicate](#deduplicate). In a way they are compl
ⷠ⊠c
⊠ⷠc
-Applying both separately, in contrast, gives completely interesting results. These results contain all information from the original argument, as `â·` indicates which cells it contained and `âŠ` indicates where they were located. The function Select (`âŠ`) reconstructs the argument from the two values.
+Applying both separately, in contrast, gives completely interesting results. These results contain all information from the original argument, as `â·` indicates which cells it contained and `âŠ` indicates where they were located. The function [Select](select.md) (`âŠ`) reconstructs the argument from the two values.
â· c
⊠c
@@ -89,15 +89,15 @@ Applying both Classify and Deduplicate gives an array that has both properties (
*See the [APL Wiki page](https://aplwiki.com/wiki/Unique_Mask) on this function as well.*
-Mark Firsts (`∊`) is the simplest self-search function: it returns `0` for any major cell of the argument that is a duplicate of an earlier cell and `1` for a major cell that's the first with its value. To implement [Deduplicate](#deduplicate) in terms of Mark Firsts, just filter out the duplicates with `∊⊸/`.
+Mark Firsts (`∊`) is the simplest self-search function: it returns `0` for any major cell of the argument that is a duplicate of an earlier cell and `1` for a major cell that's the first with its value. To implement [Deduplicate](#deduplicate) in terms of Mark Firsts, just [filter](replicate.md) out the duplicates with `∊⊸/`.
∊ 3‿1‿4‿1‿5‿9‿2‿6‿5
∊⊸/ 3‿1‿4‿1‿5‿9‿2‿6‿5
-Mark Firsts has other uses, of course. Instead of keeping the unique values, you might remove the first of each value with `¬∘∊⊸/`. You can use `∧´∊` to check that an array has no duplicate major cells, or `+´∘∊` to count the number of unique ones.
+Mark Firsts has other uses, of course. Instead of keeping the unique values, you might remove the first of each value with `¬∘∊⊸/`. You can use `∧´∊` to check that an array has no duplicate major cells, or `+´∊` to count the number of unique ones.
-What about marking the elements that appear exactly once? There's a trick for this: find the cells that are firsts running both forwards (`∊`) and backwards (`∊⌾⌽`). Such a cell has no equal before it, nor after it, so it's unique in the entire array.
+What about marking the elements that appear exactly once? There's a trick for this: find the cells that are firsts running both forwards (`∊`) and [backwards](reverse.md) (`∊⌾⌽`). Such a cell has no equal before it, nor after it, so it's unique in the entire array.
(∊∧∊⌾⌽) "duck"‿"duck"‿"teal"‿"duck"‿"goose"
@@ -121,11 +121,11 @@ One easy example with Occurrence count is to take a list that has duplicates and
(1=⊒)⊸/ "aaaabcddcc"
-An interesting combination is Occurrence Count applied to the result of Indices (`/`). The result counts up to each number from the argument in turn; in other symbols, it's `∾↕¨`. This version is interesting because it doesn't create any nested arrays, just lists of natural numbers.
+An interesting combination is Occurrence Count applied to the result of [Indices](replicate.md#indices) (`/`). The result counts up to each number from the argument in turn; in other symbols, it's `∾↕¨`. This version is interesting because it doesn't create any nested arrays, just lists of natural numbers.
⊒ / 2‿3‿4
-A more efficient way when the interpreter doesn't optimize `⊒` here is `` /(¯1⊸⊑↕⊸-âŠâŸœÂ»)+` ``, but that's clearly quite a bit more complicated.
+A more efficient way when `⊒` doesn't have a fast implementation is `` /(¯1⊸⊑↕⊸-âŠâŸœÂ»)+` ``, but that's clearly quite a bit more complicated.
### Deduplicate
diff --git a/doc/shape.md b/doc/shape.md
index 1cb98d46..4c45280f 100644
--- a/doc/shape.md
+++ b/doc/shape.md
@@ -8,7 +8,7 @@ Rank can be defined as `≠∘≢` while Length can be defined with a [fold](fol
## Examples
-The function [Reshape](reshape.md) (`⥊`) always returns an array of shape `ð•¨`, so we use it to make an array of shape `1‿3‿2‿6` in the example below ([Take](take.md) (`↑`) shares this property).
+The function [Reshape](reshape.md) (`⥊`) always returns an array of shape `ð•¨`, so we use it to make an array of shape `1‿3‿2‿6` in the example below ([Take](take.md) (`↑`) shares this property if `(≠ð•¨)≤=ð•©`).
⊢ arr ↠1‿3‿2‿6 ⥊ '0'+↕10
@@ -18,11 +18,11 @@ The function [Reshape](reshape.md) (`⥊`) always returns an array of shape `ð•
= arr # Rank
-The length is the first element of the shape, and the rank is the length of the shape—the number of axes. For another example, taking the first (and only) cell of `arr` gives an array with shape `3‿2‿6`, length `3`, and rank `3`, as we can see by applying each function to `âŠarr`.
+The length is the first element of the shape, and the rank is the length of the shape—the number of axes. For another example, taking the first (and only) cell of `arr` gives an array with shape `3‿2‿6`, length `3`, and rank `3`, as we can see by applying [each](map.md#each) function to `âŠarr`.
≢‿=‿≠ {ð•Žð•©}¨< âŠarr
-Applying Shape and the other two functions to an atom shows a shape of `⟨⟩`, the empty list, and a rank of zero and length of 1. The same is true of an enclosed array, which like an atom is a kind of unit.
+Applying Shape and the other two functions to an atom shows a shape of `⟨⟩` (the empty list), and a rank of zero and length of 1. The same is true of an enclosed array, which like an atom is a kind of unit.
≢ 5
diff --git a/doc/shift.md b/doc/shift.md
index 13c388cc..d20d4eff 100644
--- a/doc/shift.md
+++ b/doc/shift.md
@@ -2,9 +2,9 @@
# Shift functions
-The shift functions `«` and `»` are two new primitives added to BQN based on a pattern used heavily in the compiler and a reasonable amount everywhere else. Shifts resemble but are more general than the bit-based shift operations used in low-level languages. They replace the APL pattern of a 2-wise reduction after appending or prepending an element (APL's `2≠/0,v` translates to `»⊸≠v`), one of the more common uses of 2-wise reduction.
+The shift functions `«` and `»` add major cells to one side an array, displacing cells on the opposite side and moving those in between. Shifts resemble but are more general than the bit-based shift operations used in low-level languages. They replace the APL pattern of a 2-wise reduction after appending or prepending an element (APL's `2≠/0,v` translates to `»⊸≠v`), one of the more common uses of 2-wise reduction.
-The result of a shift function always has the same shape as its right argument. The function adds major cells to the beginning (`»`) or end (`«`) of `ð•©`, moving the cells already in `ð•©` to accomodate them. Some cells on the opposite side from those added will "fall off" and not be included in the result.
+The result of a shift function always has the same shape as `ð•©`. The function adds major cells to the beginning (`»`) or end (`«`) of `ð•©`, moving the cells already in `ð•©` to accomodate them. Some cells on the opposite side from those added will "fall off" and not be included in the result.
0‿0 » 3‿2‿1 # Shift Before
"end" « "add to the " # Shift After
@@ -18,7 +18,7 @@ If `ð•¨` is longer than `ð•©`, some cells from `ð•¨` will be discarded, as we
## Sequence processing with shifts
-When working with a sequence of data such as text, daily measurements, or audio data, shift functions are generally the best way to handle the concept of "next" or "previous" in the data. In the following example `s` is shown alongside the shifted-right data `»s`, and each element is compared to the previous with `-⟜»`, which we see is the inverse of `` +` ``.
+When working with a sequence of data such as text, daily measurements, or audio data, shift functions are generally the best way to handle the concept of "next" or "previous". In the following example `s` is shown alongside the shifted-right data `»s`, and each element is compared to the previous with `-⟜»`, which we see is the inverse of Plus [Scan](scan.md) `` +` ``.
s ↠1‿2‿2‿4‿3‿5‿6
s ≠»s
@@ -29,6 +29,7 @@ When working with a sequence of data such as text, daily measurements, or audio
In this way `»` refers to a sequence containing the previous element at each position. By default the array's fill is used for the element before the first, and a right argument can be given to provide a different one.
∞ » s
+
âŠâŠ¸Â» s
It may appear backwards that `»`, which typically means "go to the next item", is used to represent the previous item. In fact there is no conflict: the symbol `»` describes what position each cell of `ð•©` will have in the result, but in this context we are interested in knowing what argument value occurs in a particular result position. By moving all numbers into the future we ensure that a number in the present comes from the past. To keep your intuition functioning in these situations, it may help to think of the arrow point as fixed at some position in the result while the tail stretches back to land on the argument position where it comes from.
@@ -64,15 +65,17 @@ With a number in big-endian format, a right shift might be logical, shifting in
## Other examples
-In Take (`↑`), there's no way to specify the fill element when the result is longer than the argument. To take along the first axis with a specified, constant fill value, you can use Shift Before instead, where the right argument is an array of fills with the desired final shape.
+In [Take](take.md) (`↑`), there's no way to specify the fill element when the result is longer than the argument. To take along the first axis with a specified, constant fill value, you can use Shift Before instead, where the right argument is an array of fills with the desired final shape.
"abc" » 5⥊'F'
-When using Scan (`` ` ``), the result at a particular index is obtained from values up to and including the one at that index. But it's common to want to use the values up to but not including that one instead. This can be done either by joining or shifting in that value before scanning. The difference is that with Join the result is longer than the argument. Either form might be wanted depending on how it will be used.
+When using [Scan](scan.md) (`` ` ``), the result at a particular index is obtained from values up to and including the one at that index. But it's common to want to use the values up to but not including that one instead. This can be done either by [joining](join.md#join-to) or shifting in that value before scanning. The difference is that with Join the result is longer than the argument. Either form might be wanted depending on how it will be used.
+
+ 2 +` 1‿0‿1‿0 # Initial value not retained
+
+ 2 +`∘∾ 1‿0‿1‿0 # All values
- +` 1‿1‿1‿1
- 2 +`∘∾ 1‿1‿1‿1
- 2 +`∘» 1‿1‿1‿1
+ 2 +`∘» 1‿0‿1‿0 # Final value not created
The *strides* of an array are the distances between one element and the next along any given axis. It's the product of all axis lengths below that axis, since these are all the axes that have to be "skipped" to jump along the axis. The strides of an array `ð•©` are `` (×`1»⊢)⌾⌽∘≢𕩠``.
@@ -83,14 +86,17 @@ The *strides* of an array are the distances between one element and the next alo
Shifting always works on the first axis of `ð•©` (which must have rank 1 or more), and shifts in major cells. A left argument can have rank equal to `ð•©`, or one less than it, in which case it becomes a single cell of the result. With no left argument, a cell of fills `1↑0↑ð•©` is nudged in.
⊢ a ↠⥊⟜(↕×´) 4‿3
+
» a # Nudge adds a cell of fills
+
"one" « a # Shift in a cell
+
("two"â‰"cel") « a # Shift in multiple cells
## Definition
In any instance of `»` or `«`, `ð•©` must have rank at least 1.
-For a dyadic shift function, `ð•¨` must be Join-compatible with `ð•©` (that is, `ð•¨âˆ¾ð•©` completes without error) and cannot have greater rank than `ð•©`. Then Shift Before (`»`) is `{(≠ð•©)↑ð•¨âˆ¾ð•©}` and Shift After (`«`) is `{(-≠ð•©)↑ð•©âˆ¾ð•¨}`
+For a dyadic shift function, `ð•¨` must be [Join](join.md#join-to)-compatible with `ð•©` (that is, `ð•¨âˆ¾ð•©` completes without error) and cannot have greater rank than `ð•©`. Then Shift Before (`»`) is `{(≠ð•©)↑ð•¨âˆ¾ð•©}` and Shift After (`«`) is `{(-≠ð•©)↑ð•©âˆ¾ð•¨}`
When called monadically, the default argument is a cell of fills `1↑0↑ð•©`. That is, Nudge (`»`) is `(1↑0↑⊢)⊸»` and Nudge Back (`«`) is `(1↑0↑⊢)⊸«`. This default argument always satisfies the compatibility requirement above and so the only conditions for nudge are that `ð•©` has rank at least 1 and has a fill element.
diff --git a/doc/train.md b/doc/train.md
index afad29ba..4f58f454 100644
--- a/doc/train.md
+++ b/doc/train.md
@@ -2,7 +2,7 @@
# Function trains
-Trains are an important aspect of BQN's [tacit](tacit.md) programming capabilities. In fact, a crucial one: with trains and the identity functions Left (`⊣`) and Right (`⊢`), a fully tacit program can express any explicit function whose body is a statement with `ð•¨` and `ð•©` used only as arguments (that is, there are no assignments and `ð•¨` and `ð•©` are not used in operands or lists. Functions with assignments may have too many variables active at once to be directly translated but can be emulated by constructing lists. But it's probably a bad idea). Without trains it isn't possible to have two different functions that each use both arguments to a dyadic function. With trains it's perfectly natural.
+Trains are an important aspect of BQN's [tacit](tacit.md) programming capabilities. In fact, a crucial one: with trains and the [identity functions](identity.md) Left (`⊣`) and Right (`⊢`), a fully tacit program can express any explicit function whose body is a statement with `ð•¨` and `ð•©` used only as arguments (that is, there are no assignments and `ð•¨` and `ð•©` are not used in operands or lists. Functions with assignments may have too many variables active at once to be directly translated but can be emulated by constructing lists. But it's probably a bad idea). Without trains it isn't possible to have two different functions that each use both arguments to a dyadic function. With trains it's perfectly natural.
BQN's trains are the same as those of Dyalog APL, except that Dyalog is missing the minor convenience of BQN's Nothing (`·`). There are many Dyalog-based documents and videos on trains you can view on the [APL Wiki](https://aplwiki.com/wiki/Train).
@@ -22,7 +22,7 @@ Here [Couple](couple.md) (`â‰`) is used to combine two units into a list, so we
(·∾⌽) "ab"‿"cde"‿"f"
∾∘⌽ "ab"‿"cde"‿"f"
-The three functions `∾⌽`, `·∾⌽`, and `∾∘⌽` are completely identical. Why might we want **three** different ways to write the same thing? If we only want to define a function, there's hardly any difference. However, these three forms have different syntax, and might be easier or harder to use in different contexts. As we'll see, we can use `∾∘⌽` inside a train without parenthesizing it, and string `·∾⌽` but not `∾⌽` together with other trains. Let's look at how the train syntax extends to longer expressions.
+The three functions `∾⌽`, `·∾⌽`, and `∾∘⌽` are completely identical: [Join](join.md#join) of [Reverse](reverse.md). Why might we want **three** different ways to write the same thing? If we only want to define a function, there's hardly any difference. However, these three forms have different syntax, and might be easier or harder to use in different contexts. As we'll see, we can use `∾∘⌽` inside a train without parenthesizing it, and string `·∾⌽` but not `∾⌽` together with other trains. Let's look at how the train syntax extends to longer expressions.
## Longer trains
@@ -46,7 +46,7 @@ In a train, arguments alternate strictly with combining functions between them.
## Practice training
-The train `` ⊢>¯1»⌈` `` is actually a nice trick for marking first occurrences `∊ð•©` given the self-classify `âŠð•©` without doing another search. Let's take a closer look, first by applying it mechanically. To do this, we apply each "argument" to the train's argument, and then combine them with the combining functions.
+The train `` ⊢>¯1»⌈` `` is actually a nice trick to get the result of [Mark Firsts](selfcmp.md#mark-firsts) `∊ð•©` given the result of [Classify](selfcmp.md#classify) `âŠð•©`, without doing another search. Let's take a closer look, first by applying it mechanically. To do this, we apply each "argument" to the train's argument, and then combine them with the combining functions.
(⊢ > ¯1 » ⌈`) ð•©
(⊢ð•©) > (¯1) » (⌈`ð•©)
@@ -54,15 +54,15 @@ The train `` ⊢>¯1»⌈` `` is actually a nice trick for marking first occurre
So—although not all trains simplify so much—this confusing train is just `` {ð•©>¯1»⌈`ð•©} ``! Why would I write it in such an obtuse way? To someone used to working with trains, the function `` (⊢>¯1»⌈`) `` isn't any more complicated to read: `⊢` in an argument position of a train just means `ð•©` while `` ⌈` `` will be applied to the arguments. Using the train just means slightly shorter code and two fewer `ð•©`s to trip over.
-This function's argument is the self-classify `âŠ` of some list (in fact this technique also works on the self-indices `ð•©âŠð•©`). Self-classify moves along its argument, giving each major cell a number: the first unused natural number if that value hasn't been seen yet, and otherwise the number chosen when it was first seen. It can be implemented as `∊âŠâŠ¢`, another train!
+This function's argument is Classify (`âŠ`) of some list (in fact this technique also works on the [index-of](search.md#index-of)-self `ð•©âŠð•©`). Classify moves along its argument, giving each major cell a number: the first unused natural number if that value hasn't been seen yet, and otherwise the number chosen when it was first seen. It can be implemented as `â·âŠâŠ¢`, another train!
⊢ sc ↠⊠"tacittrains"
-Each `'t'` is `0`, each `'a'` is `1`, and so on. We'd like to discard some of the information in the self-classify, to just find whether each major cell had a new value. Here are the input and desired result:
+Each `'t'` is `0`, each `'a'` is `1`, and so on. We'd like to discard some of the information from Classify, to just find whether each major cell had a new value. Here are the input and desired result:
sc ≠∊ "tacittrains"
-The result should be `1` when a new number appears, higher than all the previous numbers. To do this, we first find the highest previous number by taking the maximum-scan `` ⌈` `` of the argument, then [shifting](shift.md) to move the previous maximum to the current position. The first cell is always new, so we shift in a `¯1`, so it will be less than any element of the argument.
+The result should be `1` when a new number appears, higher than all the previous numbers. To do this, we first find the highest previous number by taking the [maximum](arithmetic.md#additional-arithmetic)-[scan](scan.md) `` ⌈` `` of the argument, then [shifting](shift.md) to move the previous maximum to the current position. The first cell is always new, so we shift in a `¯1`, so it will be less than any element of the argument.
¯1 » ⌈`sc
(¯1»⌈`) sc
@@ -76,7 +76,7 @@ Now we compare the original list with the list of previous-maximums.
The example above uses a train with five functions: an odd number. Trains with an odd length are always composed of length-3 trains, and they themselves are composed the same way as subject expressions: an odd-length train can be placed in the last position of another train without parentheses, but it needs parentheses to go in any other position.
-But we also saw the length-2 train `∾⌽` above. Even-length trains consist of a single function (`∾`) applied to a function or odd-length train (`⌽`); another perspective is that an even-length train is an odd-length train where the left argument of the final (leftmost) function is left out, so it's called with only a right argument. An even-length train *always* needs parentheses if it's used as one of the functions in another train. However, it can also be turned into an odd-length train by placing `·` at the left, making the implicit missing argument explicit. After this it can be used at the end of an odd-length train without parentheses. To get some intuition for even-length trains, let's look at an example of three functions used together: the unique (`â·`) sorted (`∧`) absolute values (`|`) of an argument list.
+But we also saw the length-2 train `∾⌽` above. Even-length trains consist of a single function (`∾`) applied to a function or odd-length train (`⌽`); another perspective is that an even-length train is an odd-length train where the left argument of the final (leftmost) function is left out, so it's called with only a right argument. An even-length train *always* needs parentheses if it's used as one of the functions in another train. However, it can also be turned into an odd-length train by placing `·` at the left, making the implicit missing argument explicit. After this it can be used at the end of an odd-length train without parentheses. To get some intuition for even-length trains, let's look at an example of three functions used together: the [unique](selfcmp.md#deduplicate) (`â·`) [sorted](order.md#sort) (`∧`) [absolute values](arithmetic.md#additional-arithmetic) (`|`) of an argument list.
â·âˆ§| 3‿4‿¯3‿¯2‿0
diff --git a/doc/transpose.md b/doc/transpose.md
index ab573390..c3d0807b 100644
--- a/doc/transpose.md
+++ b/doc/transpose.md
@@ -2,7 +2,7 @@
# Transpose
-As in APL, Transpose (`â‰`) is a tool for rearranging the axes of an array. BQN's version is tweaked to align better with the leading axis model and make common operations easier.
+Transpose (`â‰`) is a tool for rearranging the axes of an array. BQN's version is tweaked relative to APL to align better with the leading axis model and make common operations easier.
## Transpose basics
@@ -22,12 +22,13 @@ With two axes the only interesting operation of this sort is to swap them (and w
APL extends matrix transposition to any rank by reversing all axes for its monadic `â‰`, but this generalization isn't very natural and is almost never used. The main reason for it is to maintain the equivalence `a MP b â†â†’ b MP⌾≠a`, where `MP ↠+Ë∘×⎉1‿∞` is the generalized matrix product. But even here APL's Transpose is suspect. It does much more work than it needs to, as we'll see.
-BQN's transpose takes the first axis of its argument and moves it to the end.
+BQN's transpose takes the first axis of `ð•©` and moves it to the end.
≢ a23456 ↠↕2‿3‿4‿5‿6
+
≢ ≠a23456
-In terms of the argument data as given by Deshape (`⥊`), this looks like a simple 2-dimensional transpose: one axis is exchanged with a compound axis made up of the other axes. Here we transpose a rank 3 matrix:
+In terms of the argument data as given by [Deshape](reshape.md#deshape) (`⥊`), this looks like a simple 2-dimensional transpose: one axis is exchanged with a compound axis made up of the other axes. Here we transpose a rank 3 matrix:
a322 ↠3‿2‿2⥊↕12
â‰â—‹<⟜≠a322
@@ -36,9 +37,10 @@ But, ignoring the whitespace and going in reading order, the argument and result
â‰â—‹<⟜≠⥊˘ a322
-To exchange multiple axes, use the Power modifier. A negative power moves axes in the other direction, just like how Rotate handles negative left arguments. In particular, to move the last axis to the front, use Undo (as you might expect, this exactly inverts `â‰`).
+To exchange multiple axes, use the [Repeat](repeat.md) modifier. A negative power moves axes in the other direction, just like how [Rotate](reverse.md#rotate) handles negative left arguments. In particular, to move the last axis to the front, use Undo (as you might expect, this exactly inverts `â‰`).
≢ â‰âŸ3 a23456
+
≢ â‰â¼ a23456
In fact, we have `≢â‰âŸk a â†â†’ k⌽≢a` for any whole number `k` and array `a`.
@@ -47,11 +49,11 @@ To move axes other than the first, use the Rank modifier in order to leave initi
≢ â‰âމ3 a23456
-And of course, Rank and Power can be combined to do more complicated transpositions: move a set of contiguous axes with any starting point and length to the end.
+And of course, Rank and Repeat can be combined to do more complicated transpositions: move a set of contiguous axes with any starting point and length to the end.
≢ â‰â¼âŽ‰Â¯1 a23456
-Using these forms, we can state BQN's generalized matrix product swapping rule:
+Using these forms (and the [Rank](shape.md) function), we can state BQN's generalized matrix product swapping rule:
a MP b â†â†’ â‰âŸ(1-=a) (â‰b) MP (â‰â¼a)
@@ -65,20 +67,21 @@ In a case like this BQN's Dyadic transpose is much easier.
## Dyadic Transpose
-Transpose also allows a left argument that specifies a permutation of the right argument's axes. For each index `pâ†iâŠð•¨` in the left argument, axis `i` of the argument is used for axis `p` of the result. Multiple argument axes can be sent to the same result axis, in which case that axis goes along a diagonal of the argument array, and the result will have a lower rank than the argument.
+Transpose also allows a left argument that specifies a permutation of `ð•©`'s axes. For each index `pâ†i⊑ð•¨` in the left argument, axis `i` of `ð•©` is used for axis `p` of the result. Multiple argument axes can be sent to the same result axis, in which case that axis goes along a diagonal of `ð•©`, and the result will have a lower rank than `ð•©`.
≢ 1‿3‿2‿0‿4 ≠a23456
+
≢ 1‿2‿2‿0‿0 ≠a23456 # Don't worry too much about this case though
Since this kind of rearrangement can be counterintuitive, it's often easier to use `â‰â¼` when specifying all axes. If `p≡○≠≢a`, then we have `≢pâ‰â¼a â†â†’ pâŠâ‰¢a`.
≢ 1‿3‿2‿0‿4 â‰â¼ a23456
-So far, all like APL. BQN makes one little extension, which is to allow only some axes to be specified. The left argument will be matched up with leading axes of the right argument. Those axes are moved according to the left argument, and remaining axes are placed in order into the gaps between them.
+So far, all like APL. BQN makes one little extension, which is to allow only some axes to be specified. Then `ð•¨` will be matched up with [leading axes](leading.md) of `ð•©`. Those axes are moved according to `ð•¨`, and remaining axes are placed in order into the gaps between them.
≢ 0‿2‿4 ≠a23456
-In particular, the case with only one argument specified is interesting. Here, the first axis ends up at the given location. This gives us a much better solution to the problem at the end of the last section.
+In particular, the case with only one axis specified is interesting. Here, the first axis ends up at the given location. This gives us a much better solution to the problem at the end of the last section.
≢ 2 ≠a23456 # Restrict Transpose to the first three axes
@@ -88,8 +91,8 @@ Finally, it's worth noting that, as monadic Transpose moves the first axis to th
Here we define the two valences of Transpose more precisely.
-Monadic transpose is identical to `(=-1Ë™)⊸â‰`, except that if the argument is a unit it is returned unchanged rather than giving an error.
+An atom right argument to either valence of Transpose is always enclosed to get an array before doing anything else.
-An atom right argument to dyadic Transpose is always enclosed to get an array before doing anything else.
+Monadic transpose is identical to `(=-1Ë™)⊸â‰`, except that if `ð•©` is a unit it is returned unchanged (after enclosing, if it's an atom) rather than giving an error.
-In dyadic Transpose, the left argument is a number or numeric array of rank 1 or less, and `ð•¨â‰¤â—‹â‰ â‰¢ð•©`. Define the result rank `râ†(=ð•©)-+´¬∊ð•¨` to be the argument rank minus the number of duplicate entries in the left argument. We require `∧´ð•¨<r`. Bring `ð•¨` to full length by appending the missing indices: `ð•¨âˆ¾â†©ð•¨(¬∘∊˜/⊢)↕r`. Now the result shape is defined to be `⌊´¨ð•¨âŠ”â‰¢ð•©`. Element `i⊑z` of the result `z` is element `(ð•¨âŠi)⊑ð•©` of the argument.
+In dyadic Transpose, `ð•¨` is a number or numeric array of rank 1 or less, and `ð•¨â‰¤â—‹â‰ â‰¢ð•©`. Define the result rank `râ†(=ð•©)-+´¬∊ð•¨` to be the right argument rank minus the number of duplicate entries in the left argument. We require `∧´ð•¨<r`. Bring `ð•¨` to full length by appending the missing indices: `ð•¨âˆ¾â†©ð•¨(¬∘∊˜/⊢)↕r`. Now the result shape is defined to be `⌊´¨ð•¨âŠ”â‰¢ð•©`. Element `i⊑z` of the result `z` is element `(ð•¨âŠi)⊑ð•©` of the argument.
diff --git a/doc/types.md b/doc/types.md
index 3e37ffed..2564d698 100644
--- a/doc/types.md
+++ b/doc/types.md
@@ -44,13 +44,13 @@ FS ↠{ð•© EncËœ "g"Attr⟨"font-size",(Fmtð•¨)∾"px"⟩}
⟩
-->
-The reason operations and namespaces are called "mutable" is that the values obtained from them—by calling an operation on particular arguments or reading a field from a namespace—may change over the course of the program. This property is caused by variable modification `↩`, which can directly change a namespace field, or change the behavior of an operation that uses the modified variable. This means that a program that doesn't include `↩` won't have such changes in behavior. However, there will still be an observable difference between immutable data and the mutable types: code that creates a mutable value (for example, a block function `{ð•©}`) creates a different one each time, so that two different instances don't match (`≡`) each other. Data values created at different times may match, but mutable values never will.
+The reason operations and namespaces are called "mutable" is that the values obtained from them—by calling an operation on particular arguments or reading a field from a namespace—may change over the course of the program. This property is caused by variable modification `↩`, which can directly change a namespace field, or change the behavior of an operation that uses the modified variable. This means that a program that doesn't include `↩` won't have such changes in behavior. However, there will still be an observable difference between immutable data and the mutable types: code that creates a mutable value (for example, a block function `{ð•©}`) creates a different one each time, so that two different instances don't [match](match.md) (`≡`) each other. Data values created at different times may match, but mutable values never will.
An array is considered immutable because its shape, and what elements it contains, cannot change. An array has no identity outside these properties (and possibly its fill element), so an array with a different shape or different elements would simply be a different array. However, any element of an array could be mutable, in which case the behavior of the array would change with respect to the operation of selecting that element and calling it or accessing a field.
## Data types
-Data types—numbers, characters, and arrays—are more like "things" than "actions". If called as a function, a value of one of these types simply returns itself. Data can be uniquely represented, compared for equality, and ordered using BQN's array ordering; in contrast, determining whether two functions always return the same result can be undecidable. For arrays, these properties apply only if there are no operations inside. We might say that "data" in BQN refers to numbers, characters, and arrays of data.
+Data types—numbers, characters, and arrays—are more like "things" than "actions". If called as a function, a value of one of these types simply returns itself. Data can be uniquely represented, compared for equality, and ordered using BQN's [array ordering](order.md#array-ordering); in contrast, determining whether two functions always return the same result can be undecidable. For arrays, these properties apply only if there are no operations inside. We might say that "data" in BQN refers to numbers, characters, and arrays of data.
### Numbers
@@ -60,16 +60,16 @@ The BQN spec allows for different numeric models to be used, but requires there
A character in BQN is always a [Unicode](https://en.wikipedia.org/wiki/Unicode) code point. BQN does not use encodings such as UTF-8 or UTF-16 for characters, although it would be possible to store arrays of integers or characters that correspond to data in these encodings. Because every code point corresponds to a single unit in UTF-32, BQN characters can be thought of as UTF-32 encoded.
-Addition and subtraction treat characters as an [affine space](http://videocortex.io/2018/Affine-Space-Types/) relative to the linear space of numbers. This means that:
+Addition and subtraction [treat](arithmetic.md#character-arithmetic) characters as an [affine space](http://videocortex.io/2018/Affine-Space-Types/) relative to the linear space of numbers. This means that:
* A number can be added to or subtracted from a character.
* Two characters can be subtracted to get the distance between them—a number.
Other linear combinations such as adding two characters or negating a character are not allowed. You can check whether an application of `+` or `-` on numbers and characters is allowed by applying the same function to the "characterness" of each value: `0` for a number and `1` for a character. The result will be a number if this application gives `0` and a character if this gives `1`, and otherwise the operation is not allowed.
### Arrays
-A BQN array is a multidimensional arrangement of data. This means it has a certain *shape*, which is a finite list of natural numbers giving the length along each axis, and it contains an *element* for each possible *index*, which is a choice of one natural number that's less than each axis length in the shape. The total number of elements, or *bound*, is then the product of all the lengths in the shape. The shape may have any length including zero, and this shape is known as the array's *rank*. An array of rank 0, which always contains exactly one element, is called a *unit*, while an array of rank 1 is called a *list* and an array of rank 2 is called a *table*.
+A BQN array is a multidimensional arrangement of data. This means it has a certain [*shape*](shape.md), which is a finite list of natural numbers giving the length along each axis, and it contains an *element* for each possible [*index*](indices.md), which is a choice of one natural number that's less than each axis length in the shape. The total number of elements, or *bound*, is then the product of all the lengths in the shape. The shape may have any length including zero, and this shape is known as the array's *rank*. An array of rank 0, which always contains exactly one element, is called a *unit*, while an array of rank 1 is called a *list* and an array of rank 2 is called a *table*.
-Each array—empty or nonempty—has an inferred property called a *fill*. The fill either indicates what element should be used to pad an array, or that such an element is not known and an error should result. Fills are used by Take (`↑`) and the two Nudge functions (`»«`).
+Each array—empty or nonempty—has an inferred property called a *fill*. The fill either indicates what element should be used to pad an array, or that such an element is not known and an error should result. Fills can be used by [Take](take.md) (`↑`), the two [Nudge](shift.md) functions (`»«`), [First](pick.md) (`⊑`), and [Reshape](reshape.md) (`⥊`).
Arrays are value types (or immutable), so that there is no way to "change" the shape or elements of an array. An array with different properties is a different array. As a consequence, arrays are an inductive type, and it's not possible for an array to contain itself, or contain an array that contains itself, and so on. However, it is possible for an array to contain a function or other operation that has access to the array through a variable, and in this sense an array can "know about" itself.
diff --git a/doc/windows.md b/doc/windows.md
index 30cb344a..379bf644 100644
--- a/doc/windows.md
+++ b/doc/windows.md
@@ -12,9 +12,9 @@ We'll start with the one-axis case. Here Window's left argument is a number betw
5↕"abcdefg"
-There are `1+(≠ð•©)-ð•¨`, or `(≠ð•©)¬ð•¨`, of these sections, because the starting index must be at least `0` and at most `(≠ð•©)-ð•¨`. Another way to find this result is to look at the number of cells in or before a given slice: there are always `ð•¨` in the slice and there are only `≠ð•©` in total, so the number of slices is the range spanned by these two endpoints.
+There are `1+(≠ð•©)-ð•¨`, or `(≠ð•©)¬ð•¨`, of these sections, because the starting index must be at least `0` and at most `(≠ð•©)-ð•¨`. Another way to find this result is to look at the number of cells in or before a given slice: there are always `ð•¨` in the slice and there are only `≠ð•©` in total, so the number of slices is the range [spanned](logic.md) by these two endpoints.
-You can take a slice of an array `ð•©` that has length `l` and starts at index `i` using `l↑i↓ð•©` or `l↑i⌽ð•©`. The [Prefixes](prefixes.md) function returns all the slices that end at the end of the array (`(≠ð•©)=i+l`), and Suffixes gives the slices that start at the beginning (`i=0`). Windows gives yet another collection of slices: the ones that have a fixed length `l=ð•¨`. Selecting one cell from its result gives you the slice starting at that cell's index:
+You can take a slice of an array `ð•©` that has length `l` and starts at index `i` using [Take](take.md) with Drop or [Rotate](reverse.md#rotate): `l↑i↓ð•©` or `l↑i⌽ð•©`. The [Prefixes](prefixes.md) function returns all the slices that end at the end of the array (`(≠ð•©)=i+l`), and Suffixes gives the slices that start at the beginning (`i=0`). Windows gives yet another collection of slices: the ones that have a fixed length `l=ð•¨`. Selecting one cell from its result gives you the slice starting at that cell's index:
2âŠ5↕"abcdefg"
5↑2↓"abcdefg"
@@ -33,7 +33,7 @@ Passing a list as the left argument to Windows takes slices along any number of
The slices are naturally arranged along multiple dimensions according to their starting index. Once again the equivalence `iâŠl↕x` â†â†’ `l↑i↓x` holds, provided `i` and `l` have the same length.
-If the left argument has length `0`, then the argument is not sliced along any dimensions. The only slice that results—the entire argument—is then arranged along an additional zero dimensions. In the end, the result is the same as the argument.
+If `ð•¨` has length `0`, then `ð•©` is not sliced along any dimensions. The only slice that results—the entire argument—is then arranged along an additional zero dimensions. In the end, the result is `ð•©`, unchanged.
### More formally
@@ -43,7 +43,7 @@ Using [Group](group.md) we could also write `i⊑z` â†â†’ `ð•©âŠ‘Ëœ(ð•¨âˆ¾â—‹
## Symmetry
-Let's look at an earlier example, along with its transpose.
+Let's look at an earlier example, along with its [Transpose](transpose.md) (`â‰`).
{⟨ð•©,â‰ð•©âŸ©}5↕"abcdefg"
@@ -55,21 +55,22 @@ In other words, the i'th element of slice j is the same as the j'th element of s
{(5↕ð•©)≡â‰(3↕ð•©)}"abcdefg"
-In general, we need a more complicated transpose—swapping the first set of `≠ð•¨` axes with the second set. Note again the use of Span, our slice-length to slice-number converter.
+In general, we need a more complicated transpose—swapping the first set of `≠ð•¨` axes with the second set. Note again the use of [Span](logic.md), our slice-length to slice-number converter.
{((5‿6¬2‿2)↕ð•©) ≡ 2‿3â‰(2‿2↕ð•©)} ↕5‿6‿7
## Applications
-Windows can be followed up with a reduction on each slice to give a windowed reduction. Here we take running sums of 3 values.
+Windows can be followed up with a [reduction](fold.md#insert) on each slice to give a windowed reduction. Here we take running sums of 3 values.
- +´˘3↕ ⟨2,6,0,1,4,3⟩
+ +ˢ3↕ ⟨2,6,0,1,4,3⟩
-A common task is to act on windows with an initial or final element so the total length stays the same. When using windows of length 2, the best way to accomplish this is with [shift functions](shift.md) like `«` or `»`. If the window length is longer or variable, then a trick with Windows works better: add the elements, and then use windows matching the original length. Here we invert `` +` ``, which requires we take pairwise differences starting at initial value 0.
+A common task is to act on windows with an initial or final element so the total length stays the same. When using windows of length 2, the best way to accomplish this is with a [shift](shift.md) `«` or `»`. If the window length is longer or variable, then a trick with Windows works better: add the elements, and then use windows matching the original length. Here we invert Plus [Scan](scan.md) `` +` ``, which requires we take pairwise differences starting at initial value 0.
-⟜(0»⊢) +` 3‿2‿1‿1
+
(-ËœË≠↕0∾⊢) +` 3‿2‿1‿1
-With Windows, we can modify the 3-element running sum above to keep the length constant by starting with two zeros.
+With Windows, we can modify the 3-element running sum from before to keep the length constant by starting with two zeros.
(+Ë≠↕(2⥊0)⊸∾) ⟨2,6,0,1,4,3⟩