-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5699134
commit 35c2e94
Showing
70 changed files
with
810 additions
and
449 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,304 @@ | ||
<!DOCTYPE html> | ||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="generator" content="pandoc" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> | ||
<meta name="author" content="Keith A. Lewis" /> | ||
<meta name="dcterms.date" content="2024-11-29" /> | ||
<title>APL</title> | ||
<style> | ||
code{white-space: pre-wrap;} | ||
span.smallcaps{font-variant: small-caps;} | ||
div.columns{display: flex; gap: min(4vw, 1.5em);} | ||
div.column{flex: auto; overflow-x: auto;} | ||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} | ||
/* The extra [class] is a hack that increases specificity enough to | ||
override a similar rule in reveal.js */ | ||
ul.task-list[class]{list-style: none;} | ||
ul.task-list li input[type="checkbox"] { | ||
font-size: inherit; | ||
width: 0.8em; | ||
margin: 0 0.8em 0.2em -1.6em; | ||
vertical-align: middle; | ||
} | ||
</style> | ||
<link rel="stylesheet" href="math.css" /> | ||
<script defer="" | ||
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"></script> | ||
<script>document.addEventListener("DOMContentLoaded", function () { | ||
var mathElements = document.getElementsByClassName("math"); | ||
var macros = []; | ||
for (var i = 0; i < mathElements.length; i++) { | ||
var texText = mathElements[i].firstChild; | ||
if (mathElements[i].tagName == "SPAN") { | ||
katex.render(texText.data, mathElements[i], { | ||
displayMode: mathElements[i].classList.contains('display'), | ||
throwOnError: false, | ||
macros: macros, | ||
fleqn: true | ||
}); | ||
}}}); | ||
</script> | ||
<link rel="stylesheet" | ||
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css" /> | ||
</head> | ||
<body> | ||
<header id="title-block-header"> | ||
<h1 class="title">APL</h1> | ||
<p class="author">Keith A. Lewis</p> | ||
<p class="date">November 29, 2024</p> | ||
<div class="abstract"> | ||
<div class="abstract-title">Abstract</div> | ||
A Programming Language | ||
</div> | ||
</header> | ||
<p>Let’s give names to things.</p> | ||
<section id="primitive-type" class="level2"> | ||
<h2>Primitive Type</h2> | ||
<p>The <em>primitive types</em> are booleans <span | ||
class="math inline">\mathbf{B}</span>, integers <span | ||
class="math inline">\mathbf{Z}</span>, non-negative integers <span | ||
class="math inline">\mathbf{N}</span>, real numbers <span | ||
class="math inline">\mathbf{R}</span>, and characters <span | ||
class="math inline">\mathbf{C}</span>. We have <span | ||
class="math inline">\mathbf{B}\subseteq\mathbf{N}\subseteq\mathbf{Z}\subseteq\mathbf{R}</span> | ||
as rings. We assume <span | ||
class="math inline">u\colon\mathbf{C}\to\mathbf{N}</span> is an encoding | ||
of the set of characters. (E.g., UTF-8 codepoints)</p> | ||
<p>Primitive types are classified by mathematical objects: set, monoid, | ||
group, ring, field: boolean (field), integer (commutative ring), natural | ||
number (monoid), real number (field), character (set).</p> | ||
<p>We write <span class="math inline">\mathbf{B}= | ||
\{\square,\blacksquare\}</span> where <span | ||
class="math inline">\square</span> represents false and <span | ||
class="math inline">\blacksquare</span> represents true.</p> | ||
<p><span class="math inline">(A\times B)\to C\cong A\to (B\to C)</span> | ||
by <span class="math inline">f(a,b) = c \leftrightarrow f,(a)b = | ||
c</span>.</p> | ||
<p><span class="math inline">A\to (B\to C) \cong (A\times B)\to C</span> | ||
by <span class="math inline">g(a)b = c \leftrightarrow g`(a,b) = | ||
c</span>.</p> | ||
</section> | ||
<section id="type" class="level2"> | ||
<h2>Type</h2> | ||
<p>If <span class="math inline">X</span>, <span | ||
class="math inline">X_i</span> are types</p> | ||
<p><em>array</em> <span class="math inline">x = [x_1,\ldots,x_n]\in | ||
X^n\cong n\to X</span>, <span class="math inline">x[i] = x_i</span>.</p> | ||
<p><span class="math inline">(I\times n)^A x (-n\times I)^A \to | ||
I^A</span></p> | ||
<p><em>tuple</em> <span class="math inline">x = \langle | ||
x_1,\ldots,x_n\rangle\in\prod X_{i\in\mathbf{N}}</span>, <span | ||
class="math inline">n\to(\prod X_i\to X_i)</span>, <span | ||
class="math inline">n\mapsto π_i</span>, <span | ||
class="math inline">x\langle i\rangle = π_i(x) = x_i</span>.</p> | ||
<p><em>union</em> <span class="math inline">x = \{\ldots,x_i,\ldots\} = | ||
\langle i,x_i\rangle\in\coprod_{i\in n} X_i</span>, <span | ||
class="math inline">n\to(X_i\to\coprod X_i)</span>, <span | ||
class="math inline">n\mapsto ν_i</span>, <span | ||
class="math inline">x\{i\} = ν_i(x) = \langle i,x_i\rangle</span>.</p> | ||
<p><em>sequence</em> <span class="math inline">x = (x_0,\ldots,x_{n-1}) | ||
\in X^* = \coprod_{n\in\mathbf{N}} X^n</span> and define <span | ||
class="math inline">*x = x_0</span>, <span class="math inline">+x = | ||
(x_1,\ldots,x_{n-1})</span>, <span class="math inline">?x</span> if and | ||
only if <span class="math inline">n\ge 0</span>, i.e., <span | ||
class="math inline">x</span> is not empty. Note <span | ||
class="math inline">x\in\operatorname{dom}*</span> iff <span | ||
class="math inline">?x</span>. Define <span class="math inline">x = | ||
y</span> if <span class="math inline">*x = *y</span> and <span | ||
class="math inline">+x = +y</span> or if <span | ||
class="math inline">x</span> and <span class="math inline">y</span> are | ||
both empty.</p> | ||
<p>The function <em>concatenate</em> <span class="math inline">,\colon | ||
X^*\times X^*\to X^*</span> written <span class="math inline">,(x,y) = | ||
x,y</span> is defined by <span class="math inline">*(x,y) = *x</span> if | ||
<span class="math inline">?x</span> and <span | ||
class="math inline">*y</span> if not <span | ||
class="math inline">?x</span>, <span class="math inline">+(x,y) = | ||
(+x,y)</span> if <span class="math inline">?x</span> and <span | ||
class="math inline">(x,+y)</span> if not <span | ||
class="math inline">?x</span>, <span class="math inline">?(x,y) = ?x\vee | ||
?y</span> where <span class="math inline">\vee</span> is logical or. | ||
Note <span class="math inline">x,() = x</span> and <span | ||
class="math inline">(),y = y</span> for <span class="math inline">x,y\in | ||
X^*</span> so sequences are a monoid under concatenation with unit the | ||
empty sequence.</p> | ||
<p>If <span class="math inline">x = (x_0,\ldots,x_{n-1})</span> is a | ||
sequence let <span class="math inline">[x] = [x_0,\ldots,x_{n-1}]\in | ||
X^n</span> be the array it determines and <span | ||
class="math inline">\langle x\rangle = \langle | ||
x_0,\ldots,x_{n-1}\rangle</span> be the (homogeneous) tuple it | ||
determines.</p> | ||
<p><em>exponential</em> <span class="math inline">f\in Y^X = \{f\colon | ||
X\to Y\}</span> is the set of all functions from <span | ||
class="math inline">X</span> to <span class="math inline">Y</span>. We | ||
also write <span class="math inline">X\to Y</span> for <span | ||
class="math inline">Y^X</span>.</p> | ||
<p><em>relation</em> <span class="math inline">R\subseteq X\times | ||
Y</span>. Write <span class="math inline">xRy</span> for <span | ||
class="math inline">\langle x,y\rangle\in R</span> and <span | ||
class="math inline">R' = \{\langle y, x\rangle \mid xRy\}\subseteq | ||
Y\times X</span> for its <em>transpose</em>. The <em>domain</em> of | ||
<span class="math inline">R</span> is <span | ||
class="math inline">\operatorname{dom}R = π_X(R)\subseteq X</span> and | ||
the <em>range</em> is <span class="math inline">\operatorname{ran}R = | ||
π_Y(R)\subseteq Y</span>. The <em>right coset</em> <span | ||
class="math inline">xR = \{y\in Y \mid xRy\}\subseteq Y</span> for <span | ||
class="math inline">x\in X</span>, the <em>left coset</em> <span | ||
class="math inline">Ry = \{x\in X \mid xRy\}\subseteq X</span> for <span | ||
class="math inline">y\in Y</span>. The right cosets <span | ||
class="math inline">\{xR \mid x\in X\}</span> parition <span | ||
class="math inline">\operatorname{ran}R</span> and the left cosets <span | ||
class="math inline">\{Ry \mid y\in Y\}</span> partition <span | ||
class="math inline">\operatorname{dom}R</span>.</p> | ||
<p>The <em>graph</em> of a function <span class="math inline">f\in | ||
Y^X</span> is <span class="math inline">\{\langle x,y\rangle \mid f(x) = | ||
y\}\subseteq X\times Y</span>. A relation <span | ||
class="math inline">R</span> is a function if the <em>right coset</em> | ||
<span class="math inline">xR</span> is a singleton for all <span | ||
class="math inline">x\in X</span> and we write <span | ||
class="math inline">R(x)</span> for that unique element.</p> | ||
<p><em>itoa</em> is <span class="math inline">ι = | ||
(0,1,2,\ldots)\in\mathbf{N}^*</span></p> | ||
</section> | ||
<section id="function" class="level2"> | ||
<h2>Function</h2> | ||
<p>The function <em>take</em> is <span | ||
class="math inline">\uparrow\colon\mathbf{N}\times X^*\to X^*</span> | ||
defined by <span class="math inline">\uparrow(n,x) = (*x), \uparrow(n - | ||
1, +x))</span>, <span class="math inline">\uparrow(0,x) = ()</span>, | ||
<span class="math inline">\uparrow(n,()) = ()</span>, where <span | ||
class="math inline">(x_0, ()) = x_0</span>.</p> | ||
<p>The function <em>drop</em> is <span | ||
class="math inline">\downarrow\colon\mathbf{N}\times X^*\to X^*</span> | ||
defined by <span class="math inline">\downarrow(n,x) = \downarrow(n - 1, | ||
+x)</span>, <span class="math inline">\downarrow(0,x) = x</span>, <span | ||
class="math inline">\downarrow(n,()) = ()</span>.</p> | ||
<p>The function <em>itoa</em> is <span | ||
class="math inline">ι\colon\mathbf{N}\to \mathbf{N}^*</span> <span | ||
class="math inline">ι\mapsto (0,\ldots,n-1)</span>.</p> | ||
</section> | ||
<section id="operation" class="level2"> | ||
<h2>Operation</h2> | ||
<p>The <em>evaluation function</em> <span class="math inline">ε_Y^X = | ||
ε\colon (X\to Y)\times X\to Y</span> is <span class="math inline">ε(f,x) | ||
= f(x)\in Y</span>, <span class="math inline">f\in Y^X</span>, <span | ||
class="math inline">x\in X</span>.</p> | ||
<p>monoid folds <span class="math inline">\star\colon X\times X\to | ||
X</span></p> | ||
<p>left fold <span class="math inline">(\star\colon X^n\to X</span>, | ||
<span class="math inline">(\star(x_0,\ldots,x_n) = x_0\star(x_1\dots | ||
x_n)</span></p> | ||
<p>right fold <span class="math inline">)\star\colon X^n\to X</span>, | ||
<span class="math inline">)\star(x_0,\ldots,x_n) = (x_0\dots | ||
x_{n-1})\star x_n</span></p> | ||
<section id="curry" class="level3"> | ||
<h3>Curry</h3> | ||
<p>The <em>curry function</em> <span class="math inline">γ\colon | ||
((X\times Y)\to Z)\to (X\to(Y\to Z))</span> is <span | ||
class="math inline">(γ(f)(x))(y) = f(x,y)\in Z</span>, <span | ||
class="math inline">f\in X\times Y\to Z</span>, <span | ||
class="math inline">x\in X</span>, <span class="math inline">y\in | ||
Y</span>.</p> | ||
<p>The <em>uncurry function</em> <span class="math inline">γ^*\colon | ||
((X\to (Y\to Z))\to (X\times Y\to Z)</span> is <span | ||
class="math inline">(γ^*(f))(x,y) = f(x,y)\in Z</span>, <span | ||
class="math inline">f\in X\to(Y\to Z)</span>, <span | ||
class="math inline">x\in X</span>, <span class="math inline">y\in | ||
Y</span>.</p> | ||
<p>Use <span class="math inline">.</span> for composition. If <span | ||
class="math inline">f\colon X\to Y</span> identify <span | ||
class="math inline">x</span> with the constant function <span | ||
class="math inline">K_x</span>.</p> | ||
<p>Interpret <span class="math inline">f.x</span> as <span | ||
class="math inline">f.K_x</span> so <span class="math inline">f.x(y) = | ||
f.K_x(y) = f(K_x(y)) = f(x)</span> for all <span | ||
class="math inline">y</span>.</p> | ||
<p>If <span class="math inline">x\in X</span>, <span | ||
class="math inline">y\in Y</span> write <span | ||
class="math inline">x,y</span> for <span class="math inline">(x,y)\in | ||
X\times Y</span>.</p> | ||
</section> | ||
</section> | ||
<section id="shape" class="level2"> | ||
<h2>Shape</h2> | ||
<p>The <em>shape</em> function is <span | ||
class="math inline">ρ\colon\mathbf{N}^k\to | ||
(\mathbf{N}^{k-1}\to\mathbf{N})</span>, <span | ||
class="math inline">ρ\mapsto(n \mapsto n)</span>, <span | ||
class="math inline">ρ(n,\ldots)\mapsto ((i,\ldots) \mapsto i + n | ||
ρ(\ldots)(\ldots))</span></p> | ||
<section id="partition" class="level3"> | ||
<h3>Partition</h3> | ||
<p>A function <span class="math inline">p\colon X\to\iota n</span> | ||
determines a <em>partition</em> on <span class="math inline">X</span> | ||
where <span class="math inline">i\sim i'</span> iff <span | ||
class="math inline">p(i) = p(i')</span>.</p> | ||
<p>Example: s = “a,bc,def” is a string in <span | ||
class="math inline">\mathbf{C}^{\iota 8}</span>. Using cyclic arrays | ||
<span class="math inline">= "," s</span> is <span | ||
class="math inline">\square\blacksquare\square\square\blacksquare\square\square\square</span> | ||
so <span class="math inline">+\backslash= "," s</span> is | ||
<span class="math inline">0111222</span>.</p> | ||
<p>Define <span class="math inline">ν\colon X^n\to X^m</span> by <span | ||
class="math inline">νx_0 x_1 \ldots = x_0 \nu x_2 \ldots</span> if <span | ||
class="math inline">x1 = x0</span> and <span class="math inline">νx_0 | ||
x_1 \ldots = x_0 \nu x_1 \ldots</span> if <span class="math inline">x_1 | ||
\not= x_0</span>.</p> | ||
<!-- | ||
## Remarks | ||
Natural numbers $\NN = \{0, 1, \ldots\}$. | ||
$\iota n = \{0, \ldots, n - 1\}$, $n\in\NN$. | ||
$\iota\colon\NN\to\NN^*$ where $\NN^* = \coprod{n\ge0}\NN^n$. | ||
$\iota n\in\NN^n$. | ||
Every expression is a list of data or functions in Polish notation. | ||
Expressions are parsed right to left. | ||
Data is pushed on the call stack. | ||
Functions know what is on the call stack. | ||
_Each_ is $f␣\scan␣x␣y␣\ldots$ is $f␣x␣f␣y␣\ldots$, $f␣g\scan ␣x$ is $f␣x␣g␣x$. | ||
_Fold_ is $f \fold a␣b \ldots$ is $f␣a␣f␣b␣\ldots))$. | ||
$K$ is the constant function $K\colon X\to\{Y\to X\}$ where $Kxy = x$. | ||
Use $!$ for evaluation. | ||
_Array_ $X^{\iota n}$, $[␣x_0␣x_1␣\ldots\colon \iota n\to X$ by $i\mapsto x_i$. | ||
_Tuple_ $\sqcap_{i\in I} X_i$, $\langle␣x_0␣x_1␣\ldots\colon I\to\coprod{i\in I}X_i$ by $i\mapsto (i, x_i)$. | ||
## Examples | ||
_Average_ $\div␣\stop␣\add\fold␣\add\fold K 1\scan␣x_0␣x_1␣\ldots$ | ||
## Types | ||
_boolean_ $\BB$. | ||
_integer_ $\ZZ$. | ||
_unsigned_ $\NN$. | ||
_number_ $\RR$. | ||
_character_ $\CC$ utf-8 _code points_. | ||
## Structures | ||
Storage: stack (life of function), heap (life of process), persistent (across processes), lazy generators. | ||
--> | ||
</section> | ||
</section> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.