aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2022-06-08 22:25:20 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2022-06-08 22:25:20 -0400
commit7733b104e3eff841dcd1ac3f67731eb80746e427 (patch)
treea49f1190234df28c4355eb2408f3f4c0d31c7568 /docs
parentbed78fe6147cb7921b7367960d406d28d37cb019 (diff)
Add page on function and modifier types
Diffstat (limited to 'docs')
-rw-r--r--docs/doc/glossary.html16
-rw-r--r--docs/doc/index.html3
-rw-r--r--docs/doc/ops.html32
-rw-r--r--docs/doc/types.html4
4 files changed, 45 insertions, 10 deletions
diff --git a/docs/doc/glossary.html b/docs/doc/glossary.html
index 878a6738..720c12cc 100644
--- a/docs/doc/glossary.html
+++ b/docs/doc/glossary.html
@@ -16,17 +16,17 @@
<li><a href="types.html#numbers"><strong>Number</strong></a>: Like some caveman was counting but then forty thousand years of math happened to it.</li>
<li><a href="types.html#characters"><strong>Character</strong></a>: A Unicode code point.</li>
<li><a href="types.html#arrays"><strong>Array</strong></a>: A multidimensional collection of values.</li>
-<li><a href="types.html#functions"><strong>Function</strong></a>: An operation that is called on one or two arguments.</li>
-<li><a href="types.html#modifiers"><strong>1-modifier</strong></a>: An operation that is called on one operand.</li>
-<li><a href="types.html#modifiers"><strong>2-modifier</strong></a>: An operation that is called on two operands.</li>
+<li><a href="ops.html#functions"><strong>Function</strong></a>: An operation that is called on one or two arguments.</li>
+<li><a href="ops.html#modifiers"><strong>1-modifier</strong></a>: An operation that is called on one operand.</li>
+<li><a href="ops.html#modifiers"><strong>2-modifier</strong></a>: An operation that is called on two operands.</li>
<li><a href="namespace.html"><strong>Namespace</strong></a>: A container for variables, some of which are exposed as fields.</li>
</ul>
<p>A few terms refer to multiple types collectively:</p>
<ul>
<li><a href="based.html#starting-from-atoms"><strong>Atom</strong></a>: A value that's not an array.</li>
-<li><a href="types.html#modifiers"><strong>Modifier</strong></a>: A 1-modifier or 2-modifier.</li>
+<li><a href="ops.html#modifiers"><strong>Modifier</strong></a>: A 1-modifier or 2-modifier.</li>
<li><a href="types.html#data-types"><strong>Data type</strong></a>: Number, character, or array.</li>
-<li><a href="types.html#operation-types"><strong>Operation type</strong></a>: Function, 1-modifier, or 2-modifier.</li>
+<li><a href="ops.html"><strong>Operation type</strong></a>: Function, 1-modifier, or 2-modifier.</li>
<li><a href="lexical.html#mutation"><strong>Mutable type</strong></a>: Operation or namespace.</li>
</ul>
<p>BQN uses standard terminology for particular sets of numbers, with natural numbers starting at 0.</p>
@@ -81,7 +81,7 @@
</ul>
<h2 id="operations"><a class="header" href="#operations">Operations</a></h2>
<ul>
-<li><strong>Operation</strong>: A value that is called on inputs to perform computation and return a result or cause an error.</li>
+<li><a href="ops.html"><strong>Operation</strong></a>: A value that is called on inputs to perform computation and return a result or cause an error.</li>
<li><strong>Call</strong>: Submit inputs to an operation and receive any result.</li>
<li><strong>Input</strong>: A value given (<em>passed</em>) to an operation when it's called.</li>
<li><strong>Result</strong>: A value returned from an operation when called.</li>
@@ -93,8 +93,8 @@
<li><strong>Dyadic</strong>: Called with two arguments, always or in a particular instance.</li>
</ul>
<ul>
-<li><strong>Compound function</strong>: A derived function or train.</li>
-<li><strong>Derived function</strong>: A function produced by binding operands to a deferred modifier; doing so does not cause any computation.</li>
+<li><a href="ops.html#functions"><strong>Compound function</strong></a>: A derived function or train.</li>
+<li><a href="ops.html#functions"><strong>Derived function</strong></a>: A function produced by binding operands to a deferred modifier; doing so does not cause any computation.</li>
<li><a href="train.html"><strong>Train</strong></a>: A function composed of two or more functions.</li>
<li><a href="fold.html#identity-values"><strong>Identity value</strong></a>: An inferred property of a function: the result of a reduction with this function on an empty array.</li>
</ul>
diff --git a/docs/doc/index.html b/docs/doc/index.html
index 9038f45b..c86ab0d3 100644
--- a/docs/doc/index.html
+++ b/docs/doc/index.html
@@ -32,9 +32,10 @@
<li><a href="indices.html">Array indices</a></li>
<li><a href="fill.html">Fill elements</a></li>
<li><a href="leading.html">The leading axis model</a></li>
+<li><a href="ops.html">Functions and modifiers</a></li>
<li><a href="tacit.html">Tacit programming</a></li>
<li><a href="train.html">Function trains</a></li>
-<li><a href="block.html">Blocks</a> (including function and modifier definition)</li>
+<li><a href="block.html">Blocks</a></li>
<li><a href="lexical.html">Lexical scoping</a></li>
<li><a href="functional.html">Functional programming</a></li>
<li><a href="control.html">Control flow</a></li>
diff --git a/docs/doc/ops.html b/docs/doc/ops.html
new file mode 100644
index 00000000..617aab63
--- /dev/null
+++ b/docs/doc/ops.html
@@ -0,0 +1,32 @@
+<head>
+ <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/>
+ <link href="../style.css" rel="stylesheet"/>
+ <title>BQN: Functions and modifiers</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="functions-and-modifiers"><a class="header" href="#functions-and-modifiers">Functions and modifiers</a></h1>
+<p>BQN's three operation <a href="types.html">types</a> are the function, 1-modifier, and 2-modifier.</p>
+<p>In general, an operation is <em>called</em> by passing in <em>inputs</em>, and returns a <em>result</em> value. The inputs and result can have any type. Since BQN isn't a pure <a href="functional.html">functional</a> language, the operation might also have side effects: it can modify the values of variables, perform program input or output, or call other operations with their own side effects.</p>
+<p>This page deals with types, not syntax. Expressions with a function or modifier <a href="expression.html#syntactic-role">role</a> don't have to yield a value of that type when run. However, primitives and blocks do have roles that match their types.</p>
+<h2 id="functions"><a class="header" href="#functions">Functions</a></h2>
+<p>A function has one or two inputs called <em>arguments</em>. The general layout is <code><span class='Value'>𝕨</span> <span class='Function'>Fn</span> <span class='Value'>𝕩</span></code>, with an optional left argument <code><span class='Value'>𝕨</span></code> and a non-optional right argument <code><span class='Value'>𝕩</span></code>. The number of arguments is called its <em>valence</em>, and functions are naturally <em>ambivalent</em>, allowing one or two arguments. When called with one argument—<code><span class='Value'>𝕩</span></code> only—it's <em>monadic</em>, and when called with two it's <em>dyadic</em>. More arguments, or a variable number, should be handled by using a list argument; <a href="block.html#destructuring">destructuring headers</a> can be useful in this case.</p>
+<p>Functions can be <a href="primitive.html">primitives</a> or <a href="block.html">blocks</a> (or system functions), but there are also two kinds of <em>compound</em> functions: <em>derived</em> functions that consist of a modifier and its operands, and <a href="train.html">trains</a>. <a href="tacit.html">Tacit</a> programming refers to code written without blocks, so of course it uses compound functions heavily.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyArIDQgICAgICMgUHJpbWl0aXZlIGZ1bmN0aW9uCnvwnZWpK/Cdlal9IDQgICAjIEJsb2NrIGZ1bmN0aW9uCivLnCA0ICAgICAgIyBEZXJpdmVkIGZ1bmN0aW9uCijiiqIrw7cpIDQgICAjIFRyYWlu">↗️</a><pre> <span class='Number'>3</span> <span class='Function'>+</span> <span class='Number'>4</span> <span class='Comment'># Primitive function
+</span>7
+ <span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Function'>+</span><span class='Value'>𝕩</span><span class='Brace'>}</span> <span class='Number'>4</span> <span class='Comment'># Block function
+</span>8
+ <span class='Function'>+</span><span class='Modifier'>˜</span> <span class='Number'>4</span> <span class='Comment'># Derived function
+</span>8
+ <span class='Paren'>(</span><span class='Function'>⊢+÷</span><span class='Paren'>)</span> <span class='Number'>4</span> <span class='Comment'># Train
+</span>4.25
+</pre>
+<p>Compound functions have some differences with blocks, most importantly that blocks can express <a href="lexical.html#mutation">mutation</a> while a compound function can't have side effects unless one of its constituent functions or modifiers does. More subtly, compound functions <a href="match.html#atomic-equality">match</a> when they have the same composition (much like lists) while blocks must be the same instance to match. A function's composition can also be inspected directly with <code><span class='Function'>•Decompose</span></code> (<a href="../spec/system.html#operation-properties">spec</a>).</p>
+<p>While normally functions are just called, some primitives might try to infer properties of functions, which necessarily involves inspecting their definitions. The <a href="fold.html#identity-values">identity value</a> used by reductions and the results of <a href="undo.html">Undo</a> and <a href="under.html">Under</a> rely on inference.</p>
+<h2 id="modifiers"><a class="header" href="#modifiers">Modifiers</a></h2>
+<p>There are two modifier types, separated for syntax reasons: 1-modifiers follow the layout <code><span class='Function'>𝔽</span> <span class='Modifier'>_mod</span></code> and 2-modifiers follow <code><span class='Function'>𝔽</span> <span class='Modifier2'>_mod_</span> <span class='Function'>𝔾</span></code>. The values <code><span class='Function'>𝔽</span></code> and <code><span class='Function'>𝔾</span></code> are called <em>operands</em>. There aren't any compound modifiers, so modifiers are always <a href="primitive.html">primitives</a> or system-provided, or <a href="block.html">blocks</a>. A primitive is a 1-modifier when it's written as a superscript like <code><span class='Modifier'>˘</span></code> or <code><span class='Modifier'>˝</span></code>, and a 2-modifier when it has an unbroken circle like <code><span class='Modifier2'>∘</span></code> or <code><span class='Modifier2'>⍟</span></code> (not <code><span class='Function'>⌽</span></code> or <code><span class='Function'>⍉</span></code>).</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=K+KOiTMgICAgIyBQcmltaXRpdmUgMi1tb2RpZmllciAoZGVmZXJyZWQpCjJ7LfCdlZd9ICAjIEJsb2NrIDEtbW9kaWZpZXI=">↗️</a><pre> <span class='Function'>+</span><span class='Modifier2'>⎉</span><span class='Number'>3</span> <span class='Comment'># Primitive 2-modifier (deferred)
+</span>+⎉3
+ <span class='Number'>2</span><span class='Brace'>{</span><span class='Function'>-</span><span class='Value'>𝕗</span><span class='Brace'>}</span> <span class='Comment'># Block 1-modifier
+</span>¯2
+</pre>
+<p>In general, a modifier call works just like a function: inputs out, result in. Syntactically, a modifier call expression has a function role, but that doesn't affect execution. However, one kind of modifier is more strict: a <em>deferred</em> modifier doesn't evaluate anything when called, but returns a derived function. When the derived function is finally called, the modifier's definition determines what happens. Primitive modifiers are always deferred, and a block modifier is deferred if it includes arguments, either in the header or with <code><span class='Value'>𝕨</span></code>, <code><span class='Value'>𝕩</span></code>, or <code><span class='Value'>𝕤</span></code> in the body.</p>
diff --git a/docs/doc/types.html b/docs/doc/types.html
index 20ab9578..c27a9400 100644
--- a/docs/doc/types.html
+++ b/docs/doc/types.html
@@ -63,6 +63,7 @@
<p>Arrays are value types (or immutable), so that there is no way to &quot;change&quot; the shape or elements of an array. An array with different properties is a different array. As a consequence, arrays are an inductive type, and it's not possible for an array to contain itself, or contain an array that contains itself, and so on. However, it is possible for an array to contain a function or other operation that has access to the array through a variable, and in this sense an array can &quot;know about&quot; itself.</p>
<p>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 values must not change behavior when placed in an array. However, this doesn't preclude changing the storage type of an array for better performance: for example, in a BQN implementation using 64-bit floats, an array whose elements are all integers that fit in 32-bit int range might be represented as an array of 32-bit ints.</p>
<h2 id="operation-types"><a class="header" href="#operation-types">Operation types</a></h2>
+<p><em>Full documentation <a href="ops.html">here</a>.</em></p>
<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"><a class="header" href="#functions">Functions</a></h3>
@@ -70,4 +71,5 @@
<h3 id="modifiers"><a class="header" href="#modifiers">Modifiers</a></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>
<h2 id="namespaces"><a class="header" href="#namespaces">Namespaces</a></h2>
-<p>Functions and modifiers have internal scopes which they can manipulate (by defining and modifying variables) to save and update information. Namespaces let the programmer to expose this state more directly: identifiers in a namespace may be exported, allowing code outside the namespace to read their values. They are described in detail <a href="namespace.html">here</a>.</p>
+<p><em>Full documentation <a href="namespace.html">here</a>.</em></p>
+<p>Functions and modifiers have internal scopes which they can manipulate (by defining and modifying variables) to save and update information. Namespaces let the programmer to expose this state more directly: identifiers in a namespace may be exported, allowing code outside the namespace to read their values.</p>