1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
<head>
<link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/>
<link href="../style.css" rel="stylesheet"/>
<title>BQN: Fill elements</title>
</head>
<div class="nav">(<a href="https://github.com/mlochbaum/BQN">github</a>) / <a href="../index.html">BQN</a> / <a href="index.html">doc</a></div>
<h1 id="fill-elements"><a class="header" href="#fill-elements">Fill elements</a></h1>
<p>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 <code><span class='Number'>0</span></code> or <code><span class='String'>' '</span></code>. If no fill is known, a function that requests it results in an error.</p>
<p>Fills are used by <a href="take.html">Take</a> (<code><span class='Function'>β</span></code>) when a value in <code><span class='Value'>π¨</span></code> is larger than the corresponding length in <code><span class='Value'>π©</span></code> and <a href="reshape.html">Reshape</a> (<code><span class='Function'>β₯</span></code>) when <code><span class='Value'>π¨</span></code> contains <code><span class='Function'>β</span></code>, by the two <a href="shift.html">Nudge</a> functions (<code><span class='Function'>»«</span></code>) when <code><span class='Value'>π©</span></code> is non-empty, by <a href="couple.html">Merge</a> (<code><span class='Function'>></span></code>) and <a href="join.html">Join</a> when <code><span class='Value'>π©</span></code> is empty, and by <a href="rank.html">Cells and Rank</a> 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 <a href="match.html">Match</a> (<code><span class='Function'>β‘</span></code>) doesn't depend on fills, and any attempt to compute a fill can't cause side effects.</p>
<h2 id="using-fills"><a class="header" href="#using-fills">Using fills</a></h2>
<p>For the examples in this section we'll use the fact that an all-number array usually has <code><span class='Number'>0</span></code> as a fill while a string has <code><span class='String'>' '</span></code> (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).</p>
<p><a href="take.html">Take</a> (<code><span class='Function'>β</span></code>) and <a href="shift.html">Nudge</a> (<code><span class='Function'>»«</span></code>) in either direction use the fill for padding, to extend the array past its boundary. For example, <code><span class='Value'>π¨</span><span class='Function'>β</span><span class='Value'>π©</span></code> adds elements to one side if a number in <code><span class='Function'>|</span><span class='Value'>π¨</span></code> is larger than the corresponding length in <code><span class='Function'>β’</span><span class='Value'>π©</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=wq83IOKGkSA04qWKMyAgICAgIyBGaWxsIHdpdGggMAoKwq83IOKGkSAicXJzdCIgICMgRmlsbCB3aXRoIHNwYWNl">βοΈ</a><pre> <span class='Number'>Β―7</span> <span class='Function'>β</span> <span class='Number'>4</span><span class='Function'>β₯</span><span class='Number'>3</span> <span class='Comment'># Fill with 0
</span>β¨ 0 0 0 3 3 3 3 β©
<span class='Number'>Β―7</span> <span class='Function'>β</span> <span class='String'>"qrst"</span> <span class='Comment'># Fill with space
</span>" qrst"
</pre>
<p>Nudge Left or Right shifts the array over and places a fill in the vacated space. If <code><span class='Value'>π©</span></code> is empty then it doesn't need the fill and can't error.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=wrvCqCDin6g04qWKMywicXJzdCLin6kKCjPihpHin6jin6kgICMgRmlsbCB1bmtub3duCgrCu+KfqOKfqSAgICMgRmlsbCBub3QgbmVlZGVk">βοΈ</a><pre> <span class='Function'>Β»</span><span class='Modifier'>Β¨</span> <span class='Bracket'>β¨</span><span class='Number'>4</span><span class='Function'>β₯</span><span class='Number'>3</span><span class='Separator'>,</span><span class='String'>"qrst"</span><span class='Bracket'>β©</span>
β¨ β¨ 0 3 3 3 β© " qrs" β©
<span class='Number'>3</span><span class='Function'>β</span><span class='Bracket'>β¨β©</span> <span class='Comment'># Fill unknown
</span>β¨ 0 0 0 β©
<span class='Function'>Β»</span><span class='Bracket'>β¨β©</span> <span class='Comment'># Fill not needed
</span>β¨β©
</pre>
<p><a href="reshape.html#computed-lengths">Reshape</a> (<code><span class='Function'>β₯</span></code>) uses the fill when <code><span class='Value'>π¨</span></code> contains <code><span class='Function'>β</span></code> and the product of the rest of <code><span class='Value'>π¨</span></code> doesn't evenly divide the number of elements in <code><span class='Value'>π©</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oaR4oC/OCDipYogImNvbXBsZXRlcGFydCI=">βοΈ</a><pre> <span class='Function'>β</span><span class='Ligature'>βΏ</span><span class='Number'>8</span> <span class='Function'>β₯</span> <span class='String'>"completepart"</span>
ββ
β΅"complete
part "
β
</pre>
<p>If for some reason you need to find an array's fill element, the easiest general way is probably <code><span class='Function'>βΒ»</span><span class='Number'>1</span><span class='Function'>ββ₯</span><span class='Value'>a</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqRwrsx4oaR4qWKInN0cmluZyI=">βοΈ</a><pre> <span class='Function'>βΒ»</span><span class='Number'>1</span><span class='Function'>ββ₯</span><span class='String'>"string"</span>
' '
</pre>
<h2 id="edge-cases"><a class="header" href="#edge-cases">Edge cases</a></h2>
<p>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.</p>
<p>If the argument to <a href="couple.html">Merge</a> is empty then its result will be as well, since the shape <code><span class='Function'>β’</span><span class='Value'>π©</span></code> is a prefix of <code><span class='Function'>β’></span><span class='Value'>π©</span></code>. However, the remainder of the result shape is determined by the elements of <code><span class='Value'>π©</span></code>, so if there are none then Merge uses the fill element to decide what the result shape should be. <a href="join.html">Join</a> is similar, although it multiplies the shape of <code><span class='Value'>π©</span></code> by the leading shape of the fill instead of concatenating them.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4omiID4gMuKAvzDipYo8M+KAvzTigL8x4qWKMAoK4omiIOKIviAy4oC/MOKlijwz4oC/NOKAvzHipYow">βοΈ</a><pre> <span class='Function'>β’</span> <span class='Function'>></span> <span class='Number'>2</span><span class='Ligature'>βΏ</span><span class='Number'>0</span><span class='Function'>β₯<</span><span class='Number'>3</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'>0</span>
β¨ 2 0 3 4 1 β©
<span class='Function'>β’</span> <span class='Function'>βΎ</span> <span class='Number'>2</span><span class='Ligature'>βΏ</span><span class='Number'>0</span><span class='Function'>β₯<</span><span class='Number'>3</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'>0</span>
β¨ 6 0 1 β©
</pre>
<p><a href="rank.html">Cells and Rank</a> 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 <code><span class='Function'>π½</span></code> using a cell of fills for the argument. As in Each (<code><span class='Modifier'>Β¨</span></code>) described below, this evaluation is not allowed to produce side effects. If it doesn't work, the result cell shape is assumed to be <code><span class='Bracket'>β¨β©</span></code>.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4omiIOKMvcuYIOKGlTDigL804oC/MyAgIyBTaGFwZSBpcyBkZXRlcm1pbmVkIGJ5IGZpbGxz">βοΈ</a><pre> <span class='Function'>β’</span> <span class='Function'>β½</span><span class='Modifier'>Λ</span> <span class='Function'>β</span><span class='Number'>0</span><span class='Ligature'>βΏ</span><span class='Number'>4</span><span class='Ligature'>βΏ</span><span class='Number'>3</span> <span class='Comment'># Shape is determined by fills
</span>β¨ 0 4 3 β©
</pre>
<h2 id="how-fills-are-computed"><a class="header" href="#how-fills-are-computed">How fills are computed</a></h2>
<p>For the exact requirements placed on fill, see <a href="../spec/inferred.html#fill-elements">the specification</a> (particularly "required functions"). This section loosely describes behavior in existing BQN implementations, and includes some parts that aren't required in the specification.</p>
<p>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 <code><span class='Number'>0</span></code>. If every element is a list of two numbers, then the fill should be <code><span class='Bracket'>β¨</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Bracket'>β©</span></code>. If every element is a list but the lengths might vary, <code><span class='Bracket'>β¨β©</span></code> is probably a reasonable fill element.</p>
<p>For <a href="arithmetic.html">arithmetic</a> primitives, the fill is found by the rules of pervasion, applying the function to both argument fills. Generally this means it consists of <code><span class='Number'>0</span></code>, but <a href="arithmetic.html#character-arithmetic">character arithmetic</a> can produce space for a fill value.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=wrsgImFiYyIgKyA04oC/M+KAvzI=">βοΈ</a><pre> <span class='Function'>Β»</span> <span class='String'>"abc"</span> <span class='Function'>+</span> <span class='Number'>4</span><span class='Ligature'>βΏ</span><span class='Number'>3</span><span class='Ligature'>βΏ</span><span class='Number'>2</span>
" ee"
</pre>
<p><a href="map.html">Mapping</a> modifiers Each and Table (<code><span class='Modifier'>Β¨β</span></code>) might try to follow a similar strategy, applying <code><span class='Function'>π½</span></code> 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 <code><span class='Function'>π½</span></code> such as a block function this procedure is likely to be aborted to avoid disrupting the rest of the program.</p>
<p>Most other primitives fit in one of three broad categories as shown in the table below. Structural primitives, indicated by <code><span class='Function'>β’</span></code>, don't change the fill of <code><span class='Value'>π©</span></code>. Combining structural primitives, indicated by <code><span class='Value'>β©</span></code>, only depend on the fill of all combined arraysβelements of <code><span class='Value'>π©</span></code> in the one-argument case, or <code><span class='Value'>π¨</span></code> and <code><span class='Value'>π©</span></code> 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 <a href="search.html">search functions</a> return only arrays of numbers and have a fill of <code><span class='Number'>0</span></code>.</p>
<table>
<thead>
<tr>
<th>Fill</th>
<th>Monads</th>
<th>Dyads</th>
<th>Modifiers</th>
</tr>
</thead>
<tbody>
<tr>
<td><code><span class='Function'>β’</span></code></td>
<td><code><span class='Function'>β§β¨β₯β»«β½βββ·</span></code></td>
<td><code><span class='Function'>β₯ββββ½β/β</span></code></td>
<td><code><span class='Function'>π½</span><span class='Modifier'>`</span></code></td>
</tr>
<tr>
<td><code><span class='Value'>β©</span></code></td>
<td><code><span class='Function'>>βΎ</span></code></td>
<td><code><span class='Function'>βΎβ»«</span></code></td>
<td></td>
</tr>
<tr>
<td><code><span class='Number'>0</span></code></td>
<td><code><span class='Function'>β’/βββββ</span></code></td>
<td><code><span class='Function'>ββββββ·</span></code></td>
<td></td>
</tr>
</tbody>
</table>
<p>Besides these, there are a few primitives with special fills. <a href="enclose.html">Enclose</a> (<code><span class='Function'><</span></code>) uses a fill derived directly from <code><span class='Value'>π©</span></code>, with all numbers replaced by <code><span class='Number'>0</span></code> and characters by <code><span class='String'>' '</span></code> (if it contains non-data atoms, the fill doesn't exist). <a href="pair.html">Enlist</a> works the same way, while <a href="pair.html">Pair</a> sets the fill this way based on both <code><span class='Value'>π¨</span></code> and <code><span class='Value'>π©</span></code>, if they agree. <a href="range.html">Range</a> (<code><span class='Function'>β</span></code>) does the same, although the reason is less obvious: the result elements don't match <code><span class='Value'>π©</span></code>, but they have the same structure.</p>
<p><a href="prefixes.html">Prefixes and Suffixes</a> (<code><span class='Function'>ββ</span></code>) use <code><span class='Number'>0</span><span class='Function'>β</span><span class='Value'>π©</span></code> for the fill, as do <a href="group.html">Group</a> and Group Indices (<code><span class='Function'>β</span></code>) in the single-axis case. Fills for multi-axis <code><span class='Function'>β</span></code> are more complicated, but follow the rule that variable-length axes are changed to length 0. The <em>elements</em> of the result of <code><span class='Function'>β</span></code> also have a fill specified: the same as <code><span class='Value'>π©</span></code> for Group, or <code><span class='Number'>0</span></code> for Group Indices.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=NiDihpEg4oaR4oaVMyAgIyBUd28gZmlsbHMgYXQgdGhlIGVuZAoKwrvCqCAz4oC/NOKAvzEgL+KKuOKKlCAiYWJjMDEyM0Ei">βοΈ</a><pre> <span class='Number'>6</span> <span class='Function'>β</span> <span class='Function'>ββ</span><span class='Number'>3</span> <span class='Comment'># Two fills at the end
</span>β¨ β¨β© β¨ 0 β© β¨ 0 1 β© β¨ 0 1 2 β© β¨β© β¨β© β©
<span class='Function'>Β»</span><span class='Modifier'>Β¨</span> <span class='Number'>3</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='Modifier2'>βΈ</span><span class='Function'>β</span> <span class='String'>"abc0123A"</span>
β¨ " ab" " 012" " " β©
</pre>
|