aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2022-06-05 17:19:14 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2022-06-05 17:19:14 -0400
commit8b115bd20d7a91361a7fe87f293a8a53ff12406c (patch)
tree44e4bd404532d007b5f2bdbdfc392c1698a20a49
parentd6b2e28359a2e0f5f8a0f98782b30d34c18138a1 (diff)
Editing continues
-rw-r--r--doc/oop.md20
-rw-r--r--doc/order.md26
-rw-r--r--doc/pair.md4
-rw-r--r--doc/paradigms.md6
-rw-r--r--doc/pick.md11
-rw-r--r--docs/doc/oop.html20
-rw-r--r--docs/doc/order.html24
-rw-r--r--docs/doc/pair.html4
-rw-r--r--docs/doc/paradigms.html6
-rw-r--r--docs/doc/pick.html13
10 files changed, 65 insertions, 69 deletions
diff --git a/doc/oop.md b/doc/oop.md
index 8c7ff9eb..76d4cc39 100644
--- a/doc/oop.md
+++ b/doc/oop.md
@@ -21,7 +21,7 @@ Mixins | Not really (needs `this`)
## Objects
-An object in BQN is simply a namespace: its fields and methods are variables in the namespace, and one of these can be accessed outside of the namespace with dot syntax if it's exported with `⇐`. Unexported variables are instance-private in OOP parlance, meaning that they're only visible to the object containing them. They could be utilities, or hold state for the object. As an example, the object below implements the [Tower of Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi) puzzle with five disks. You can view the state (a list of disks occupying each of the three rods) with `towerOfHanoi.View`, or move the top disk from one rod to another with `towerOfHanoi.Move`.
+An object in BQN is simply a namespace: its fields and methods are variables in the namespace, and a variable can be accessed outside of the namespace with dot syntax if it's exported with `⇐`. Unexported variables are instance-private in OOP parlance, meaning that they're only visible to the object containing them. They could be utilities, or hold state for the object. As an example, the object below implements the [Tower of Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi) puzzle with five disks. You can view the state (a list of disks occupying each of the three rods) with `towerOfHanoi.View`, or move the top disk from one rod to another with `towerOfHanoi.Move`.
towerOfHanoi ← {
l ← ↕¨5‿0‿0
@@ -39,7 +39,7 @@ An object in BQN is simply a namespace: its fields and methods are variables in
}
}
-Two fields `l` and `Transfer` aren't exported, for two different reasons. `l` encodes the state of the tower, but it's often better to expose it with the function `View` instead to allow the internal representation to be changed freely. `Transfer` is just a utility function. While it's not dangerous to use outside of the object, there's no reason to expose it through `towerOfHanoi`'s interface. If it's wanted in another place it should be moved to a common location.
+Two variables `l` and `Transfer` aren't exported, for two different reasons. `l` encodes the state of the tower, but it's only exposed with the function `View`, which allows the internal representation to be changed freely. `Transfer` is just a utility function. While it's not dangerous to use outside of the object, there's no reason to expose it through `towerOfHanoi`'s interface. If it's wanted in another place it should be moved to a common location.
Here are the results of a few applications of these functions.
@@ -61,7 +61,7 @@ Here are the results of a few applications of these functions.
## Classes
-The object above is a singleton: there's just one of it, at least in the scope it occupies. It's often more useful to have a class that can be used to create objects. What we'll call a "class" is a namespace function, that is, a function that contains `⇐` and so returns a namespace. It's very easy to convert a singleton object to a class: just add a no-op `𝕤` line to force it to be a function, and call it with `@` when needed.
+The object above is a singleton: there's just one of it, at least in the scope it occupies. It's often more useful to have a class that can be used to create objects. What we'll call a "class" is a namespace function, that is, a function that contains `⇐` and so returns a namespace. It's very easy to convert a singleton object to a class: [just add](control.md#blocks-and-functions) a no-op `𝕤` line to force it to be a function, and call it with `@` when needed.
MakeStack ← {𝕤
st←@
@@ -69,7 +69,7 @@ The object above is a singleton: there's just one of it, at least in the scope i
Pop ⇐{𝕤⋄ r‿s←st ⋄ st↩s ⋄ r}
}
-But there's no need to ignore the argument: often it's useful to initialize a class using one or two arguments. For example, the stack class above can be modified to use `𝕩` as an initial list of values for the stack.
+But arguments don't have to be ignored: often it makes sense to use one or two arguments to initialize the object. For example, the stack class above can be modified to use `𝕩` as an initial list of values for the stack.
MakeStackInit ← {
st←@
@@ -78,7 +78,7 @@ But there's no need to ignore the argument: often it's useful to initialize a cl
Push¨ 𝕩
}
-A stack is a particularly simple class to make because its state can be represented efficiently as a BQN value. Other data structures don't allow this, and will often require an extra `Node` class when they are implemented—see `MakeQueue` below.
+A stack is a particularly simple class to make because its state can be represented efficiently as a BQN value. Other data structures don't allow this, and will often require an extra `Node` class in an implementation—see `MakeQueue` below.
## Mutability
@@ -90,7 +90,7 @@ Let's look at how mutability plays out in an example class for a single-ended qu
t←h←e←{SetN⇐{h↩𝕩}}
Node←{v⇐𝕩⋄n⇐e ⋄ SetN⇐{n↩𝕩}}
Push⇐{t.SetN n←Node 𝕩 ⋄ t↩n}
- Pop ⇐{𝕤⋄v←h.v⋄{t↩𝕩}⍟(e⊸=)h↩h.n⋄v}
+ Pop ⇐{𝕤⋄v←h.v⋄h↩h.n⋄{e=h?t↩e;@}⋄v}
}
Unlike a stack, a node's successor isn't known when it's created, and it has to be set. You might be inclined to make `n` settable directly, but we'll get more mileage out of a setter function `SetN`. This allows us to create a pseudo-node `e` (for "empty") indicating there are no values in the queue. Because it has no `.v` field, if `h` is `e` then `Pop` gives an error (but in a real implementation you'd want to test explicitly instead in order to give an appropriate error message). In fact it doesn't have an `n` field, and essentially uses the queue head `h` instead. With this empty "node", the queue definition is straightforward. The only tricky part to remember is that if `Pop` removes the last node, resulting in `e=h`, then the tail has to be set to `e` as well, or it will keep pointing to the removed node and cause bugs.
@@ -106,7 +106,7 @@ BQN classes don't support inheritance because there's no way to extend an existi
Undo ⇐ t.Move∘⌽∘Pop
}
-This class composes a Tower of Hanoi with an undo stack that stores previous moves. To undo a move from `a` to `b`, it moves from `b` to `a`, although if you felt really fancy you might define `Move⁼` in `towerOfHanoi` instead with `𝕊⁼𝕩: 𝕊⌽𝕩`.
+This class composes a Tower of Hanoi with an undo stack that stores previous moves. To undo a move from `a` to `b`, it moves from `b` to `a`, although if you felt really fancy you might define `Move⁼` in `towerOfHanoi` instead with an [undo header](undo.md#undo-headers) `𝕊⁼𝕩: 𝕊⌽𝕩`.
It's also possible to copy several variables and only export some of them, with an export statement. For example, if I wasn't going to make another method called `Move`, I might have written `View‿Move ← towerOfHanoi` and then `View⇐`. In fact, depending on your personal style and how complicated your classes are, you might prefer to avoid inline `⇐` exports entirely, and declare all the exports at the top.
@@ -119,16 +119,16 @@ It's not currently possible for an object to know its own value without some out
IntrospectiveClass ← {
obj ← {
this⇐@
- SetThis ⇐ { !this=@ ⋄ this↩𝕩 }
+ SetThis ⇐ { !this≡@ ⋄ this↩𝕩 }
}
obj.setThis obj
}
-This is a pretty clunky solution, and exports a useless method `SetThis` (which gives an error if it's ever called). It would be possible for BQN to define a system value `•this` that just gets the namespace's value. It would work only at the top level, so it would have to be assigned (`this←•this`) in order to use it in functions. This means it's always used before the namespace is done being defined, so a drawback is that it introduces the possibility that an object used in a program has undefined fields. The reason this isn't possible for objects without `•this` is that BQN's blocks don't have any sort of control flow, so that they always execute every statement in order. The namespace becomes accessible as a value once the block finishes, and at this point every statement has been executed and every field is initialized.
+This is a pretty clunky solution, and exports a useless method `SetThis` (which gives an error if it's ever called). It would be possible for BQN to define a system value `•this` that just gets the namespace's value. It would work only at the top level, so it would have to be assigned (`this←•this`) in order to use it in functions. This means it's always used before the namespace is done being defined, so a drawback is that it introduces the possibility that an object used in a program has undefined fields. Currently a namespace can only be created with all fields set: a block body doesn't have any sort of control flow other than the early exit `?`, so it can only finish by executing every statement, including every field definition, in order.
## Class members
-As with `this`, giving a class variables that belong to it is a do-it-yourself sort of thing (or more positively, not at all magic (funny how programmer jargon goes the opposite way to ordinary English)). It's an easy one though, as this is exactly what [lexical scoping](lexical.md) does:
+As with `this`, creating variables that belong to a class and not its objects is a do-it-yourself sort of thing (or more positively, not at all magic (funny how programmer jargon goes the opposite way to ordinary English)). It's an easy one though, as this is exactly what [lexical scoping](lexical.md) does:
staticClass ← {
counter ← 0
diff --git a/doc/order.md b/doc/order.md
index cf63a101..3cd25b71 100644
--- a/doc/order.md
+++ b/doc/order.md
@@ -4,8 +4,8 @@
BQN has six functions that order arrays as part of their operation (the [comparison functions](arithmetic.md#comparisons) `≤<>≥` only order atoms, so they aren't included). These come in three pairs, where one of each pair uses an ascending ordering and the other uses a descending ordering.
-- `∨∧`, Sort, rearranges the argument to order it
-- `⍒⍋`, Grade, outputs the permutation that Sort would use to rearrange it
+- `∨∧`, Sort, puts major cells of `𝕩` in order
+- `⍒⍋`, Grade, outputs the permutation that Sort would use to rearrange `𝕩`
- `⍒⍋`, Bins, takes an ordered `𝕨` and determines where each cell of `𝕩` fits in this ordering.
The array ordering shared by all six is described last. For lists it's "dictionary ordering": two lists are compared one element at a time until one runs out, and the shorter one comes first in case of a tie. Operation values aren't ordered, so if an argument to an ordering function has a function or modifier somewhere in it then it will fail unless all the orderings can be decided without checking that value.
@@ -14,13 +14,13 @@ You can't provide a custom ordering function to Sort. The function would have to
## Sort
-You've probably seen it before. Sort Up (`∧`) reorders the major cells of its argument to place them in ascending order, and Sort Down (`∨`) puts them in descending order. Every ordering function follows this naming convention—there's an "Up" version pointing up and a "Down" version going the other way.
+You've probably seen it before. Sort Up (`∧`) reorders the [major cells](array.md#cells) of its argument to place them in ascending order, and Sort Down (`∨`) puts them in descending order. Every ordering function follows this naming convention—there's an "Up" version pointing up and a "Down" version going the other way.
∧ "delta"‿"alpha"‿"beta"‿"gamma"
∨ "δαβγ"
-Sort Down always [matches](match.md) Sort Up [reversed](reverse.md), `⌽∘∧`. The reason for this is that BQN's array ordering is a [total order](https://en.wikipedia.org/wiki/Total_order), meaning that if one array doesn't come earlier or later than another array in the ordering then the two arrays match. Since any two non-matching argument cells are strictly ordered, they will have one ordering in `∧` and the opposite ordering in `∨`. With the reverse, any pair of non-matching cells are ordered the same way in `⌽∘∧` and `∨`. Since these two results have the same major cells in the same order, they match. However, note that the results will not always behave identically because Match doesn't take [fill elements](fill.md) into account (if you're curious, take a look at `⊑¨∨⟨↕0,""⟩` versus `⊑¨⌽∘∧⟨↕0,""⟩`).
+Sort Down always [matches](match.md) Sort Up [reversed](reverse.md), `⌽∘∧`. The reason for this is that BQN's array ordering is a [total order](https://en.wikipedia.org/wiki/Total_order), meaning that if one array doesn't come earlier or later than another array in the ordering then the two arrays match. Since any two non-matching argument cells are strictly ordered, they will have one ordering in `∧` and the opposite ordering in `∨`. After the reverse, any pair of non-matching cells are ordered the same way in `⌽∘∧` and `∨`. Since these two results have the same major cells in the same order, they match. However, note that the results will not always behave identically because Match doesn't take [fill elements](fill.md) into account (if you're curious, take a look at `⊑¨∨⟨↕0,""⟩` versus `⊑¨⌽∘∧⟨↕0,""⟩`).
## Grade
@@ -61,7 +61,7 @@ tp ← ⍉ tx ⋈⌜ y
}
-->
-Grade is more abstract than Sort. Rather than rearranging the argument's cells immediately, it returns a list of indices (more precisely, a permutation) giving the ordering that would sort them.
+Grade is more abstract than Sort. Rather than rearranging the argument's cells immediately, it returns a list of [indices](indices.md) (more precisely, a permutation) giving the ordering that would sort them.
⊢ l ← "planet"‿"moon"‿"star"‿"asteroid"
@@ -99,11 +99,11 @@ How does it work? First, let's note that `⍋l` is a *permutation*: it contains
But what's the inverse `q` of a permutation `p`? Our requirement is that `𝕩 ≡ q⊏p⊏𝕩` for any `𝕩` with the same length as `p`. Setting `𝕩` to `↕≠p` (the identity permutation), we have `(↕≠p) ≡ q⊏p`, because `p⊏↕≠p` is just `p`. But if `p` is a permutation then `∧p` is `↕≠p`, so our requirement could also be written `(∧p) ≡ q⊏p`. Now it's all coming back around again. We know exactly how to get `q`! Defining `q←⍋p`, we have `q⊏p ↔ (⍋p)⊏p ↔ ∧p ↔ ↕≠p`, and `q⊏p⊏𝕩 ↔ (q⊏p)⊏𝕩 ↔ (↕≠p)⊏𝕩 ↔ 𝕩`.
-The fact that Grade Up inverts a permutation is useful in itself. Note that this applies to Grade Up specifically, and not Grade Down. This is because the identity permutation is ordered in ascending order. Grade Down would actually invert the reverse of a permutation, which is unlikely to be useful. So the ordinals idiom that goes in the opposite direction is actually not `⍒⍒` but `⍋⍒`. The initial grade is different, but the way to invert it is the same.
+The fact that Grade Up inverts a permutation is useful in itself. Note that this applies to Grade Up specifically, and not Grade Down. This is because the identity permutation is ordered in ascending order. Grade Down would invert the reverse of a permutation, which is unlikely to be useful. So the ordinals idiom that goes in the opposite direction is actually not `⍒⍒` but `⍋⍒`. The initial grade is different, but the way to invert it is the same.
### Stability
-When sorting an array, we usually don't care how matching cells are ordered relative to each other (although it's possible to detect it by using fill elements carefully. They maintain their ordering). Grading is a different matter, because often the grade of one array is used to order another one.
+When sorting an array, we usually don't care how matching cells are ordered relative to each other (although as mentioned above it's possible to detect it by using fill elements carefully. They maintain their ordering). Grading is a different matter, because often the grade of one array is used to order another one.
⊢ t ← >⟨ "dog"‿4, "ant"‿6, "pigeon"‿2, "pig"‿4 ⟩
@@ -121,11 +121,9 @@ To see some of the possibilities of Grade, you might pick apart the following ex
## Bins
-*There's also an [APL Wiki page](https://aplwiki.com/wiki/Interval_Index) on this function, but be careful as the Dyalog version has subtle differences.*
-
The two Bins functions are written with the same symbols `⍋` and `⍒` as Grade, but take two arguments instead of one. More complicated? A little, but once you understand Bins you'll find that it's a basic concept that shows up in the real world all the time.
-Bins behaves like a [search function](search.md) with respect to rank: it looks up cells from `𝕩` relative to major cells of `𝕨`. However, there's an extra requirement: the left argument to Bins is already sorted according to whichever ordering is used. If it isn't, you'll get an error.
+Bins behaves like a [search function](search.md) with respect to rank: it looks up [cells](array.md#cells) from `𝕩` relative to major cells of `𝕨`. However, there's an extra requirement: the left argument to Bins must already be sorted according to whichever ordering is used. If it isn't, you'll get an error.
5‿6‿2‿4‿1 ⍋ 3
@@ -145,16 +143,14 @@ A score of `565e7` sits between `578e7` and `553e7` at rank 3, `322e7` wouldn't
Most of the time you won't need to worry about the details of how BQN arrays are ordered. It's documented here because, well, that's what documentation does.
-The array ordering defines some arrays to be smaller or larger than others. All of the "Up" ordering functions use this ordering directly, so that smaller arrays come earlier, and the "Down" ones use the opposite ordering, with larger arrays coming earlier. For arrays consisting only of characters and numbers, with arbitrary nesting, the ordering is always defined. If an array contains an operation, trying to order it relative to another array might give an error. If comparing two arrays succeeds, there are three possibilities: the first array is smaller, the second is smaller, or the two arrays [match](match.md).
+BQN's *array ordering* is an extension of the number and character ordering given by `≤` to [arrays](array.md). In this system, any two arrays that have only numbers and characters for atoms can be compared with each other. Furthermore, some arrays that contain incomparable atoms (operations or namespaces) might be comparable, if the result of the comparison can be decided before reaching these atoms. Array ordering never depends on [fill elements](fill.md). If comparing two arrays succeeds, there are three possibilities: the first array is smaller, the second is smaller, or the two arrays [match](match.md). All of the "Up" ordering functions use this ordering directly, so that smaller arrays come earlier, and the "Down" ones use the opposite ordering, with larger arrays coming earlier.
-Comparing two atoms is defined to work the same way as the [comparison functions](arithmetic.md#comparisons) `≤<>≥`. Numbers come earlier than characters and otherwise these two types are ordered in the obvious way. To compare an atom to an array, the atom enclosing and then compared with the array ordering defined below. The result of this comparison is used except when the two arrays match: in that case, the atom is considered smaller.
+Comparing two atoms is defined to work the same way as the [comparison functions](arithmetic.md#comparisons) `≤<>≥`. Numbers come earlier than characters and otherwise these two types are ordered in the obvious way. To compare an atom to an array, the atom is enclosed and then compared with the array ordering defined below. The result of this comparison is used except when the two arrays match: in that case, the atom is considered smaller.
-Two arrays of the same shape are compared by comparing all their corresponding elements, in index order. This comparison can stop at the first pair of different elements (which allows later elements to contain operations without causing an error). If any elements were different, then they decide the result of the comparison. If all the elements matched, then by definition the two arrays match.
+Two arrays of the same shape are compared by comparing all their corresponding elements, in index order. This comparison stops at the first pair of different elements (which allows later elements to contain operations without causing an error). If any elements were different, then they decide the result of the comparison. If all the elements matched, then by definition the two arrays match.
The principle for arrays of different shapes is the same, but there are two factors that need to be taken into account. First, it's not obvious any more what it means to compare corresponding elements—what's the correspondence? Second, the two arrays can't match because they have different shapes. So even if all elements end up matching one of them needs to come earlier.
-BQN's *array ordering* is an extension of the number and character ordering given by `≤` to arrays. In this system, any two arrays consisting of only numbers and characters for atoms can be compared with each other. Furthermore, some arrays that contain incomparable atoms (operations) might be comparable, if the result of the comparison can be decided before reaching these atoms. Array ordering does not depend on the fill elements for the two arguments.
-
Let's discuss correspondence first. One way to think about how BQN makes arrays correspond is that they're simply laid on top of each other, lining up the first (as in `⊑`) elements. So a shape `⟨4⟩` array will match up with the first row of a shape `5‿3` array, but have an extra element off the end. A simple way to think about this is to say that the lower rank array is brought up to a matching rank by putting `1`s in front of the shape, and then lengths along each axis are matched up by padding the shorter array along that axis with a special "nothing" element. This "nothing" element will be treated as smaller than any actual array, because this rule recovers the "dictionary ordering" rule that a word that's a prefix of a longer word comes before that word. In the case of the shapes `⟨4⟩` and `5‿3`, if the three overlapping elements match then the fourth element comes from the first row and is present in the first array but not the second. So the shape `5‿3` array would be considered smaller without even looking at its other four rows.
It can happen that two arrays of different shape have all matching elements with this procedure: either because one array's shape is the same as the other's but with some extra `1`s at the beginning, or because both arrays are empty. In this case, the arrays are compared first by rank, with the higher-rank array considered larger, and then by shape, beginning with the leading axes.
diff --git a/doc/pair.md b/doc/pair.md
index d4519e49..377ffa0b 100644
--- a/doc/pair.md
+++ b/doc/pair.md
@@ -30,7 +30,7 @@ However, before making a long list of this sort, consider that your goal might b
## Pair versus Couple
-Enlist and Pair closely related to [Solo and Couple](couple.md), in that `⋈` is equivalent to `≍○<` and `≍` is equivalent to `>∘⋈`. However, the result of `⋈` is always a list (rank 1) while Solo or Couple return an array of rank at least 1.
+Enlist and Pair are closely related to [Solo and Couple](couple.md), in that `⋈` is equivalent to `≍○<` and `≍` is equivalent to `>∘⋈`. However, the result of `⋈` is always a list (rank 1) while Solo or Couple return an array of rank at least 1.
"abc" ≍ "def"
@@ -42,7 +42,7 @@ And the arguments to Couple must have the same shape, while Enlist takes any two
"abc" ⋈ "defg"
-The difference is that Couple treats the arguments as cells, and adds a dimension, while Pair treats them as elements, adding a layer of depth. Couple is a "flat" version of Pair, much like Cells (`˘`) is a flat version of Each (`¨`). Pair is more versatile, but—precisely because of its restrictions—Couple may allow more powerful array operations on the result.
+The difference is that Couple treats the arguments as [cells](array.md#cell), and adds a dimension, while Pair treats them as elements, adding a layer of depth. Couple is a "flat" version of Pair, much like [Cells](rank.md#cells) (`˘`) is a flat version of [Each](map.md#each) (`¨`). Pair is more versatile, but—precisely because of its restrictions—Couple may allow more powerful array operations on the result.
## Fill element
diff --git a/doc/paradigms.md b/doc/paradigms.md
index 37189854..b3c691a6 100644
--- a/doc/paradigms.md
+++ b/doc/paradigms.md
@@ -10,7 +10,7 @@ When programming in BQN, I almost always use array, tacit, and (slightly impure)
## Typing
-BQN is a **dynamically typed** language with a coarse [type system](types.md) that only distinguishes types when the difference is blindingly obvious. There is a single numeric type and a single unicode character type. A fast implementation such as CBQN will check to see when it can represent the data with a smaller type than the one offered by the language. BQN usually avoids implicit type conversion, with the exception that many primitives automatically convert atoms to unit arrays. The fact that a data value can be applied as a function to return itself could also be considered an implicit conversion.
+BQN is a **dynamically typed** language with a coarse [type system](types.md) that only distinguishes types when the difference is blindingly obvious. There is a single numeric type and a single Unicode character type. A fast implementation such as CBQN will check to see when it can represent the data with a smaller type than the one offered by the language. BQN usually avoids implicit type conversion, with the exception that many primitives automatically convert atoms to unit arrays. The fact that a data value can be applied as a function to return itself could also be considered an implicit conversion.
BQN has no "pointer" or "reference" type, and uses **automatic memory management**. Its data types are **immutable** while operations and namespaces are [mutable](lexical.md#mutation); mutable data can create reference loops, which the implementation must account for in garbage collection but the programmer doesn't have to worry about.
@@ -20,9 +20,9 @@ Dynamic types and garbage collection introduce overhead relative to a statically
BQN is designed for **array** programming. The array is its only built-in collection type and it has many primitives designed to work with arrays.
-BQN is okay for **imperative** programming. Blocks are lists of statements. Variables can be modified with `↩`, and while there are no truly global variables, [lexical scoping](lexical.md) allows variables at the top level of a file, which are similar (`•Import` with no left argument saves and reuses results, so that data can be shared between files by loading the same namespace-defining file in each). BQN doesn't directly support **structured** programming (which refers to a particular way to structure programs; it also doesn't have a Goto statement, the "unstructured" alternative when the term was coined). However, its first-class functions allow a reasonably similar [imitation](control.md) of control structures.
+BQN is okay for **imperative** programming. Blocks are lists of statements. Variables can be modified with `↩`, and while there are no truly global variables, [lexical scoping](lexical.md) allows variables at the top level of a file, which are similar (`•Import` with no left argument saves and reuses results, so that data can be shared between files by loading the same namespace-defining file in each). BQN doesn't directly support **structured** programming (which refers to a particular way to structure programs; it also doesn't have a Go-to statement, the "unstructured" alternative when the term was coined). However, its first-class functions allow a reasonably similar [imitation](control.md) of control structures.
-**Functional** programming is a term with many meanings. Using the terms defined in the [functional programming document](functional.md), BQN supports first-class functions and function-level programming, allows but doesn't encourage pure functional programming, and does not support typed functional programming. BQN uses **lexical scope** and has full support for **closures**. In this way BQN is very similar to Lisp, although it lacks Lisp's macro system.
+**Functional** programming is a term with many meanings. Using the terms defined in the [page on functional programming](functional.md), BQN supports first-class functions and function-level programming, allows but doesn't encourage pure functional programming, and does not support typed functional programming. BQN uses **lexical scope** and has full support for **closures**. In this way BQN is very similar to Lisp, although it lacks Lisp's macro system.
BQN has excellent [support](tacit.md) for **tacit** or **point-free** programming, with [trains](train.md) and intuitive symbols for combinators making it much easier to work with (in my opinion) than other languages that support this style. It's near-universally considered a poor choice to implement entire programs in a tacit style, so this paradigm is best used as a small-scale tool within a style like functional or object-oriented programming.
diff --git a/doc/pick.md b/doc/pick.md
index 254c64ec..bc30b930 100644
--- a/doc/pick.md
+++ b/doc/pick.md
@@ -4,7 +4,7 @@
Pick (`⊑`) chooses elements from `𝕩` based on [index](indices.md) lists from `𝕨`. `𝕨` can be a plain list, or even one number if `𝕩` is a list, in order to get one element from `𝕩`. It can also be an array of index lists, or have deeper array structure: each index list will be replaced with the element of `𝕩` at that index, effectively applying to `𝕨` at [depth](depth.md#the-depth-modifier) 1.
-With no `𝕨`, monadic `⊑𝕩` takes the first element of `𝕩` in index order, with an error if `𝕩` is empty.
+The one-argument form is called First, and `⊑𝕩` takes the first element of `𝕩` in index order, with an error if `𝕩` is empty.
While sometimes "scatter-point" indexing is necessary, using Pick to select multiple elements from `𝕩` is less array-oriented than [Select](select.md) (`⊏`), and probably slower. Consider rearranging your data so that you can select along axes instead of picking out elements.
@@ -21,7 +21,7 @@ A negative number `𝕨` behaves like `𝕨+≠𝕩`, so that `¯1` will select
¯2 ⊑ 0‿1‿2‿3‿4
¯2 ⊑ "abc"
-Making `𝕩` a list is only a special case. In general `𝕨` can be a list of numbers whose length is `𝕩`'s rank. So when `=𝕩` is 1, `𝕨` can be length-1 list. For convenience, a number is also allowed, but not an enclosed number (which could be confused with the nested case).
+Making `𝕩` a list is only a special case. In general `𝕨` can be a list of numbers whose length is `𝕩`'s rank. So when `=𝕩` is 1, `𝕨` can be length-1 list. The case above where `𝕨` is a number is a simplification, but an enclosed number `𝕨` isn't allowed because it could be confused with the nested case described below.
⟨2,0⟩ ⊑ ↕4‿5
@@ -31,22 +31,23 @@ Above we see that picking from the result of [Range](range.md) gives the index.
2‿0 ⊑ a
1‿¯1 ⊑ a
-This applies even if `𝕩` is a unit. By definition it has rank 0, so the only possible value for `𝕨` is the empty list. This extracts an [enclosed](enclose.md) element, and returns an atom unchanged—the atom is promoted to an array by enclosing it, then the action of Pick undoes this. But there's rarely a reason to use this case, because the monadic form First accomplishes the same thing.
+`𝕩` can even be a [unit](enclose.md#whats-a-unit). By definition it has rank 0, so the only possible value for `𝕨` is the empty list. This extracts an [enclosed](enclose.md) element, and returns an atom unchanged—the atom is promoted to an array by enclosing it, then the action of Pick undoes this. But there's rarely a reason to use this case, because the monadic form First accomplishes the same thing.
⟨⟩ ⊑ <'a'
⟨⟩ ⊑ 'a'
### First
-With no left argument, `⊑` is called First, and performs a slight generalization of Pick with a default left argument `0¨≢𝕩`. For a non-empty array it returns the first element in index order.
+With no left argument, `⊑` is called First, and is the same as Pick with a default left argument `0¨≢𝕩`. For a non-empty array it returns the first element in index order.
⊑ <'a'
⊑ "First"
⊑ ↕4‿2‿5‿1
-If `𝕩` is empty then First results in an error, like Pick.
+And if `𝕩` is empty then First results in an error.
⊑ ""
+
⊑ ≢π
In APL it's common to get the last element of a list with an idiom that translates to `⊑⌽`, or First-[Reverse](reverse.md). In BQN the most straightforward way is to select with index `¯1` instead. I also sometimes use [Fold](fold.md) with the Right [identity function](identity.md).
diff --git a/docs/doc/oop.html b/docs/doc/oop.html
index 66df070f..2e47476c 100644
--- a/docs/doc/oop.html
+++ b/docs/doc/oop.html
@@ -65,7 +65,7 @@
</tbody>
</table>
<h2 id="objects"><a class="header" href="#objects">Objects</a></h2>
-<p>An object in BQN is simply a namespace: its fields and methods are variables in the namespace, and one of these can be accessed outside of the namespace with dot syntax if it's exported with <code><span class='Gets'>⇐</span></code>. Unexported variables are instance-private in OOP parlance, meaning that they're only visible to the object containing them. They could be utilities, or hold state for the object. As an example, the object below implements the <a href="https://en.wikipedia.org/wiki/Tower_of_Hanoi">Tower of Hanoi</a> puzzle with five disks. You can view the state (a list of disks occupying each of the three rods) with <code><span class='Value'>towerOfHanoi.</span><span class='Function'>View</span></code>, or move the top disk from one rod to another with <code><span class='Value'>towerOfHanoi.</span><span class='Function'>Move</span></code>.</p>
+<p>An object in BQN is simply a namespace: its fields and methods are variables in the namespace, and a variable can be accessed outside of the namespace with dot syntax if it's exported with <code><span class='Gets'>⇐</span></code>. Unexported variables are instance-private in OOP parlance, meaning that they're only visible to the object containing them. They could be utilities, or hold state for the object. As an example, the object below implements the <a href="https://en.wikipedia.org/wiki/Tower_of_Hanoi">Tower of Hanoi</a> puzzle with five disks. You can view the state (a list of disks occupying each of the three rods) with <code><span class='Value'>towerOfHanoi.</span><span class='Function'>View</span></code>, or move the top disk from one rod to another with <code><span class='Value'>towerOfHanoi.</span><span class='Function'>Move</span></code>.</p>
<pre><span class='Value'>towerOfHanoi</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='Value'>l</span> <span class='Gets'>←</span> <span class='Function'>↕</span><span class='Modifier'>¨</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span>
<span class='Function'>View</span> <span class='Gets'>⇐</span> <span class='Brace'>{</span><span class='Value'>𝕤</span>
@@ -82,7 +82,7 @@
<span class='Brace'>}</span>
<span class='Brace'>}</span>
</pre>
-<p>Two fields <code><span class='Value'>l</span></code> and <code><span class='Function'>Transfer</span></code> aren't exported, for two different reasons. <code><span class='Value'>l</span></code> encodes the state of the tower, but it's often better to expose it with the function <code><span class='Function'>View</span></code> instead to allow the internal representation to be changed freely. <code><span class='Function'>Transfer</span></code> is just a utility function. While it's not dangerous to use outside of the object, there's no reason to expose it through <code><span class='Value'>towerOfHanoi</span></code>'s interface. If it's wanted in another place it should be moved to a common location.</p>
+<p>Two variables <code><span class='Value'>l</span></code> and <code><span class='Function'>Transfer</span></code> aren't exported, for two different reasons. <code><span class='Value'>l</span></code> encodes the state of the tower, but it's only exposed with the function <code><span class='Function'>View</span></code>, which allows the internal representation to be changed freely. <code><span class='Function'>Transfer</span></code> is just a utility function. While it's not dangerous to use outside of the object, there's no reason to expose it through <code><span class='Value'>towerOfHanoi</span></code>'s interface. If it's wanted in another place it should be moved to a common location.</p>
<p>Here are the results of a few applications of these functions.</p>
<pre> <span class='Value'>t</span> <span class='Gets'>←</span> <span class='Value'>towerOfHanoi</span>
<span class='Value'>t.</span><span class='Function'>View</span><span class='String'>@</span>
@@ -101,14 +101,14 @@
<span class='Bracket'>⟨</span> <span class='Bracket'>⟨</span> <span class='Number'>2</span> <span class='Number'>3</span> <span class='Number'>4</span> <span class='Bracket'>⟩</span> <span class='Bracket'>⟨</span> <span class='Number'>0</span> <span class='Number'>1</span> <span class='Bracket'>⟩</span> <span class='Bracket'>⟨⟩</span> <span class='Bracket'>⟩</span>
</pre>
<h2 id="classes"><a class="header" href="#classes">Classes</a></h2>
-<p>The object above is a singleton: there's just one of it, at least in the scope it occupies. It's often more useful to have a class that can be used to create objects. What we'll call a &quot;class&quot; is a namespace function, that is, a function that contains <code><span class='Gets'>⇐</span></code> and so returns a namespace. It's very easy to convert a singleton object to a class: just add a no-op <code><span class='Value'>𝕤</span></code> line to force it to be a function, and call it with <code><span class='String'>@</span></code> when needed.</p>
+<p>The object above is a singleton: there's just one of it, at least in the scope it occupies. It's often more useful to have a class that can be used to create objects. What we'll call a &quot;class&quot; is a namespace function, that is, a function that contains <code><span class='Gets'>⇐</span></code> and so returns a namespace. It's very easy to convert a singleton object to a class: <a href="control.html#blocks-and-functions">just add</a> a no-op <code><span class='Value'>𝕤</span></code> line to force it to be a function, and call it with <code><span class='String'>@</span></code> when needed.</p>
<pre><span class='Function'>MakeStack</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>𝕤</span>
<span class='Value'>st</span><span class='Gets'>←</span><span class='String'>@</span>
<span class='Function'>Push</span><span class='Gets'>⇐</span><span class='Brace'>{</span> <span class='Value'>st</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Ligature'>‿</span><span class='Value'>st</span><span class='Brace'>}</span>
<span class='Function'>Pop</span> <span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Value'>𝕤</span><span class='Separator'>⋄</span> <span class='Value'>r</span><span class='Ligature'>‿</span><span class='Value'>s</span><span class='Gets'>←</span><span class='Value'>st</span> <span class='Separator'>⋄</span> <span class='Value'>st</span><span class='Gets'>↩</span><span class='Value'>s</span> <span class='Separator'>⋄</span> <span class='Value'>r</span><span class='Brace'>}</span>
<span class='Brace'>}</span>
</pre>
-<p>But there's no need to ignore the argument: often it's useful to initialize a class using one or two arguments. For example, the stack class above can be modified to use <code><span class='Value'>𝕩</span></code> as an initial list of values for the stack.</p>
+<p>But arguments don't have to be ignored: often it makes sense to use one or two arguments to initialize the object. For example, the stack class above can be modified to use <code><span class='Value'>𝕩</span></code> as an initial list of values for the stack.</p>
<pre><span class='Function'>MakeStackInit</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='Value'>st</span><span class='Gets'>←</span><span class='String'>@</span>
<span class='Function'>Push</span><span class='Gets'>⇐</span><span class='Brace'>{</span> <span class='Value'>st</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Ligature'>‿</span><span class='Value'>st</span><span class='Brace'>}</span>
@@ -116,7 +116,7 @@
<span class='Function'>Push</span><span class='Modifier'>¨</span> <span class='Value'>𝕩</span>
<span class='Brace'>}</span>
</pre>
-<p>A stack is a particularly simple class to make because its state can be represented efficiently as a BQN value. Other data structures don't allow this, and will often require an extra <code><span class='Function'>Node</span></code> class when they are implemented—see <code><span class='Function'>MakeQueue</span></code> below.</p>
+<p>A stack is a particularly simple class to make because its state can be represented efficiently as a BQN value. Other data structures don't allow this, and will often require an extra <code><span class='Function'>Node</span></code> class in an implementation—see <code><span class='Function'>MakeQueue</span></code> below.</p>
<h2 id="mutability"><a class="header" href="#mutability">Mutability</a></h2>
<p>An object is one way to transform <em>variable mutation</em> <code><span class='Gets'>↩</span></code> into <em>mutable data</em>. These are two different concepts: <code><span class='Gets'>↩</span></code> changes which value is attached to a <em>name</em> in a scope, while mutable data means that the behavior of a particular <em>value</em> can change. But if a value is linked to a scope (for an object, the scope that contains its fields), then variable mutation in that scope can change the value's behavior. In fact, in BQN this is the only way to create mutable data. Which doesn't mean it's rare: functions, modifiers, and namespaces are all potentially mutable. The difference between objects and the operations is just a matter of syntax. Mutability in operations can only be observed by calling them. For instance <code><span class='Function'>F</span> <span class='Number'>10</span></code> or <code><span class='Function'>-</span><span class='Modifier'>_m</span></code> could return a different result even if the variables involved don't change value. Mutability in an object can only be observed by accessing a member, meaning that <code><span class='Value'>obj.field</span></code> or <code><span class='Bracket'>⟨</span><span class='Value'>field</span><span class='Bracket'>⟩</span><span class='Gets'>←</span><span class='Value'>obj</span></code> can yield different values over the course of a program even if <code><span class='Value'>obj</span></code> is still the same object.</p>
<p>Let's look at how mutability plays out in an example class for a single-ended queue. This queue works by linking new nodes to the tail <code><span class='Value'>t</span></code> of the queue, and detaching nodes from the head <code><span class='Value'>h</span></code> when requested (a detached node will still point to <code><span class='Value'>h</span></code>, but nothing in the queue points to <em>it</em>, so it's unreachable and will eventually be garbage collected). Each node has some data <code><span class='Value'>v</span></code> and a single node reference <code><span class='Value'>n</span></code> directed tailwards; in a double-ended queue or more complicated structure it would have more references. You can find every mutable variable in the queue by searching for <code><span class='Gets'>↩</span></code>, which shows that <code><span class='Value'>t</span></code> and <code><span class='Value'>h</span></code> in the queue, and <code><span class='Value'>n</span></code> in a node, may be mutated. It's impossible for the other variables to change value once they're assigned.</p>
@@ -124,7 +124,7 @@
<span class='Value'>t</span><span class='Gets'>←</span><span class='Value'>h</span><span class='Gets'>←</span><span class='Value'>e</span><span class='Gets'>←</span><span class='Brace'>{</span><span class='Function'>SetN</span><span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Value'>h</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Brace'>}}</span>
<span class='Function'>Node</span><span class='Gets'>←</span><span class='Brace'>{</span><span class='Value'>v</span><span class='Gets'>⇐</span><span class='Value'>𝕩</span><span class='Separator'>⋄</span><span class='Value'>n</span><span class='Gets'>⇐</span><span class='Value'>e</span> <span class='Separator'>⋄</span> <span class='Function'>SetN</span><span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Value'>n</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Brace'>}}</span>
<span class='Function'>Push</span><span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Value'>t.</span><span class='Function'>SetN</span> <span class='Value'>n</span><span class='Gets'>←</span><span class='Function'>Node</span> <span class='Value'>𝕩</span> <span class='Separator'>⋄</span> <span class='Value'>t</span><span class='Gets'>↩</span><span class='Value'>n</span><span class='Brace'>}</span>
- <span class='Function'>Pop</span> <span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Value'>𝕤</span><span class='Separator'>⋄</span><span class='Value'>v</span><span class='Gets'>←</span><span class='Value'>h.v</span><span class='Separator'>⋄</span><span class='Brace'>{</span><span class='Value'>t</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Value'>e</span><span class='Modifier2'>⊸</span><span class='Function'>=</span><span class='Paren'>)</span><span class='Value'>h</span><span class='Gets'>↩</span><span class='Value'>h.n</span><span class='Separator'>⋄</span><span class='Value'>v</span><span class='Brace'>}</span>
+ <span class='Function'>Pop</span> <span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Value'>𝕤</span><span class='Separator'>⋄</span><span class='Value'>v</span><span class='Gets'>←</span><span class='Value'>h.v</span><span class='Separator'>⋄</span><span class='Value'>h</span><span class='Gets'>↩</span><span class='Value'>h.n</span><span class='Separator'>⋄</span><span class='Brace'>{</span><span class='Value'>e</span><span class='Function'>=</span><span class='Value'>h</span><span class='Head'>?</span><span class='Value'>t</span><span class='Gets'>↩</span><span class='Value'>e</span><span class='Head'>;</span><span class='String'>@</span><span class='Brace'>}</span><span class='Separator'>⋄</span><span class='Value'>v</span><span class='Brace'>}</span>
<span class='Brace'>}</span>
</pre>
<p>Unlike a stack, a node's successor isn't known when it's created, and it has to be set. You might be inclined to make <code><span class='Value'>n</span></code> settable directly, but we'll get more mileage out of a setter function <code><span class='Function'>SetN</span></code>. This allows us to create a pseudo-node <code><span class='Value'>e</span></code> (for &quot;empty&quot;) indicating there are no values in the queue. Because it has no <code><span class='Value'>.v</span></code> field, if <code><span class='Value'>h</span></code> is <code><span class='Value'>e</span></code> then <code><span class='Function'>Pop</span></code> gives an error (but in a real implementation you'd want to test explicitly instead in order to give an appropriate error message). In fact it doesn't have an <code><span class='Value'>n</span></code> field, and essentially uses the queue head <code><span class='Value'>h</span></code> instead. With this empty &quot;node&quot;, the queue definition is straightforward. The only tricky part to remember is that if <code><span class='Function'>Pop</span></code> removes the last node, resulting in <code><span class='Value'>e</span><span class='Function'>=</span><span class='Value'>h</span></code>, then the tail has to be set to <code><span class='Value'>e</span></code> as well, or it will keep pointing to the removed node and cause bugs.</p>
@@ -137,7 +137,7 @@
<span class='Function'>Undo</span> <span class='Gets'>⇐</span> <span class='Value'>t.</span><span class='Function'>Move</span><span class='Modifier2'>∘</span><span class='Function'>⌽</span><span class='Modifier2'>∘</span><span class='Function'>Pop</span>
<span class='Brace'>}</span>
</pre>
-<p>This class composes a Tower of Hanoi with an undo stack that stores previous moves. To undo a move from <code><span class='Value'>a</span></code> to <code><span class='Value'>b</span></code>, it moves from <code><span class='Value'>b</span></code> to <code><span class='Value'>a</span></code>, although if you felt really fancy you might define <code><span class='Function'>Move</span><span class='Modifier'>⁼</span></code> in <code><span class='Value'>towerOfHanoi</span></code> instead with <code><span class='Function'>𝕊</span><span class='Modifier'>⁼</span><span class='Value'>𝕩</span><span class='Head'>:</span> <span class='Function'>𝕊⌽</span><span class='Value'>𝕩</span></code>.</p>
+<p>This class composes a Tower of Hanoi with an undo stack that stores previous moves. To undo a move from <code><span class='Value'>a</span></code> to <code><span class='Value'>b</span></code>, it moves from <code><span class='Value'>b</span></code> to <code><span class='Value'>a</span></code>, although if you felt really fancy you might define <code><span class='Function'>Move</span><span class='Modifier'>⁼</span></code> in <code><span class='Value'>towerOfHanoi</span></code> instead with an <a href="undo.html#undo-headers">undo header</a> <code><span class='Function'>𝕊</span><span class='Modifier'>⁼</span><span class='Value'>𝕩</span><span class='Head'>:</span> <span class='Function'>𝕊⌽</span><span class='Value'>𝕩</span></code>.</p>
<p>It's also possible to copy several variables and only export some of them, with an export statement. For example, if I wasn't going to make another method called <code><span class='Function'>Move</span></code>, I might have written <code><span class='Function'>View</span><span class='Ligature'>‿</span><span class='Function'>Move</span> <span class='Gets'>←</span> <span class='Value'>towerOfHanoi</span></code> and then <code><span class='Function'>View</span><span class='Gets'>⇐</span></code>. In fact, depending on your personal style and how complicated your classes are, you might prefer to avoid inline <code><span class='Gets'>⇐</span></code> exports entirely, and declare all the exports at the top.</p>
<h2 id="self-reference"><a class="header" href="#self-reference">Self-reference</a></h2>
<p>An object's class is given by <code><span class='Function'>𝕊</span></code>. Remember, a class is an ordinary BQN function! It might be useful for an object to produce another object of the same class (particularly if it's immutable), and an object might also expose a field <code><span class='Value'>class</span><span class='Gets'>⇐</span><span class='Value'>𝕤</span></code> to test whether an object <code><span class='Value'>o</span></code> belongs to a class <code><span class='Value'>c</span></code> with <code><span class='Value'>o.class</span> <span class='Function'>=</span> <span class='Value'>c</span></code>.</p>
@@ -145,14 +145,14 @@
<pre><span class='Function'>IntrospectiveClass</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='Value'>obj</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='Value'>this</span><span class='Gets'>⇐</span><span class='String'>@</span>
- <span class='Function'>SetThis</span> <span class='Gets'>⇐</span> <span class='Brace'>{</span> <span class='Function'>!</span><span class='Value'>this</span><span class='Function'>=</span><span class='String'>@</span> <span class='Separator'>⋄</span> <span class='Value'>this</span><span class='Gets'>↩</span><span class='Value'>𝕩</span> <span class='Brace'>}</span>
+ <span class='Function'>SetThis</span> <span class='Gets'>⇐</span> <span class='Brace'>{</span> <span class='Function'>!</span><span class='Value'>this</span><span class='Function'>≡</span><span class='String'>@</span> <span class='Separator'>⋄</span> <span class='Value'>this</span><span class='Gets'>↩</span><span class='Value'>𝕩</span> <span class='Brace'>}</span>
<span class='Brace'>}</span>
<span class='Value'>obj.setThis</span> <span class='Value'>obj</span>
<span class='Brace'>}</span>
</pre>
-<p>This is a pretty clunky solution, and exports a useless method <code><span class='Function'>SetThis</span></code> (which gives an error if it's ever called). It would be possible for BQN to define a system value <code><span class='Value'>•this</span></code> that just gets the namespace's value. It would work only at the top level, so it would have to be assigned (<code><span class='Value'>this</span><span class='Gets'>←</span><span class='Value'>•this</span></code>) in order to use it in functions. This means it's always used before the namespace is done being defined, so a drawback is that it introduces the possibility that an object used in a program has undefined fields. The reason this isn't possible for objects without <code><span class='Value'>•this</span></code> is that BQN's blocks don't have any sort of control flow, so that they always execute every statement in order. The namespace becomes accessible as a value once the block finishes, and at this point every statement has been executed and every field is initialized.</p>
+<p>This is a pretty clunky solution, and exports a useless method <code><span class='Function'>SetThis</span></code> (which gives an error if it's ever called). It would be possible for BQN to define a system value <code><span class='Value'>•this</span></code> that just gets the namespace's value. It would work only at the top level, so it would have to be assigned (<code><span class='Value'>this</span><span class='Gets'>←</span><span class='Value'>•this</span></code>) in order to use it in functions. This means it's always used before the namespace is done being defined, so a drawback is that it introduces the possibility that an object used in a program has undefined fields. Currently a namespace can only be created with all fields set: a block body doesn't have any sort of control flow other than the early exit <code><span class='Head'>?</span></code>, so it can only finish by executing every statement, including every field definition, in order.</p>
<h2 id="class-members"><a class="header" href="#class-members">Class members</a></h2>
-<p>As with <code><span class='Value'>this</span></code>, giving a class variables that belong to it is a do-it-yourself sort of thing (or more positively, not at all magic (funny how programmer jargon goes the opposite way to ordinary English)). It's an easy one though, as this is exactly what <a href="lexical.html">lexical scoping</a> does:</p>
+<p>As with <code><span class='Value'>this</span></code>, creating variables that belong to a class and not its objects is a do-it-yourself sort of thing (or more positively, not at all magic (funny how programmer jargon goes the opposite way to ordinary English)). It's an easy one though, as this is exactly what <a href="lexical.html">lexical scoping</a> does:</p>
<pre><span class='Value'>staticClass</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='Value'>counter</span> <span class='Gets'>←</span> <span class='Number'>0</span>
<span class='Brace'>{</span><span class='Value'>𝕤</span>
diff --git a/docs/doc/order.html b/docs/doc/order.html
index 58ed2583..a75c2600 100644
--- a/docs/doc/order.html
+++ b/docs/doc/order.html
@@ -7,21 +7,21 @@
<h1 id="ordering-functions"><a class="header" href="#ordering-functions">Ordering functions</a></h1>
<p>BQN has six functions that order arrays as part of their operation (the <a href="arithmetic.html#comparisons">comparison functions</a> <code><span class='Function'>≤&lt;&gt;≥</span></code> only order atoms, so they aren't included). These come in three pairs, where one of each pair uses an ascending ordering and the other uses a descending ordering.</p>
<ul>
-<li><code><span class='Function'>∨∧</span></code>, Sort, rearranges the argument to order it</li>
-<li><code><span class='Function'>⍒⍋</span></code>, Grade, outputs the permutation that Sort would use to rearrange it</li>
+<li><code><span class='Function'>∨∧</span></code>, Sort, puts major cells of <code><span class='Value'>𝕩</span></code> in order</li>
+<li><code><span class='Function'>⍒⍋</span></code>, Grade, outputs the permutation that Sort would use to rearrange <code><span class='Value'>𝕩</span></code></li>
<li><code><span class='Function'>⍒⍋</span></code>, Bins, takes an ordered <code><span class='Value'>𝕨</span></code> and determines where each cell of <code><span class='Value'>𝕩</span></code> fits in this ordering.</li>
</ul>
<p>The array ordering shared by all six is described last. For lists it's &quot;dictionary ordering&quot;: two lists are compared one element at a time until one runs out, and the shorter one comes first in case of a tie. Operation values aren't ordered, so if an argument to an ordering function has a function or modifier somewhere in it then it will fail unless all the orderings can be decided without checking that value.</p>
<p>You can't provide a custom ordering function to Sort. The function would have to be called on one pair of cells at a time, which is contrary to the idea of array programming, and passing in a function with side effects could lead to implementation-specific behavior. Instead, build another array that will sort in the order you want (for example, by selecting or deriving the property you want to sort on). Then Grade it, and use the result to select from the original array.</p>
<h2 id="sort"><a class="header" href="#sort">Sort</a></h2>
-<p>You've probably seen it before. Sort Up (<code><span class='Function'>∧</span></code>) reorders the major cells of its argument to place them in ascending order, and Sort Down (<code><span class='Function'>∨</span></code>) puts them in descending order. Every ordering function follows this naming convention—there's an &quot;Up&quot; version pointing up and a &quot;Down&quot; version going the other way.</p>
+<p>You've probably seen it before. Sort Up (<code><span class='Function'>∧</span></code>) reorders the <a href="array.html#cells">major cells</a> of its argument to place them in ascending order, and Sort Down (<code><span class='Function'>∨</span></code>) puts them in descending order. Every ordering function follows this naming convention—there's an &quot;Up&quot; version pointing up and a &quot;Down&quot; version going the other way.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oinICJkZWx0YSLigL8iYWxwaGEi4oC/ImJldGEi4oC/ImdhbW1hIgoK4oioICLOtM6xzrLOsyI=">↗️</a><pre> <span class='Function'>∧</span> <span class='String'>&quot;delta&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;alpha&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;beta&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;gamma&quot;</span>
⟨ "alpha" "beta" "delta" "gamma" ⟩
<span class='Function'>∨</span> <span class='String'>&quot;δαβγ&quot;</span>
"δγβα"
</pre>
-<p>Sort Down always <a href="match.html">matches</a> Sort Up <a href="reverse.html">reversed</a>, <code><span class='Function'>⌽</span><span class='Modifier2'>∘</span><span class='Function'>∧</span></code>. The reason for this is that BQN's array ordering is a <a href="https://en.wikipedia.org/wiki/Total_order">total order</a>, meaning that if one array doesn't come earlier or later than another array in the ordering then the two arrays match. Since any two non-matching argument cells are strictly ordered, they will have one ordering in <code><span class='Function'>∧</span></code> and the opposite ordering in <code><span class='Function'>∨</span></code>. With the reverse, any pair of non-matching cells are ordered the same way in <code><span class='Function'>⌽</span><span class='Modifier2'>∘</span><span class='Function'>∧</span></code> and <code><span class='Function'>∨</span></code>. Since these two results have the same major cells in the same order, they match. However, note that the results will not always behave identically because Match doesn't take <a href="fill.html">fill elements</a> into account (if you're curious, take a look at <code><span class='Function'>⊑</span><span class='Modifier'>¨</span><span class='Function'>∨</span><span class='Bracket'>⟨</span><span class='Function'>↕</span><span class='Number'>0</span><span class='Separator'>,</span><span class='String'>&quot;&quot;</span><span class='Bracket'>⟩</span></code> versus <code><span class='Function'>⊑</span><span class='Modifier'>¨</span><span class='Function'>⌽</span><span class='Modifier2'>∘</span><span class='Function'>∧</span><span class='Bracket'>⟨</span><span class='Function'>↕</span><span class='Number'>0</span><span class='Separator'>,</span><span class='String'>&quot;&quot;</span><span class='Bracket'>⟩</span></code>).</p>
+<p>Sort Down always <a href="match.html">matches</a> Sort Up <a href="reverse.html">reversed</a>, <code><span class='Function'>⌽</span><span class='Modifier2'>∘</span><span class='Function'>∧</span></code>. The reason for this is that BQN's array ordering is a <a href="https://en.wikipedia.org/wiki/Total_order">total order</a>, meaning that if one array doesn't come earlier or later than another array in the ordering then the two arrays match. Since any two non-matching argument cells are strictly ordered, they will have one ordering in <code><span class='Function'>∧</span></code> and the opposite ordering in <code><span class='Function'>∨</span></code>. After the reverse, any pair of non-matching cells are ordered the same way in <code><span class='Function'>⌽</span><span class='Modifier2'>∘</span><span class='Function'>∧</span></code> and <code><span class='Function'>∨</span></code>. Since these two results have the same major cells in the same order, they match. However, note that the results will not always behave identically because Match doesn't take <a href="fill.html">fill elements</a> into account (if you're curious, take a look at <code><span class='Function'>⊑</span><span class='Modifier'>¨</span><span class='Function'>∨</span><span class='Bracket'>⟨</span><span class='Function'>↕</span><span class='Number'>0</span><span class='Separator'>,</span><span class='String'>&quot;&quot;</span><span class='Bracket'>⟩</span></code> versus <code><span class='Function'>⊑</span><span class='Modifier'>¨</span><span class='Function'>⌽</span><span class='Modifier2'>∘</span><span class='Function'>∧</span><span class='Bracket'>⟨</span><span class='Function'>↕</span><span class='Number'>0</span><span class='Separator'>,</span><span class='String'>&quot;&quot;</span><span class='Bracket'>⟩</span></code>).</p>
<h2 id="grade"><a class="header" href="#grade">Grade</a></h2>
<svg viewBox='-186 -13.6 486 193.12'>
<g font-family='BQN,monospace' font-size='22px' text-anchor='middle'>
@@ -68,7 +68,7 @@
</g>
</svg>
-<p>Grade is more abstract than Sort. Rather than rearranging the argument's cells immediately, it returns a list of indices (more precisely, a permutation) giving the ordering that would sort them.</p>
+<p>Grade is more abstract than Sort. Rather than rearranging the argument's cells immediately, it returns a list of <a href="indices.html">indices</a> (more precisely, a permutation) giving the ordering that would sort them.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGwg4oaQICJwbGFuZXQi4oC/Im1vb24i4oC/InN0YXIi4oC/ImFzdGVyb2lkIgoK4oinIGwKCuKNiyBs">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>l</span> <span class='Gets'>←</span> <span class='String'>&quot;planet&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;moon&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;star&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;asteroid&quot;</span>
⟨ "planet" "moon" "star" "asteroid" ⟩
@@ -153,9 +153,9 @@
</pre>
<p>How does it work? First, let's note that <code><span class='Function'>⍋</span><span class='Value'>l</span></code> is a <em>permutation</em>: it contains exactly the numbers <code><span class='Function'>↕≠</span><span class='Value'>l</span></code>, possibly in a different order. In other words, <code><span class='Function'>∧⍋</span><span class='Value'>l</span></code> is <code><span class='Function'>↕≠</span><span class='Value'>l</span></code>. Permuting an array rearranges the cells but doesn't remove or duplicate any. This implies it's always invertible: given a permutation <code><span class='Value'>p</span></code>, some other permutation <code><span class='Value'>q</span></code> will have <code><span class='Value'>𝕩</span> <span class='Function'>≡</span> <span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> for every <code><span class='Value'>𝕩</span></code> of the right length. This would mean that while <code><span class='Function'>⍋</span><span class='Value'>l</span></code> transforms <code><span class='Value'>l</span></code> to <code><span class='Function'>∧</span><span class='Value'>l</span></code>, the inverse of <code><span class='Function'>⍋</span><span class='Value'>l</span></code> transforms <code><span class='Function'>∧</span><span class='Value'>l</span></code> back into <code><span class='Value'>l</span></code>. That's what we want: for each cell of <code><span class='Value'>l</span></code>, the corresponding number in the inverse of <code><span class='Function'>⍋</span><span class='Value'>l</span></code> is what index that cell has after sorting.</p>
<p>But what's the inverse <code><span class='Value'>q</span></code> of a permutation <code><span class='Value'>p</span></code>? Our requirement is that <code><span class='Value'>𝕩</span> <span class='Function'>≡</span> <span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span><span class='Function'>⊏</span><span class='Value'>𝕩</span></code> for any <code><span class='Value'>𝕩</span></code> with the same length as <code><span class='Value'>p</span></code>. Setting <code><span class='Value'>𝕩</span></code> to <code><span class='Function'>↕≠</span><span class='Value'>p</span></code> (the identity permutation), we have <code><span class='Paren'>(</span><span class='Function'>↕≠</span><span class='Value'>p</span><span class='Paren'>)</span> <span class='Function'>≡</span> <span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span></code>, because <code><span class='Value'>p</span><span class='Function'>⊏↕≠</span><span class='Value'>p</span></code> is just <code><span class='Value'>p</span></code>. But if <code><span class='Value'>p</span></code> is a permutation then <code><span class='Function'>∧</span><span class='Value'>p</span></code> is <code><span class='Function'>↕≠</span><span class='Value'>p</span></code>, so our requirement could also be written <code><span class='Paren'>(</span><span class='Function'>∧</span><span class='Value'>p</span><span class='Paren'>)</span> <span class='Function'>≡</span> <span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span></code>. Now it's all coming back around again. We know exactly how to get <code><span class='Value'>q</span></code>! Defining <code><span class='Value'>q</span><span class='Gets'>←</span><span class='Function'>⍋</span><span class='Value'>p</span></code>, we have <code><span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span> <span class='Value'>↔</span> <span class='Paren'>(</span><span class='Function'>⍋</span><span class='Value'>p</span><span class='Paren'>)</span><span class='Function'>⊏</span><span class='Value'>p</span> <span class='Value'>↔</span> <span class='Function'>∧</span><span class='Value'>p</span> <span class='Value'>↔</span> <span class='Function'>↕≠</span><span class='Value'>p</span></code>, and <code><span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span><span class='Function'>⊏</span><span class='Value'>𝕩</span> <span class='Value'>↔</span> <span class='Paren'>(</span><span class='Value'>q</span><span class='Function'>⊏</span><span class='Value'>p</span><span class='Paren'>)</span><span class='Function'>⊏</span><span class='Value'>𝕩</span> <span class='Value'>↔</span> <span class='Paren'>(</span><span class='Function'>↕≠</span><span class='Value'>p</span><span class='Paren'>)</span><span class='Function'>⊏</span><span class='Value'>𝕩</span> <span class='Value'>↔</span> <span class='Value'>𝕩</span></code>.</p>
-<p>The fact that Grade Up inverts a permutation is useful in itself. Note that this applies to Grade Up specifically, and not Grade Down. This is because the identity permutation is ordered in ascending order. Grade Down would actually invert the reverse of a permutation, which is unlikely to be useful. So the ordinals idiom that goes in the opposite direction is actually not <code><span class='Function'>⍒⍒</span></code> but <code><span class='Function'>⍋⍒</span></code>. The initial grade is different, but the way to invert it is the same.</p>
+<p>The fact that Grade Up inverts a permutation is useful in itself. Note that this applies to Grade Up specifically, and not Grade Down. This is because the identity permutation is ordered in ascending order. Grade Down would invert the reverse of a permutation, which is unlikely to be useful. So the ordinals idiom that goes in the opposite direction is actually not <code><span class='Function'>⍒⍒</span></code> but <code><span class='Function'>⍋⍒</span></code>. The initial grade is different, but the way to invert it is the same.</p>
<h3 id="stability"><a class="header" href="#stability">Stability</a></h3>
-<p>When sorting an array, we usually don't care how matching cells are ordered relative to each other (although it's possible to detect it by using fill elements carefully. They maintain their ordering). Grading is a different matter, because often the grade of one array is used to order another one.</p>
+<p>When sorting an array, we usually don't care how matching cells are ordered relative to each other (although as mentioned above it's possible to detect it by using fill elements carefully. They maintain their ordering). Grading is a different matter, because often the grade of one array is used to order another one.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIHQg4oaQID7in6ggImRvZyLigL80LCAiYW50IuKAvzYsICJwaWdlb24i4oC/MiwgInBpZyLigL80IOKfqQoKMSDiio/LmCB0CgooMeKKj8uYdCkg4o2L4oq44oqPIHQ=">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>t</span> <span class='Gets'>←</span> <span class='Function'>&gt;</span><span class='Bracket'>⟨</span> <span class='String'>&quot;dog&quot;</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Separator'>,</span> <span class='String'>&quot;ant&quot;</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Separator'>,</span> <span class='String'>&quot;pigeon&quot;</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Separator'>,</span> <span class='String'>&quot;pig&quot;</span><span class='Ligature'>‿</span><span class='Number'>4</span> <span class='Bracket'>⟩</span>
┌─
╵ "dog" 4
@@ -189,9 +189,8 @@
"210dcbaEDCBA"
</pre>
<h2 id="bins"><a class="header" href="#bins">Bins</a></h2>
-<p><em>There's also an <a href="https://aplwiki.com/wiki/Interval_Index">APL Wiki page</a> on this function, but be careful as the Dyalog version has subtle differences.</em></p>
<p>The two Bins functions are written with the same symbols <code><span class='Function'>⍋</span></code> and <code><span class='Function'>⍒</span></code> as Grade, but take two arguments instead of one. More complicated? A little, but once you understand Bins you'll find that it's a basic concept that shows up in the real world all the time.</p>
-<p>Bins behaves like a <a href="search.html">search function</a> with respect to rank: it looks up cells from <code><span class='Value'>𝕩</span></code> relative to major cells of <code><span class='Value'>𝕨</span></code>. However, there's an extra requirement: the left argument to Bins is already sorted according to whichever ordering is used. If it isn't, you'll get an error.</p>
+<p>Bins behaves like a <a href="search.html">search function</a> with respect to rank: it looks up <a href="array.html#cells">cells</a> from <code><span class='Value'>𝕩</span></code> relative to major cells of <code><span class='Value'>𝕨</span></code>. However, there's an extra requirement: the left argument to Bins must already be sorted according to whichever ordering is used. If it isn't, you'll get an error.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=NeKAvzbigL8y4oC/NOKAvzEg4o2LIDMKCjDigL8z4oC/NOKAvzfigL85IOKNkiAz">↗️</a><pre> <span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>6</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>1</span> <span class='Function'>⍋</span> <span class='Number'>3</span>
<span class='Error'>Error: ⍋: 𝕨 must be sorted</span>
@@ -208,10 +207,9 @@
<p>A score of <code><span class='Number'>565e7</span></code> sits between <code><span class='Number'>578e7</span></code> and <code><span class='Number'>553e7</span></code> at rank 3, <code><span class='Number'>322e7</span></code> wouldn't make the list, <code><span class='Number'>788e7</span></code> would beat everyone, and <code><span class='Number'>627e7</span></code> would tie the high score but not beat it. The same principles apply to less spring-loaded things like character indices and line numbers (<code><span class='Value'>𝕨</span></code> is the index of the start of each line), or percentage scores and letter grades on a test (<code><span class='Value'>𝕨</span></code> is the minimum score possible for each grade). In each case, it's better to think of Bins not as a counting exercise but as finding &quot;what bin&quot; something fits into.</p>
<h2 id="array-ordering"><a class="header" href="#array-ordering">Array ordering</a></h2>
<p>Most of the time you won't need to worry about the details of how BQN arrays are ordered. It's documented here because, well, that's what documentation does.</p>
-<p>The array ordering defines some arrays to be smaller or larger than others. All of the &quot;Up&quot; ordering functions use this ordering directly, so that smaller arrays come earlier, and the &quot;Down&quot; ones use the opposite ordering, with larger arrays coming earlier. For arrays consisting only of characters and numbers, with arbitrary nesting, the ordering is always defined. If an array contains an operation, trying to order it relative to another array might give an error. If comparing two arrays succeeds, there are three possibilities: the first array is smaller, the second is smaller, or the two arrays <a href="match.html">match</a>.</p>
-<p>Comparing two atoms is defined to work the same way as the <a href="arithmetic.html#comparisons">comparison functions</a> <code><span class='Function'>≤&lt;&gt;≥</span></code>. Numbers come earlier than characters and otherwise these two types are ordered in the obvious way. To compare an atom to an array, the atom enclosing and then compared with the array ordering defined below. The result of this comparison is used except when the two arrays match: in that case, the atom is considered smaller.</p>
-<p>Two arrays of the same shape are compared by comparing all their corresponding elements, in index order. This comparison can stop at the first pair of different elements (which allows later elements to contain operations without causing an error). If any elements were different, then they decide the result of the comparison. If all the elements matched, then by definition the two arrays match.</p>
+<p>BQN's <em>array ordering</em> is an extension of the number and character ordering given by <code><span class='Function'>≤</span></code> to <a href="array.html">arrays</a>. In this system, any two arrays that have only numbers and characters for atoms can be compared with each other. Furthermore, some arrays that contain incomparable atoms (operations or namespaces) might be comparable, if the result of the comparison can be decided before reaching these atoms. Array ordering never depends on <a href="fill.html">fill elements</a>. If comparing two arrays succeeds, there are three possibilities: the first array is smaller, the second is smaller, or the two arrays <a href="match.html">match</a>. All of the &quot;Up&quot; ordering functions use this ordering directly, so that smaller arrays come earlier, and the &quot;Down&quot; ones use the opposite ordering, with larger arrays coming earlier.</p>
+<p>Comparing two atoms is defined to work the same way as the <a href="arithmetic.html#comparisons">comparison functions</a> <code><span class='Function'>≤&lt;&gt;≥</span></code>. Numbers come earlier than characters and otherwise these two types are ordered in the obvious way. To compare an atom to an array, the atom is enclosed and then compared with the array ordering defined below. The result of this comparison is used except when the two arrays match: in that case, the atom is considered smaller.</p>
+<p>Two arrays of the same shape are compared by comparing all their corresponding elements, in index order. This comparison stops at the first pair of different elements (which allows later elements to contain operations without causing an error). If any elements were different, then they decide the result of the comparison. If all the elements matched, then by definition the two arrays match.</p>
<p>The principle for arrays of different shapes is the same, but there are two factors that need to be taken into account. First, it's not obvious any more what it means to compare corresponding elements—what's the correspondence? Second, the two arrays can't match because they have different shapes. So even if all elements end up matching one of them needs to come earlier.</p>
-<p>BQN's <em>array ordering</em> is an extension of the number and character ordering given by <code><span class='Function'>≤</span></code> to arrays. In this system, any two arrays consisting of only numbers and characters for atoms can be compared with each other. Furthermore, some arrays that contain incomparable atoms (operations) might be comparable, if the result of the comparison can be decided before reaching these atoms. Array ordering does not depend on the fill elements for the two arguments.</p>
<p>Let's discuss correspondence first. One way to think about how BQN makes arrays correspond is that they're simply laid on top of each other, lining up the first (as in <code><span class='Function'>⊑</span></code>) elements. So a shape <code><span class='Bracket'>⟨</span><span class='Number'>4</span><span class='Bracket'>⟩</span></code> array will match up with the first row of a shape <code><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>3</span></code> array, but have an extra element off the end. A simple way to think about this is to say that the lower rank array is brought up to a matching rank by putting <code><span class='Number'>1</span></code>s in front of the shape, and then lengths along each axis are matched up by padding the shorter array along that axis with a special &quot;nothing&quot; element. This &quot;nothing&quot; element will be treated as smaller than any actual array, because this rule recovers the &quot;dictionary ordering&quot; rule that a word that's a prefix of a longer word comes before that word. In the case of the shapes <code><span class='Bracket'>⟨</span><span class='Number'>4</span><span class='Bracket'>⟩</span></code> and <code><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>3</span></code>, if the three overlapping elements match then the fourth element comes from the first row and is present in the first array but not the second. So the shape <code><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>3</span></code> array would be considered smaller without even looking at its other four rows.</p>
<p>It can happen that two arrays of different shape have all matching elements with this procedure: either because one array's shape is the same as the other's but with some extra <code><span class='Number'>1</span></code>s at the beginning, or because both arrays are empty. In this case, the arrays are compared first by rank, with the higher-rank array considered larger, and then by shape, beginning with the leading axes.</p>
diff --git a/docs/doc/pair.html b/docs/doc/pair.html
index a3a3a33e..40d153e6 100644
--- a/docs/doc/pair.html
+++ b/docs/doc/pair.html
@@ -39,7 +39,7 @@
⟨ 9 3 18 2 ⟩
</pre>
<h2 id="pair-versus-couple"><a class="header" href="#pair-versus-couple">Pair versus Couple</a></h2>
-<p>Enlist and Pair closely related to <a href="couple.html">Solo and Couple</a>, in that <code><span class='Function'>⋈</span></code> is equivalent to <code><span class='Function'>≍</span><span class='Modifier2'>○</span><span class='Function'>&lt;</span></code> and <code><span class='Function'>≍</span></code> is equivalent to <code><span class='Function'>&gt;</span><span class='Modifier2'>∘</span><span class='Function'>⋈</span></code>. However, the result of <code><span class='Function'>⋈</span></code> is always a list (rank 1) while Solo or Couple return an array of rank at least 1.</p>
+<p>Enlist and Pair are closely related to <a href="couple.html">Solo and Couple</a>, in that <code><span class='Function'>⋈</span></code> is equivalent to <code><span class='Function'>≍</span><span class='Modifier2'>○</span><span class='Function'>&lt;</span></code> and <code><span class='Function'>≍</span></code> is equivalent to <code><span class='Function'>&gt;</span><span class='Modifier2'>∘</span><span class='Function'>⋈</span></code>. However, the result of <code><span class='Function'>⋈</span></code> is always a list (rank 1) while Solo or Couple return an array of rank at least 1.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ImFiYyIg4omNICJkZWYiCgoiYWJjIiDii4ggImRlZiI=">↗️</a><pre> <span class='String'>&quot;abc&quot;</span> <span class='Function'>≍</span> <span class='String'>&quot;def&quot;</span>
┌─
╵"abc
@@ -56,7 +56,7 @@
<span class='String'>&quot;abc&quot;</span> <span class='Function'>⋈</span> <span class='String'>&quot;defg&quot;</span>
⟨ "abc" "defg" ⟩
</pre>
-<p>The difference is that Couple treats the arguments as cells, and adds a dimension, while Pair treats them as elements, adding a layer of depth. Couple is a &quot;flat&quot; version of Pair, much like Cells (<code><span class='Modifier'>˘</span></code>) is a flat version of Each (<code><span class='Modifier'>¨</span></code>). Pair is more versatile, but—precisely because of its restrictions—Couple may allow more powerful array operations on the result.</p>
+<p>The difference is that Couple treats the arguments as <a href="array.html#cell">cells</a>, and adds a dimension, while Pair treats them as elements, adding a layer of depth. Couple is a &quot;flat&quot; version of Pair, much like <a href="rank.html#cells">Cells</a> (<code><span class='Modifier'>˘</span></code>) is a flat version of <a href="map.html#each">Each</a> (<code><span class='Modifier'>¨</span></code>). Pair is more versatile, but—precisely because of its restrictions—Couple may allow more powerful array operations on the result.</p>
<h2 id="fill-element"><a class="header" href="#fill-element">Fill element</a></h2>
<p>Enlist and Pair set the result's <a href="fill.html">fill</a> element, while list notation doesn't have to. So the following result is guaranteed:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=NCDihpEgImEi4oC/NSDii4ggImIi4oC/Nw==">↗️</a><pre> <span class='Number'>4</span> <span class='Function'>↑</span> <span class='String'>&quot;a&quot;</span><span class='Ligature'>‿</span><span class='Number'>5</span> <span class='Function'>⋈</span> <span class='String'>&quot;b&quot;</span><span class='Ligature'>‿</span><span class='Number'>7</span>
diff --git a/docs/doc/paradigms.html b/docs/doc/paradigms.html
index 5542f213..145de26c 100644
--- a/docs/doc/paradigms.html
+++ b/docs/doc/paradigms.html
@@ -9,13 +9,13 @@
<p>This information doesn't tell you what tasks BQN is good for: after all, it turns out you can write an efficient compiler entirely using array programming, something many people assumed was impossible. Instead, it tells you what approaches you can take to writing programs, and how comfortable you'll find it to start using BQN—or how much you can use it to stretch your brain in new directions.</p>
<p>When programming in BQN, I almost always use array, tacit, and (slightly impure) functional styles, and encapsulate code in medium or large projects using namespaces. I sometimes use object-oriented or imperative programming in addition to these.</p>
<h2 id="typing"><a class="header" href="#typing">Typing</a></h2>
-<p>BQN is a <strong>dynamically typed</strong> language with a coarse <a href="types.html">type system</a> that only distinguishes types when the difference is blindingly obvious. There is a single numeric type and a single unicode character type. A fast implementation such as CBQN will check to see when it can represent the data with a smaller type than the one offered by the language. BQN usually avoids implicit type conversion, with the exception that many primitives automatically convert atoms to unit arrays. The fact that a data value can be applied as a function to return itself could also be considered an implicit conversion.</p>
+<p>BQN is a <strong>dynamically typed</strong> language with a coarse <a href="types.html">type system</a> that only distinguishes types when the difference is blindingly obvious. There is a single numeric type and a single Unicode character type. A fast implementation such as CBQN will check to see when it can represent the data with a smaller type than the one offered by the language. BQN usually avoids implicit type conversion, with the exception that many primitives automatically convert atoms to unit arrays. The fact that a data value can be applied as a function to return itself could also be considered an implicit conversion.</p>
<p>BQN has no &quot;pointer&quot; or &quot;reference&quot; type, and uses <strong>automatic memory management</strong>. Its data types are <strong>immutable</strong> while operations and namespaces are <a href="lexical.html#mutation">mutable</a>; mutable data can create reference loops, which the implementation must account for in garbage collection but the programmer doesn't have to worry about.</p>
<p>Dynamic types and garbage collection introduce overhead relative to a statically-typed or manually managed language. The impact of this overhead can be greatly reduced with array programming, because an array of numbers or characters can be stored as a single unit of memory and processed with functions specialized to its element type.</p>
<h2 id="styles"><a class="header" href="#styles">Styles</a></h2>
<p>BQN is designed for <strong>array</strong> programming. The array is its only built-in collection type and it has many primitives designed to work with arrays.</p>
-<p>BQN is okay for <strong>imperative</strong> programming. Blocks are lists of statements. Variables can be modified with <code><span class='Gets'>↩</span></code>, and while there are no truly global variables, <a href="lexical.html">lexical scoping</a> allows variables at the top level of a file, which are similar (<code><span class='Function'>•Import</span></code> with no left argument saves and reuses results, so that data can be shared between files by loading the same namespace-defining file in each). BQN doesn't directly support <strong>structured</strong> programming (which refers to a particular way to structure programs; it also doesn't have a Goto statement, the &quot;unstructured&quot; alternative when the term was coined). However, its first-class functions allow a reasonably similar <a href="control.html">imitation</a> of control structures.</p>
-<p><strong>Functional</strong> programming is a term with many meanings. Using the terms defined in the <a href="functional.html">functional programming document</a>, BQN supports first-class functions and function-level programming, allows but doesn't encourage pure functional programming, and does not support typed functional programming. BQN uses <strong>lexical scope</strong> and has full support for <strong>closures</strong>. In this way BQN is very similar to Lisp, although it lacks Lisp's macro system.</p>
+<p>BQN is okay for <strong>imperative</strong> programming. Blocks are lists of statements. Variables can be modified with <code><span class='Gets'>↩</span></code>, and while there are no truly global variables, <a href="lexical.html">lexical scoping</a> allows variables at the top level of a file, which are similar (<code><span class='Function'>•Import</span></code> with no left argument saves and reuses results, so that data can be shared between files by loading the same namespace-defining file in each). BQN doesn't directly support <strong>structured</strong> programming (which refers to a particular way to structure programs; it also doesn't have a Go-to statement, the &quot;unstructured&quot; alternative when the term was coined). However, its first-class functions allow a reasonably similar <a href="control.html">imitation</a> of control structures.</p>
+<p><strong>Functional</strong> programming is a term with many meanings. Using the terms defined in the <a href="functional.html">page on functional programming</a>, BQN supports first-class functions and function-level programming, allows but doesn't encourage pure functional programming, and does not support typed functional programming. BQN uses <strong>lexical scope</strong> and has full support for <strong>closures</strong>. In this way BQN is very similar to Lisp, although it lacks Lisp's macro system.</p>
<p>BQN has excellent <a href="tacit.html">support</a> for <strong>tacit</strong> or <strong>point-free</strong> programming, with <a href="train.html">trains</a> and intuitive symbols for combinators making it much easier to work with (in my opinion) than other languages that support this style. It's near-universally considered a poor choice to implement entire programs in a tacit style, so this paradigm is best used as a small-scale tool within a style like functional or object-oriented programming.</p>
<p>BQN uses <a href="namespace.html">namespaces</a> as <strong>modules</strong> to organize code; the only possible interaction with a module is by its exported variables. There doesn't seem to be a name for this paradigm, but there should be.</p>
<p>BQN supports <strong>object-oriented</strong> programming <a href="oop.html">only incidentally</a>. This is not as bad as it sounds, and programming with objects in BQN can often feel pretty similar to other object-based languages. The main differences are that objects don't have a <code><span class='Value'>this</span></code> property to pass themselves into functions, and there's no built-in way to find the class of an object. There is also no support for inheritance, which is not unheard of in the object-oriented world.</p>
diff --git a/docs/doc/pick.html b/docs/doc/pick.html
index 275b623a..060dcdc1 100644
--- a/docs/doc/pick.html
+++ b/docs/doc/pick.html
@@ -6,7 +6,7 @@
<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="pick"><a class="header" href="#pick">Pick</a></h1>
<p>Pick (<code><span class='Function'>⊑</span></code>) chooses elements from <code><span class='Value'>𝕩</span></code> based on <a href="indices.html">index</a> lists from <code><span class='Value'>𝕨</span></code>. <code><span class='Value'>𝕨</span></code> can be a plain list, or even one number if <code><span class='Value'>𝕩</span></code> is a list, in order to get one element from <code><span class='Value'>𝕩</span></code>. It can also be an array of index lists, or have deeper array structure: each index list will be replaced with the element of <code><span class='Value'>𝕩</span></code> at that index, effectively applying to <code><span class='Value'>𝕨</span></code> at <a href="depth.html#the-depth-modifier">depth</a> 1.</p>
-<p>With no <code><span class='Value'>𝕨</span></code>, monadic <code><span class='Function'>⊑</span><span class='Value'>𝕩</span></code> takes the first element of <code><span class='Value'>𝕩</span></code> in index order, with an error if <code><span class='Value'>𝕩</span></code> is empty.</p>
+<p>The one-argument form is called First, and <code><span class='Function'>⊑</span><span class='Value'>𝕩</span></code> takes the first element of <code><span class='Value'>𝕩</span></code> in index order, with an error if <code><span class='Value'>𝕩</span></code> is empty.</p>
<p>While sometimes &quot;scatter-point&quot; indexing is necessary, using Pick to select multiple elements from <code><span class='Value'>𝕩</span></code> is less array-oriented than <a href="select.html">Select</a> (<code><span class='Function'>⊏</span></code>), and probably slower. Consider rearranging your data so that you can select along axes instead of picking out elements.</p>
<h2 id="one-element"><a class="header" href="#one-element">One element</a></h2>
<p>When the left argument is a number, Pick gets an element from a list:</p>
@@ -23,7 +23,7 @@
<span class='Number'>¯2</span> <span class='Function'>⊑</span> <span class='String'>&quot;abc&quot;</span>
'b'
</pre>
-<p>Making <code><span class='Value'>𝕩</span></code> a list is only a special case. In general <code><span class='Value'>𝕨</span></code> can be a list of numbers whose length is <code><span class='Value'>𝕩</span></code>'s rank. So when <code><span class='Function'>=</span><span class='Value'>𝕩</span></code> is 1, <code><span class='Value'>𝕨</span></code> can be length-1 list. For convenience, a number is also allowed, but not an enclosed number (which could be confused with the nested case).</p>
+<p>Making <code><span class='Value'>𝕩</span></code> a list is only a special case. In general <code><span class='Value'>𝕨</span></code> can be a list of numbers whose length is <code><span class='Value'>𝕩</span></code>'s rank. So when <code><span class='Function'>=</span><span class='Value'>𝕩</span></code> is 1, <code><span class='Value'>𝕨</span></code> can be length-1 list. The case above where <code><span class='Value'>𝕨</span></code> is a number is a simplification, but an enclosed number <code><span class='Value'>𝕨</span></code> isn't allowed because it could be confused with the nested case described below.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+oMiww4p+pIOKKkSDihpU04oC/NQ==">↗️</a><pre> <span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Bracket'>⟩</span> <span class='Function'>⊑</span> <span class='Function'>↕</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>5</span>
⟨ 2 0 ⟩
</pre>
@@ -40,14 +40,14 @@
<span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>¯1</span> <span class='Function'>⊑</span> <span class='Value'>a</span>
'j'
</pre>
-<p>This applies even if <code><span class='Value'>𝕩</span></code> is a unit. By definition it has rank 0, so the only possible value for <code><span class='Value'>𝕨</span></code> is the empty list. This extracts an <a href="enclose.html">enclosed</a> element, and returns an atom unchanged—the atom is promoted to an array by enclosing it, then the action of Pick undoes this. But there's rarely a reason to use this case, because the monadic form First accomplishes the same thing.</p>
+<p><code><span class='Value'>𝕩</span></code> can even be a <a href="enclose.html#whats-a-unit">unit</a>. By definition it has rank 0, so the only possible value for <code><span class='Value'>𝕨</span></code> is the empty list. This extracts an <a href="enclose.html">enclosed</a> element, and returns an atom unchanged—the atom is promoted to an array by enclosing it, then the action of Pick undoes this. But there's rarely a reason to use this case, because the monadic form First accomplishes the same thing.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4p+o4p+pIOKKkSA8J2EnCuKfqOKfqSDiipEgJ2En">↗️</a><pre> <span class='Bracket'>⟨⟩</span> <span class='Function'>⊑</span> <span class='Function'>&lt;</span><span class='String'>'a'</span>
'a'
<span class='Bracket'>⟨⟩</span> <span class='Function'>⊑</span> <span class='String'>'a'</span>
'a'
</pre>
<h3 id="first"><a class="header" href="#first">First</a></h3>
-<p>With no left argument, <code><span class='Function'>⊑</span></code> is called First, and performs a slight generalization of Pick with a default left argument <code><span class='Number'>0</span><span class='Modifier'>¨</span><span class='Function'>≢</span><span class='Value'>𝕩</span></code>. For a non-empty array it returns the first element in index order.</p>
+<p>With no left argument, <code><span class='Function'>⊑</span></code> is called First, and is the same as Pick with a default left argument <code><span class='Number'>0</span><span class='Modifier'>¨</span><span class='Function'>≢</span><span class='Value'>𝕩</span></code>. For a non-empty array it returns the first element in index order.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqRIDwnYScK4oqRICJGaXJzdCIK4oqRIOKGlTTigL8y4oC/NeKAvzE=">↗️</a><pre> <span class='Function'>⊑</span> <span class='Function'>&lt;</span><span class='String'>'a'</span>
'a'
<span class='Function'>⊑</span> <span class='String'>&quot;First&quot;</span>
@@ -55,9 +55,10 @@
<span class='Function'>⊑</span> <span class='Function'>↕</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>1</span>
⟨ 0 0 0 0 ⟩
</pre>
-<p>If <code><span class='Value'>𝕩</span></code> is empty then First results in an error, like Pick.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqRICIiCuKKkSDiiaLPgA==">↗️</a><pre> <span class='Function'>⊑</span> <span class='String'>&quot;&quot;</span>
+<p>And if <code><span class='Value'>𝕩</span></code> is empty then First results in an error.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqRICIiCgriipEg4omiz4A=">↗️</a><pre> <span class='Function'>⊑</span> <span class='String'>&quot;&quot;</span>
<span class='Error'>Error: ⊑: Argument cannot be empty</span>
+
<span class='Function'>⊑</span> <span class='Function'>≢</span><span class='Number'>π</span>
<span class='Error'>Error: ⊑: Argument cannot be empty</span>
</pre>