aboutsummaryrefslogtreecommitdiff
path: root/docs/spec/primitive.html
blob: 53a74f25959df181cf8802980ad79f9be627e4b7 (plain)
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
<head>
  <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/>
  <link href="../style.css" rel="stylesheet"/>
  <title>Specification: BQN primitives</title>
</head>
<div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a> / <a href="../index.html">main</a> / <a href="index.html">spec</a></div>
<h1 id="specification-bqn-primitives">Specification: BQN primitives</h1>
<p>Most primitives are specified by the BQN-based implementation in <a href="https://github.com/mlochbaum/BQN/blob/master/spec/reference.bqn">reference.bqn</a>. This document specifies the basic functionality required by those definitions. Descriptions of other primitives are for informational purposes only.</p>
<h2 id="pervasive-primitives">Pervasive primitives</h2>
<p>Functions in this section are defined for atoms only; the reference implementations extend them to arrays.</p>
<h3 id="arithmetic">Arithmetic</h3>
<p>BQN uses five arithmetic functions that are standard in mathematics. The precision of these operations should be specified by the number <a href="types.html">type</a>.</p>
<ul>
<li><strong>Add</strong> <code><span class='Function'>+</span></code></li>
<li><strong>Negate</strong> and <strong>Subtract</strong> <code><span class='Function'>-</span></code> invert addition, with <code><span class='Function'>-</span><span class='Value'>๐•ฉ</span></code> equivalent to <code><span class='Number'>0</span><span class='Function'>-</span><span class='Value'>๐•ฉ</span></code>.</li>
<li><strong>Multiply</strong> <code><span class='Function'>ร—</span></code> generalizes repeated addition.</li>
<li><strong>Divide</strong> and <strong>Reciprocal</strong> <code><span class='Function'>รท</span></code> invert multiplication, with <code><span class='Function'>รท</span><span class='Value'>๐•ฉ</span></code> equivalent to <code><span class='Number'>1</span><span class='Function'>รท</span><span class='Value'>๐•ฉ</span></code>.</li>
<li><strong>Power</strong> <code><span class='Function'>โ‹†</span></code> generalizes repeated multiplication, and <strong>Exponential</strong> <code><span class='Function'>โ‹†</span></code> is Power with Euler's number <em>e</em> as the base.</li>
</ul>
<p>The three higher functions <code><span class='Function'>ร—</span></code>, <code><span class='Function'>รท</span></code>, and <code><span class='Function'>โ‹†</span></code> apply to numbers and no other atomic types. <code><span class='Function'>+</span></code> and <code><span class='Function'>-</span></code> apply to numbers, and possibly also to characters, according to the rules of the affine character type:</p>
<ul>
<li>If one argument to <code><span class='Function'>+</span></code> is the character with code point <code><span class='Value'>c</span></code> and the other is a number <code><span class='Value'>n</span></code> (in either order), then the result is the character with code point <code><span class='Value'>c</span><span class='Function'>+</span><span class='Value'>n</span></code>.</li>
<li>If the left argument to <code><span class='Function'>-</span></code> is the character with code point <code><span class='Value'>c</span></code> and the right is a number <code><span class='Value'>n</span></code>, the result is the character with code point <code><span class='Value'>c</span><span class='Function'>-</span><span class='Value'>n</span></code>.</li>
<li>If both arguments to <code><span class='Function'>-</span></code> are characters, the result is the difference of their respective code points.</li>
</ul>
<p>In the first two cases, if the result would not be a valid Unicode code point, then an error results. The remaining cases of <code><span class='Function'>+</span></code> and <code><span class='Function'>-</span></code> (adding two characters; negating a character or subtracting it from a number) are not allowed.</p>
<p>Additionally, the <strong>Floor</strong> function <code><span class='Function'>โŒŠ</span></code> returns the largest integer smaller than the argument, or the argument itself if it is <code><span class='Number'>ยฏโˆž</span></code> or <code><span class='Number'>โˆž</span></code>. It's needed because the arithmetic operations give no fixed-time way to determine if a value is an integer. Floor gives an error if the argument is an atom other than a number.</p>
<h3 id="comparison">Comparison</h3>
<p>Two kinds of comparison are needed to define BQN's primitives: <em>equality</em> comparison and <em>ordered</em> comparison.</p>
<p>Ordered comparison is simpler and is provided by the dyadic Less than or Equal to (<code><span class='Function'>โ‰ค</span></code>) function. This function gives an error if either argument is an operation, so it needs to be defined only for numbers and characters. For numbers it is defined by the number system, and for characters it returns <code><span class='Number'>1</span></code> if the left argument's code point is less than that of the right argument. Characters are considered greater than numbers, so that <code><span class='Value'>n</span><span class='Function'>โ‰ค</span><span class='Value'>c</span></code> is <code><span class='Number'>1</span></code> and <code><span class='Value'>c</span><span class='Function'>โ‰ค</span><span class='Value'>n</span></code> is <code><span class='Number'>0</span></code> if <code><span class='Value'>c</span></code> is a character and <code><span class='Value'>n</span></code> is a number.</p>
<p>The dyadic function <code><span class='Function'>=</span></code>, representing equality comparison, can be applied to any two atoms without an error. Roughly speaking, it returns <code><span class='Number'>1</span></code> if they are indistinguishable within the language and <code><span class='Number'>0</span></code> otherwise. If the two arguments have different types, the result is <code><span class='Number'>0</span></code>; if they have the same type, the comparison depends on type:</p>
<ul>
<li>Equality of numbers is specified by the number type.</li>
<li>Characters are equal if they have the same code point.</li>
</ul>
<p>Operations are split into subtypes depending on how they were created.</p>
<ul>
<li>Primitives are equal if they have the same token spelling.</li>
<li>Derived operations are equal if they are derived by the same rule and each corresponding component is the same.</li>
<li>Block instances are equal if they are the same instance.</li>
</ul>
<p>This means that block instance equality indicates identity in the context of mutability: two block instances are equal if any change of state in one would be reflected in the other as well. The concept of identity holds even if the blocks in question have no way of changing or accessing state. For example, <code><span class='Function'>=</span><span class='Modifier2'>โ—‹</span><span class='Brace'>{</span><span class='Value'>๐•ฉ</span><span class='Separator'>โ‹„</span><span class='Brace'>{</span><span class='Value'>๐•ฉ</span><span class='Brace'>}}</span><span class='Modifier'>หœ</span><span class='String'>@</span></code> is <code><span class='Number'>0</span></code> while <code><span class='Function'>=</span><span class='Modifier'>หœ</span><span class='Modifier2'>โ—‹</span><span class='Brace'>{</span><span class='Value'>๐•ฉ</span><span class='Separator'>โ‹„</span><span class='Brace'>{</span><span class='Value'>๐•ฉ</span><span class='Brace'>}}</span><span class='String'>@</span></code> is <code><span class='Number'>1</span></code>.</p>
<h2 id="array-functionality">Array functionality</h2>
<p>Several subsets of primitives, or dedicated operations, are used to manipulate arrays in the reference implementation.</p>
<ul>
<li><code><span class='Function'>IsArray</span></code> returns <code><span class='Number'>1</span></code> if the argument is an array and <code><span class='Number'>0</span></code> if it's an atom.</li>
</ul>
<p>The following functions translate between arrays and the two lists that define them: the shape and ravel.</p>
<ul>
<li><strong>Shape</strong> (<code><span class='Function'>โ‰ข</span></code>) returns the shape of array <code><span class='Value'>๐•ฉ</span></code>, as a list of natural numbers.</li>
<li><strong>Deshape</strong> (monadic <code><span class='Function'>โฅŠ</span></code>) returns the ravel of array <code><span class='Value'>๐•ฉ</span></code>, that is, the list of its elements.</li>
<li><strong>Reshape</strong> (dyadic <code><span class='Function'>โฅŠ</span></code>) returns an array with the same ravel as <code><span class='Value'>๐•ฉ</span></code> with shape <code><span class='Value'>๐•จ</span></code>. It can be assumed that <code><span class='Function'>โ‰ข</span><span class='Value'>๐•ฉ</span></code> and <code><span class='Value'>๐•จ</span></code> have the same product.</li>
</ul>
<p>The following functions manipulate lists. In these functions, a valid index for list <code><span class='Value'>l</span></code> is a natural number less than the length of <code><span class='Value'>l</span></code>.</p>
<ul>
<li><strong>Range</strong> gives the list of length <code><span class='Value'>๐•ฉ</span></code> (a natural number) with value <code><span class='Value'>i</span></code> at any index <code><span class='Value'>i</span></code>.</li>
<li><strong>Pick</strong> (<code><span class='Function'>โŠ‘</span></code>) selects the element at index <code><span class='Value'>๐•จ</span></code> from list <code><span class='Value'>๐•ฉ</span></code>.</li>
<li><code><span class='Modifier'>_amend</span></code> returns an array identical to list <code><span class='Value'>๐•ฉ</span></code> except that the element at index <code><span class='Value'>๐•—</span></code> is changed to <code><span class='Value'>๐•จ</span></code>.</li>
</ul>
<h2 id="inferred-functionality">Inferred functionality</h2>
<p>Inferred properties are specified in <a href="inferred.html">their own document</a>, not in the reference implementation.</p>
<ul>
<li><code><span class='Function'>Identity</span></code> gives the identity value for reduction by function <code><span class='Function'>๐•</span></code>.</li>
<li><strong>Undo</strong> (<code><span class='Modifier'>โผ</span></code>) gives a partial right inverse for function <code><span class='Function'>๐”ฝ</span></code>.</li>
<li><code><span class='Function'>Fill</span></code> gives the enclose of the fill value for array <code><span class='Value'>๐•ฉ</span></code>.</li>
</ul>
<h2 id="other-provided-functionality">Other provided functionality</h2>
<ul>
<li><strong>Assert</strong> (<code><span class='Function'>!</span></code>) causes an error if the argument is not <code><span class='Number'>1</span></code>. If <code><span class='Value'>๐•จ</span></code> is provided, it gives a message to be associated with this error (which can be any value, not necessarily a string).</li>
</ul>