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
|
<head>
<link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/>
<link href="../style.css" rel="stylesheet"/>
<title>BQN: Types</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="types">Types</h1>
<p>BQN supports the following fundamental types:</p>
<ul>
<li><a href="#numbers">Number</a></li>
<li><a href="#characters">Character</a> (Unicode code point)</li>
<li><a href="#arrays">Array</a></li>
<li><a href="#functions">Function</a></li>
<li>1-<a href="#modifiers">Modifier</a></li>
<li>2-<a href="#modifiers">Modifier</a></li>
</ul>
<p>The first three types are called <em>data types</em>, and the rest are <em>operation types</em>. The array is the only <em>compound type</em>; the other types are <em>atomic types</em> and values of these types are called <em>atoms</em>. The fact that an array is only one type of many is common in modern programming languages but a novelty in the APL family. This decision is discussed in the page on <a href="based.html">based array theory</a>.</p>
<svg viewBox='-64 -36 512 204'>
<g stroke-width='2'>
<path d='M0 12A12 12 0 0 1 12 0L244 0A12 12 0 0 1 256 12L256 52A12 12 0 0 0 268 64L372 64A12 12 0 0 1 384 76L384 116A12 12 0 0 1 372 128L12 128A12 12 0 0 1 0 116Z' class='yellow'/>
<rect width='368' height='48' x='8' y='8' rx='10px' class='purple'/>
<rect width='368' height='48' x='8' y='72' rx='10px' class='bluegreen'/>
</g>
<g text-anchor='middle' fill='currentColor'>
<g font-size='18px'>
<text x='64' y='32' dy='0.32em'>Number</text>
<text x='64' y='96' dy='0.32em'>Function</text>
<text x='192' y='32' dy='0.32em'>Character</text>
<text x='192' y='96' dy='0.32em'>1-modifier</text>
<text x='320' y='32' dy='0.32em'>Array</text>
<text x='320' y='96' dy='0.32em'>2-modifier</text>
</g>
<g font-size='16px'>
<text class='purple' x='96' y='-12.8' dy='0.32em'>Data</text>
<text class='bluegreen' x='96' y='140.8' dy='0.32em'>Operation</text>
<text class='yellow' x='281.6' y='147.2' dy='0.32em'>Atom</text>
</g>
</g>
</svg>
<p>All of these types are immutable, meaning that a particular copy of a value will never change (to go further, with immutable types it doesn't really make sense to talk about a "copy" of a value: values just exist and nothing you do will affect them). The only form of mutability BQN has is the ability to change the value of a particular variable, that is, make the variable refer to a different value. Such a change can also change the behavior of a function or modifier that has the variable in its scope, and in this sense operation types are mutable—in fact it is possible to implement typical mutable data structures as functions that act on enclosed state.</p>
<p>It is likely that in the future <a href="extensions.html#namespaces-and-symbols">namespaces</a>, or references to enclosed scopes, will be added as a more directly manipulable mutable data type.</p>
<h2 id="data-types">Data types</h2>
<p>Data types—numbers, characters, and arrays—are more like "things" than "actions". If called as a function, a value of one of these types simply returns itself. Data can be uniquely represented, compared for equality, and ordered using BQN's array ordering; in contrast, determining whether two functions always return the same result can be undecidable. For arrays, these properties apply only if there are no operations inside. We might say that "data" in BQN refers to numbers, characters, and arrays of data.</p>
<h3 id="numbers">Numbers</h3>
<p>The BQN spec allows for different numeric models to be used, but requires there to be only one numeric type from the programmer's perspective: while programs can often be executed faster by using limited-range integer types, there is no need to expose these details to the programmer. Existing BQN implementations are based on <a href="https://en.wikipedia.org/wiki/IEEE-754">double-precision floats</a>, like Javascript or Lua.</p>
<h3 id="characters">Characters</h3>
<p>A character in BQN is always a <a href="https://en.wikipedia.org/wiki/Unicode">Unicode</a> code point. BQN does not use encodings such as UTF-8 or UTF-16 for characters, although it would be possible to store arrays of integers or characters that correspond to data in these encodings. Because every code point corresponds to a single unit in UTF-32, BQN characters can be thought of as UTF-32 encoded.</p>
<p>Addition and subtraction treat characters as an <a href="http://videocortex.io/2018/Affine-Space-Types/">affine space</a> relative to the linear space of numbers. This means that:</p>
<ul>
<li>A number can be added to or subtracted from a character.</li>
<li>Two characters can be subtracted to get the distance between them—a number.</li>
</ul>
<p>Other linear combinations such as adding two characters or negating a character are not allowed. You can check whether an application of <code><span class='Function'>+</span></code> or <code><span class='Function'>-</span></code> on numbers and characters is allowed by applying the same function to the "characterness" of each value: <code><span class='Number'>0</span></code> for a number and <code><span class='Number'>1</span></code> for a character. The result will be a number if this application gives <code><span class='Number'>0</span></code> and a character if this gives <code><span class='Number'>1</span></code>, and otherwise the operation is not allowed.</p>
<h3 id="arrays">Arrays</h3>
<p>A BQN array is a multidimensional arrangement of data.</p>
<p>Currently, the intention is that arrays will not have prototypes, so that all empty arrays of the same shape behave identically. Different elements of an array should not influence each other. While some APLs force numbers placed in the same array to a common representation, which may have different precision properties, BQN will enforce 64-bit floating-point precision, and only use representations or methods compatible with it (for example, integers up to 32 bits).</p>
<h2 id="operation-types">Operation types</h2>
<p>An operation is either a function or modifier, and can be applied to <em>inputs</em>—which are called <em>arguments</em> for functions and <em>operands</em> for modifiers—to obtain a result. During this application an operation might also change variables within its scope and call other operations, or cause an error, in which case it doesn't return a result. There is one type of call for each of the three operation types, and an operation will give an error if it is called in a way that doesn't match its type.</p>
<p>In BQN syntax the result of a function has a subject role and the result of a modifier has a function role. However, the result can be any value at all: roles take place at the syntactic level, which has no bearing on types and values in the semantic level. This distinction is discussed further in <a href="context.html#mixing-roles">Mixing roles</a>.</p>
<h3 id="functions">Functions</h3>
<p>A function is called with one or two arguments. A data value (number, character, or array) can also be called the same way, but only a function takes any action when passed arguments, as data just returns itself. Both the one-argument and two-argument calls are considered function calls, and it's common for a function to allow both. A function that always errors in one case or the other might be called a one-argument or two-argument function, depending on which case is allowed.</p>
<h3 id="modifiers">Modifiers</h3>
<p>A 1-modifier is called with one operand, while a 2-modifier is called with two. In contrast to functions, these are distinct types, and it is impossible to have a value that can be called with either one or two operands. Also in contrast to functions, data values cannot be called as modifiers: they will cause an error if called this way.</p>
|