diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-07-04 22:25:39 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-07-04 22:25:39 -0400 |
| commit | df5ddc0ed2fe48411645228c6e2d596be239a0c6 (patch) | |
| tree | 3a18a3674130c5aa646ac23106de3570eb03ae8d /doc/fill.md | |
| parent | 81c0f0844edeb2a92f6644455c100700cab6c3c8 (diff) | |
A few edits more
Diffstat (limited to 'doc/fill.md')
| -rw-r--r-- | doc/fill.md | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/doc/fill.md b/doc/fill.md index d330537a..d33c0d85 100644 --- a/doc/fill.md +++ b/doc/fill.md @@ -4,19 +4,19 @@ A few array operations need an array element to use when no existing element applies. BQN tries to maintain a "default" element for every array, known as a fill element, for this purpose. If it's known, the fill element is a nested array structure where each atom is either `0` or `' '`. If no fill is known, a function that requests it results in an error. -Fills are used by [Take](take.md) (`β`) when a value in `π¨` is larger than the corresponding length in `π©`, by the two [Nudge](shift.md) functions (`»«`) when `π©` is non-empty, by [Merge](couple.md) (`>`) when `π©` is empty, and by [Reshape](reshape.md) (`β₯`) when `π¨` contains `β`. Except for these specific cases, the fill value an array has can't affect the program. The result of [Match](match.md) (`β‘`) doesn't depend on fills, and any attempt to compute a fill can't cause side effects. +Fills are used by [Take](take.md) (`β`) when a value in `π¨` is larger than the corresponding length in `π©` and [Reshape](reshape.md) (`β₯`) when `π¨` contains `β`, by the two [Nudge](shift.md) functions (`»«`) when `π©` is non-empty, by [Merge](couple.md) (`>`) and [Join](join.md) when `π©` is empty, and by [Cells and Rank](rank.md) when the result has an empty frame. These are the only ways that an array's fill value can affect the program. The result of [Match](match.md) (`β‘`) doesn't depend on fills, and any attempt to compute a fill can't cause side effects. ## Using fills -For the examples in this section we'll use the fact that an all-number array usually has `0` as a fill while a string has `' '` (BQN maintains fills alongside array values rather than deriving them from arrays, so it's possible to construct arrays where this isn't true, but this probably wouldn't happen in ordinary code). +For the examples in this section we'll use the fact that an all-number array usually has `0` as a fill while a string has `' '` (it's not too rare to end up with such an array that has no fill, and possible but very unusual for an array to have a fill that conflicts with those rules). -[Take](take.md) (`β`) and [Nudge](shift.md) (`»«`) in either direction use the fill for padding, to extend the array past its boundary. For example, `π¨βπ©` will add elements to one side when a number in `|π¨` is larger than the corresponding length in `β’π©`. +[Take](take.md) (`β`) and [Nudge](shift.md) (`»«`) in either direction use the fill for padding, to extend the array past its boundary. For example, `π¨βπ©` adds elements to one side if a number in `|π¨` is larger than the corresponding length in `β’π©`. Β―7 β 4β₯3 # Fill with 0 Β―7 β "qrst" # Fill with space -Nudge Left or Right shifts the array over and places a fill in the vacated space, effectively extending it backwards by one. If `π©` is empty then it shouldn't give an error, but it's safer not to rely on this. +Nudge Left or Right shifts the array over and places a fill in the vacated space. If `π©` is empty then it doesn't need the fill and can't error. Ȭ β¨4β₯3,"qrst"β© @@ -24,8 +24,6 @@ Nudge Left or Right shifts the array over and places a fill in the vacated space Β»β¨β© # Fill not needed -If the argument to [Merge](couple.md) is empty then its result will be as well, since the shape `β’π©` is a prefix of `β’>π©`. However, the remainder of the result shape is determined by the elements of `π©`, so if there are none then Merge uses the fill element to decide what the result shape should be. - [Reshape](reshape.md#computed-lengths) (`β₯`) uses the fill when `π¨` contains `β` and the product of the rest of `π¨` doesn't evenly divide the number of elements in `π©`. ββΏ8 β₯ "completepart" @@ -34,19 +32,33 @@ If for some reason you need to find an array's fill element, the easiest general βΒ»1ββ₯"string" +## Edge cases + +The above functions use the fill as part of their core definition. A few other functions use fills only when they encounter empty arrays. The goal of this behavior is to make programs working on empty arrays more similar to the non-empty case, so if all goes well you don't need to be thinking about these cases. + +If the argument to [Merge](couple.md) is empty then its result will be as well, since the shape `β’π©` is a prefix of `β’>π©`. However, the remainder of the result shape is determined by the elements of `π©`, so if there are none then Merge uses the fill element to decide what the result shape should be. [Join](join.md) is similar, although it multiplies the shape of `π©` by the leading shape of the fill instead of concatenating them. + + β’ > 2βΏ0β₯<3βΏ4βΏ1β₯0 + + β’ βΎ 2βΏ0β₯<3βΏ4βΏ1β₯0 + +[Cells and Rank](rank.md) rely on fills in a slightly more complicated way. If one of the argument frames is empty, that means the result will be empty, but the shape of a result cell still needs to be known to determine its shape (and similarly for the fill, but that's optional). BQN implementations may try to find it by running `π½` using a cell of fills for the argument. As in Each (`Β¨`) described below, this evaluation is not allowed to produce side effects. If it doesn't work, the result cell shape is assumed to be `β¨β©`. + + β’ β½Λ β0βΏ4βΏ3 # Shape is determined by fills + ## How fills are computed For the exact requirements placed on fill, see [the specification](../spec/inferred.md#fill-elements) (particularly "required functions"). This section loosely describes behavior in existing BQN implementations, and includes some parts that aren't required in the specification. A fill element should encompass something that's necessarily true for all elements of an array. If the way an array is computed implies it's all numbers, the fill should be `0`. If every element is a list of two numbers, then the fill should be `β¨0,0β©`. If every element is a list but the lengths might vary, `β¨β©` is probably a reasonable fill element. -For [arithmetic](arithmetic.md) primitives, the fill is found by the rules of pervasion, applying the function to both argument fills. Generally this means it consists of `0`, but character arithmetic also allows space fills. +For [arithmetic](arithmetic.md) primitives, the fill is found by the rules of pervasion, applying the function to both argument fills. Generally this means it consists of `0`, but [character arithmetic](arithmetic.md#character-arithmetic) can produce space for a fill value. Β» "abc" + 4βΏ3βΏ2 [Mapping](map.md) modifiers Each and Table (`Β¨β`) might try to follow a similar strategy, applying `π½` to argument fills to obtain the result fill. The absolute rule here is that this computation can't cause side effects or an error, so for a complicated `π½` such as a block function this procedure is likely to be aborted to avoid disrupting the rest of the program. -Most other primitives fit in one of three broad categories as shown in the table below. Structural primitives, indicated by `β’`, don't change the fill of `π©`. Combining structural primitives, indicated by `β©`, only depend on the fill of all combined arraysβelements of `π©` in the one-argument case, or `π¨` and `π©` in the two-argument case. Finally, many functions such as [search functions](search.md) return only numbers and have a fill of `0`. +Most other primitives fit in one of three broad categories as shown in the table below. Structural primitives, indicated by `β’`, don't change the fill of `π©`. Combining structural primitives, indicated by `β©`, only depend on the fill of all combined arraysβelements of `π©` in the one-argument case, or `π¨` and `π©` in the two-argument case. If these fills are the same value, then that's the fill; otherwise, the result has no fill. Finally, many functions such as [search functions](search.md) return only arrays of numbers and have a fill of `0`. | Fill | Monads | Dyads | Modifiers |--------|--------------|-------------|---------- |
