aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2021-06-08 17:32:38 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2021-06-08 17:32:38 -0400
commit7a09ad46c547fe6914c3aab01b7f0789b04ae3ef (patch)
tree737f0f2bc42fcea94974b9520474141d98f4f4f9
parent8f973563e1a750a964bca3239e5a23b87dd8e6d1 (diff)
Documentation for Shape, Rank, and Length
-rw-r--r--doc/README.md1
-rw-r--r--doc/primitive.md6
-rw-r--r--doc/shape.md45
-rw-r--r--docs/doc/index.html1
-rw-r--r--docs/doc/primitive.html6
-rw-r--r--docs/doc/shape.html80
6 files changed, 133 insertions, 6 deletions
diff --git a/doc/README.md b/doc/README.md
index 1cd340bd..b4d28b13 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -30,6 +30,7 @@ Concepts:
Primitives:
- [Arithmetic](arithmetic.md) (`+-×÷⋆√⌊⌈|`)
- [Array depth](depth.md) (`≡` and `⚇`)
+- [Array dimensions](shape.md) (`≢=≠`)
- [Assert](assert.md) (`!`)
- [Deshape and Reshape](reshape.md) (`⥊`)
- [Fold and Insert](fold.md) (`´˝`)
diff --git a/doc/primitive.md b/doc/primitive.md
index 0715e669..c782d8ba 100644
--- a/doc/primitive.md
+++ b/doc/primitive.md
@@ -30,10 +30,10 @@ Functions that have significant differences from APL functions are marked with a
| `<` | [Enclose](https://aplwiki.com/wiki/Enclose) | [Less Than](https://aplwiki.com/wiki/Less_than)
| `>` | [Merge](couple.md)* | [Greater Than](https://aplwiki.com/wiki/Greater_than)
| `≥` | | [Greater Than or Equal to](https://aplwiki.com/wiki/Greater_than_or_Equal_to)
-| `=` | Rank | [Equals](https://aplwiki.com/wiki/Equal_to)
-| `≠` | [Length](https://aplwiki.com/wiki/Tally) | [Not Equals](https://aplwiki.com/wiki/Not_Equal_to)
+| `=` | [Rank](shape.md)* | [Equals](https://aplwiki.com/wiki/Equal_to)
+| `≠` | [Length](shape.md) | [Not Equals](https://aplwiki.com/wiki/Not_Equal_to)
| `≡` | [Depth](depth.md)* | [Match](match.md)
-| `≢` | [Shape](https://aplwiki.com/wiki/Shape) | [Not Match](match.md)
+| `≢` | [Shape](shape.md) | [Not Match](match.md)
| `⊣` | [Identity](https://aplwiki.com/wiki/Identity) | [Left](https://aplwiki.com/wiki/Identity)
| `⊢` | [Identity](https://aplwiki.com/wiki/Identity) | [Right](https://aplwiki.com/wiki/Identity)
| `⥊` | [Deshape](reshape.md) | [Reshape](reshape.md)*
diff --git a/doc/shape.md b/doc/shape.md
new file mode 100644
index 00000000..90a71cdd
--- /dev/null
+++ b/doc/shape.md
@@ -0,0 +1,45 @@
+*View this file with results and syntax highlighting [here](https://mlochbaum.github.io/BQN/doc/shape.html).*
+
+# Array dimensions
+
+The function Shape (`≢`) returns an array's shape, and Rank (`=`) and Length (`≠`) return properties that can be derived from the shape. BQN's arrays are multidimensional, so that the shape is a list of natural numbers (the length along each axis), while the rank (length of the shape) and length (of the first axis) are numbers. In these functions, an atom is treated as a unit array, which has rank 0 and empty shape. A unit has no first axis, but its length is defined to be 1.
+
+Rank can be defined as `≠∘≢` while Length can be defined with a [fold](fold.md) to be `1⊣´≢`.
+
+## Examples
+
+The function [Reshape](reshape.md) (`⥊`) always returns an array of shape `𝕨`, so we use it to make an array of shape `1‿3‿2‿6` in the example below ([Take](take.md) (`↑`) shares this property).
+
+ ⊢ arr ← 1‿3‿2‿6 ⥊ '0'+↕10
+
+ ≢ arr # Shape
+
+ ≠ arr # Length
+
+ = arr # Rank
+
+The length is the first element of the shape, and the rank is the length of the shape—the number of axes. For another example, taking the first (and only) cell of `arr` gives an array with shape `3‿2‿6`, length `3`, and rank `3`, as we can see by applying each function to `⊏arr`.
+
+ ≢‿=‿≠ {𝕎𝕩}¨< ⊏arr
+
+Applying Shape and the other two functions to an atom shows a shape of `⟨⟩`, the empty list, and a rank of zero and length of 1. The same is true of an enclosed array, which like an atom is a kind of unit.
+
+ ≢ 5
+
+ (= ≍ ≠) 5
+
+ (= ≍ ≠) <↕10
+
+## Units
+
+A unit is an atom, or an array with no axes—rank 0. Since it doesn't have any axes, its shape should have no elements. It should be the empty list `⟨⟩` (with a fill of `0`, like all shapes). As there's no first element in the shape, it's not obvious what the length should be, and a stricter language would just give an error. However, there are some good reasons to use a length of `1`. First, the total number of elements is 1, meaning that if the length divides this number evenly (as it does for non-unit arrays) then the only possible natural number it can be is 1. Second, many functions that take a list for a particular argument also accept a unit, and treat it as a length-1 array. For example, `5⥊a` and `⟨5⟩⥊a` are identical. Defining `≠5` to be `1` means that `=s⥊a` is always `≠s`.
+
+Despite this last point, it's important to remember that a unit isn't the same as a 1-element list. For example, the length-1 string `"a"` doesn't match `<'a'` but instead `⟨'a'⟩`. And also bear in mind that having an empty *shape* doesn't make a unit an empty *array*. That would mean it has no elements, not one!
+
+Value | Shape | Rank | Length
+---------------|--------|------|-------
+Unit | `⟨⟩` | `0` | `1`
+1-element list | `⟨1⟩` | `1` | `1`
+Empty list | `⟨0⟩` | `1` | `0`
+
+These three kinds of array are distinguished in the table above. A related fact is that repeating the Shape function three times (`≢⍟3`) always gives `⟨1⟩`: the first time returns a list, the second a 1-element list, and the third that specific list. Another comment is that there's no value with rank 0 *and* length 0. An rank-0 array is a unit by definition, so it has length 1.
diff --git a/docs/doc/index.html b/docs/doc/index.html
index e8d3c468..8d08b068 100644
--- a/docs/doc/index.html
+++ b/docs/doc/index.html
@@ -36,6 +36,7 @@
<ul>
<li><a href="arithmetic.html">Arithmetic</a> (<code><span class='Function'>+-×÷⋆√⌊⌈|</span></code>)</li>
<li><a href="depth.html">Array depth</a> (<code><span class='Function'>≡</span></code> and <code><span class='Modifier2'>⚇</span></code>)</li>
+<li><a href="shape.html">Array dimensions</a> (<code><span class='Function'>≢=≠</span></code>)</li>
<li><a href="assert.html">Assert</a> (<code><span class='Function'>!</span></code>)</li>
<li><a href="reshape.html">Deshape and Reshape</a> (<code><span class='Function'>⥊</span></code>)</li>
<li><a href="fold.html">Fold and Insert</a> (<code><span class='Modifier'>´˝</span></code>)</li>
diff --git a/docs/doc/primitive.html b/docs/doc/primitive.html
index d50c58d6..62b612dc 100644
--- a/docs/doc/primitive.html
+++ b/docs/doc/primitive.html
@@ -101,12 +101,12 @@
</tr>
<tr>
<td><code><span class='Function'>=</span></code></td>
-<td>Rank</td>
+<td><a href="shape.html">Rank</a>*</td>
<td><a href="https://aplwiki.com/wiki/Equal_to">Equals</a></td>
</tr>
<tr>
<td><code><span class='Function'>≠</span></code></td>
-<td><a href="https://aplwiki.com/wiki/Tally">Length</a></td>
+<td><a href="shape.html">Length</a></td>
<td><a href="https://aplwiki.com/wiki/Not_Equal_to">Not Equals</a></td>
</tr>
<tr>
@@ -116,7 +116,7 @@
</tr>
<tr>
<td><code><span class='Function'>≢</span></code></td>
-<td><a href="https://aplwiki.com/wiki/Shape">Shape</a></td>
+<td><a href="shape.html">Shape</a></td>
<td><a href="match.html">Not Match</a></td>
</tr>
<tr>
diff --git a/docs/doc/shape.html b/docs/doc/shape.html
new file mode 100644
index 00000000..350e3587
--- /dev/null
+++ b/docs/doc/shape.html
@@ -0,0 +1,80 @@
+<head>
+ <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/>
+ <link href="../style.css" rel="stylesheet"/>
+ <title>BQN: Array dimensions</title>
+</head>
+<div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a> / <a href="../index.html">main</a> / <a href="index.html">doc</a></div>
+<h1 id="array-dimensions">Array dimensions</h1>
+<p>The function Shape (<code><span class='Function'>≢</span></code>) returns an array's shape, and Rank (<code><span class='Function'>=</span></code>) and Length (<code><span class='Function'>≠</span></code>) return properties that can be derived from the shape. BQN's arrays are multidimensional, so that the shape is a list of natural numbers (the length along each axis), while the rank (length of the shape) and length (of the first axis) are numbers. In these functions, an atom is treated as a unit array, which has rank 0 and empty shape. A unit has no first axis, but its length is defined to be 1.</p>
+<p>Rank can be defined as <code><span class='Function'>≠</span><span class='Modifier2'>∘</span><span class='Function'>≢</span></code> while Length can be defined with a <a href="fold.html">fold</a> to be <code><span class='Number'>1</span><span class='Function'>⊣</span><span class='Modifier'>´</span><span class='Function'>≢</span></code>.</p>
+<h2 id="examples">Examples</h2>
+<p>The function <a href="reshape.html">Reshape</a> (<code><span class='Function'>⥊</span></code>) always returns an array of shape <code><span class='Value'>𝕨</span></code>, so we use it to make an array of shape <code><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>6</span></code> in the example below (<a href="take.html">Take</a> (<code><span class='Function'>↑</span></code>) shares this property).</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGFyciDihpAgMeKAvzPigL8y4oC/NiDipYogJzAnK+KGlTEwCgriiaIgYXJyICAjIFNoYXBlCgriiaAgYXJyICAjIExlbmd0aAoKPSBhcnIgICMgUmFuaw==">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>arr</span> <span class='Gets'>←</span> <span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>6</span> <span class='Function'>⥊</span> <span class='String'>'0'</span><span class='Function'>+↕</span><span class='Number'>10</span>
+┌─
+┆"012345
+ 678901
+
+ ·234567
+ 890123
+
+ ·456789
+ 012345"
+ ┘
+
+ <span class='Function'>≢</span> <span class='Value'>arr</span> <span class='Comment'># Shape
+</span>⟨ 1 3 2 6 ⟩
+
+ <span class='Function'>≠</span> <span class='Value'>arr</span> <span class='Comment'># Length
+</span>1
+
+ <span class='Function'>=</span> <span class='Value'>arr</span> <span class='Comment'># Rank
+</span>4
+</pre>
+<p>The length is the first element of the shape, and the rank is the length of the shape—the number of axes. For another example, taking the first (and only) cell of <code><span class='Value'>arr</span></code> gives an array with shape <code><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>6</span></code>, length <code><span class='Number'>3</span></code>, and rank <code><span class='Number'>3</span></code>, as we can see by applying each function to <code><span class='Function'>⊏</span><span class='Value'>arr</span></code>.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4omi4oC/PeKAv+KJoCB78J2VjvCdlal9wqg8IOKKj2Fycg==">↗️</a><pre> <span class='Function'>≢</span><span class='Ligature'>‿</span><span class='Function'>=</span><span class='Ligature'>‿</span><span class='Function'>≠</span> <span class='Brace'>{</span><span class='Function'>𝕎</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier'>¨</span><span class='Function'>&lt;</span> <span class='Function'>⊏</span><span class='Value'>arr</span>
+⟨ ⟨ 3 2 6 ⟩ 3 3 ⟩
+</pre>
+<p>Applying Shape and the other two functions to an atom shows a shape of <code><span class='Bracket'>⟨⟩</span></code>, the empty list, and a rank of zero and length of 1. The same is true of an enclosed array, which like an atom is a kind of unit.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4omiIDUKCig9IOKJjSDiiaApIDUKCig9IOKJjSDiiaApIDzihpUxMA==">↗️</a><pre> <span class='Function'>≢</span> <span class='Number'>5</span>
+⟨⟩
+
+ <span class='Paren'>(</span><span class='Function'>=</span> <span class='Function'>≍</span> <span class='Function'>≠</span><span class='Paren'>)</span> <span class='Number'>5</span>
+⟨ 0 1 ⟩
+
+ <span class='Paren'>(</span><span class='Function'>=</span> <span class='Function'>≍</span> <span class='Function'>≠</span><span class='Paren'>)</span> <span class='Function'>&lt;↕</span><span class='Number'>10</span>
+⟨ 0 1 ⟩
+</pre>
+<h2 id="units">Units</h2>
+<p>A unit is an atom, or an array with no axes—rank 0. Since it doesn't have any axes, its shape should have no elements. It should be the empty list <code><span class='Bracket'>⟨⟩</span></code> (with a fill of <code><span class='Number'>0</span></code>, like all shapes). As there's no first element in the shape, it's not obvious what the length should be, and a stricter language would just give an error. However, there are some good reasons to use a length of <code><span class='Number'>1</span></code>. First, the total number of elements is 1, meaning that if the length divides this number evenly (as it does for non-unit arrays) then the only possible natural number it can be is 1. Second, many functions that take a list for a particular argument also accept a unit, and treat it as a length-1 array. For example, <code><span class='Number'>5</span><span class='Function'>⥊</span><span class='Value'>a</span></code> and <code><span class='Bracket'>⟨</span><span class='Number'>5</span><span class='Bracket'>⟩</span><span class='Function'>⥊</span><span class='Value'>a</span></code> are identical. Defining <code><span class='Function'>≠</span><span class='Number'>5</span></code> to be <code><span class='Number'>1</span></code> means that <code><span class='Function'>=</span><span class='Value'>s</span><span class='Function'>⥊</span><span class='Value'>a</span></code> is always <code><span class='Function'>≠</span><span class='Value'>s</span></code>.</p>
+<p>Despite this last point, it's important to remember that a unit isn't the same as a 1-element list. For example, the length-1 string <code><span class='String'>&quot;a&quot;</span></code> doesn't match <code><span class='Function'>&lt;</span><span class='String'>'a'</span></code> but instead <code><span class='Bracket'>⟨</span><span class='String'>'a'</span><span class='Bracket'>⟩</span></code>. And also bear in mind that having an empty <em>shape</em> doesn't make a unit an empty <em>array</em>. That would mean it has no elements, not one!</p>
+<table>
+<thead>
+<tr>
+<th>Value</th>
+<th>Shape</th>
+<th>Rank</th>
+<th>Length</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Unit</td>
+<td><code><span class='Bracket'>⟨⟩</span></code></td>
+<td><code><span class='Number'>0</span></code></td>
+<td><code><span class='Number'>1</span></code></td>
+</tr>
+<tr>
+<td>1-element list</td>
+<td><code><span class='Bracket'>⟨</span><span class='Number'>1</span><span class='Bracket'>⟩</span></code></td>
+<td><code><span class='Number'>1</span></code></td>
+<td><code><span class='Number'>1</span></code></td>
+</tr>
+<tr>
+<td>Empty list</td>
+<td><code><span class='Bracket'>⟨</span><span class='Number'>0</span><span class='Bracket'>⟩</span></code></td>
+<td><code><span class='Number'>1</span></code></td>
+<td><code><span class='Number'>0</span></code></td>
+</tr>
+</tbody>
+</table>
+<p>These three kinds of array are distinguished in the table above. A related fact is that repeating the Shape function three times (<code><span class='Function'>≢</span><span class='Modifier2'>⍟</span><span class='Number'>3</span></code>) always gives <code><span class='Bracket'>⟨</span><span class='Number'>1</span><span class='Bracket'>⟩</span></code>: the first time returns a list, the second a 1-element list, and the third that specific list. Another comment is that there's no value with rank 0 <em>and</em> length 0. An rank-0 array is a unit by definition, so it has length 1.</p>