aboutsummaryrefslogtreecommitdiff
path: root/docs/tutorial/expression.html
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2022-07-24 16:04:24 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2022-07-24 16:04:24 -0400
commit1045ede124fc60de41f273d7997521d386c82bf1 (patch)
treed6675707151b8ad73eb1c1935cfcd6083c27a6b1 /docs/tutorial/expression.html
parent7b96b5911e7aa4e542f7f0ea472f71fb7857abe6 (diff)
Editing pass over first two tutorials
Diffstat (limited to 'docs/tutorial/expression.html')
-rw-r--r--docs/tutorial/expression.html25
1 files changed, 13 insertions, 12 deletions
diff --git a/docs/tutorial/expression.html b/docs/tutorial/expression.html
index 3708dc95..9ce866a7 100644
--- a/docs/tutorial/expression.html
+++ b/docs/tutorial/expression.html
@@ -119,7 +119,7 @@
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KDTDtzMpIMOXIM+AIMOXIDLii4Yz">↗️</a><pre> <span class='Paren'>(</span><span class='Number'>4</span><span class='Function'>÷</span><span class='Number'>3</span><span class='Paren'>)</span> <span class='Function'>×</span> <span class='Number'>π</span> <span class='Function'>×</span> <span class='Number'>2</span><span class='Function'>⋆</span><span class='Number'>3</span>
33.51032163829112
</pre>
-<p>The evaluation order is diagrammed below, with the function <code><span class='Function'>⋆</span></code> on the first line evaluated first, then <code><span class='Function'>×</span></code> on the next, and so on. The effect of the parentheses is that <code><span class='Function'>÷</span></code> is evaluated before the leftmost <code><span class='Function'>×</span></code>.</p>
+<p>The evaluation order is diagrammed below, with the function <code><span class='Function'>⋆</span></code> at the highest level evaluated first, then <code><span class='Function'>×</span></code> below it, and so on. The effect of the parentheses is that <code><span class='Function'>÷</span></code> is evaluated before the leftmost <code><span class='Function'>×</span></code>.</p>
<svg viewBox='-174.7 -34 512 188'>
<g font-family='BQN,monospace' font-size='18px' class='Paren' fill='currentColor'>
<rect class='code' stroke-width='1' rx='10' x='-21.68' y='-24' width='205.96' height='168'/>
@@ -223,21 +223,21 @@
</g>
</svg>
-<p>But wait: how do we know that <code><span class='Function'>√</span></code> in the expressions above uses the one-argument form? Remember that it can also take a left argument. For that matter, how do we know that <code><span class='Function'>-</span></code> takes two arguments and not just one? Maybe this looks trivial right now: a good enough answer while we're only doing arithmetic is that a function is called with one argument if there is nothing to its left, or another function, and with two arguments otherwise. But it will get more complicated as we expand the syntax with expressions that can return functions and so on, so it's a good idea to discuss the foundations that will allow us to handle that complexity. In BQN, the way expressions are evaluated—the sequence of function calls and other operations—is determined by the <em>syntactic role</em> of the things it contains. A few rules of roles make sense of the syntax seen so far:</p>
+<p>But wait: how do we know that <code><span class='Function'>√</span></code> in the expressions above uses the one-argument form? Remember that it can also take a left argument. For that matter, how do we know that <code><span class='Function'>-</span></code> takes two arguments and not just one? Maybe this looks trivial right now: a good enough answer while we're only doing arithmetic is that a function is called with one argument if there is nothing to its left, or another function, and with two arguments otherwise. But it'll get more complicated as we expand the syntax with expressions that can return functions and so on, so it's a good idea to discuss the foundations that will allow us to handle that complexity. In BQN, the way expressions are evaluated—the sequence of function calls and other operations—is determined by the <em>syntactic role</em> of the things it contains. A few rules of roles make sense of the syntax seen so far:</p>
<ul>
<li><em>Numeric literals</em> such as <code><span class='Number'>1</span></code> and <code><span class='Number'>π</span></code> are <em>subjects</em>.</li>
<li><em>Primitive functions</em> are <em>functions</em> (gasp).</li>
-<li>A function's arguments are subjects. To call a function it must have a subject on the right, and may have a subject on the left, which is used as the left argument.</li>
+<li>A function's arguments are subjects. To call a function it must have a subject on the right, and may have a subject on the left, which becomes the left argument.</li>
<li>A function's result is a subject—or, more precisely, a function call expression is a subject.</li>
<li>A set of parentheses has the same role as whatever's inside it.</li>
</ul>
-<p>Perhaps more than you thought! To really get roles, it's important to understand that a role is properly a property of an expression, and not its value. In language implementation terms, roles are used only to parse expressions, giving a syntax tree, but don't dictate what values are possible when the tree is evaluated. So it's possible to have a function with a number role or a number with a function role. The reason this doesn't happen with the numeric literals and primitives we've introduced is that these tokens have a constant value. <code><span class='Function'>×</span></code> or <code><span class='Number'>∞</span></code> have the same value in any possible program, and so it makes sense that their types and roles should correspond. When we introduce identifiers, we'll see this correspondence break down—and why that's good!</p>
+<p>Perhaps more than you thought! To really get roles, it's important to understand that a role is properly a property of an expression, and not its value. In language implementation terms, roles are used only to parse expressions, giving a syntax tree, but don't dictate what values may appear when the tree is evaluated. So it's possible to have a function with a number role or a number with a function role. The reason this doesn't happen with the numeric literals and primitives we've introduced is that these tokens have a constant value. <code><span class='Function'>×</span></code> or <code><span class='Number'>∞</span></code> have the same value in any possible program, and so it makes sense that their types and roles should correspond. When we introduce identifiers, we'll see this correspondence break down—and why that's good!</p>
<h2 id="character-arithmetic"><a class="header" href="#character-arithmetic">Character arithmetic</a></h2>
<p>Gosh, that's a lot of arithmetic up there. Maybe adding characters will mix things up a bit? Hang on, you can't add characters, only subtract them… let's back up.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=J2Mn">↗️</a><pre> <span class='String'>'c'</span>
'c'
</pre>
-<p>A character is written with single quotes. As in the C language, it's not the same as a string, which is written with double quotes. There are no escapes for characters: any source code character between single quotes becomes a character literal, even a newline. Some kinds of arithmetic e<a href="https://xkcd.com/1537/">x</a>tend to characters:</p>
+<p>A character is written with single quotes. As in the C language, it's not the same as a string, which is written with double quotes. There are no character escapes: any source code character between single quotes becomes a character literal, even a newline. Some kinds of arithmetic e<a href="https://xkcd.com/1537/">x</a>tend to characters:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=J2MnICsgMQonaCcgLSAnYSc=">↗️</a><pre> <span class='String'>'c'</span> <span class='Function'>+</span> <span class='Number'>1</span>
'd'
<span class='String'>'h'</span> <span class='Function'>-</span> <span class='String'>'a'</span>
@@ -285,7 +285,7 @@
<p>It's a convenient way to write non-printing characters without having to include them in your source code: for example <code><span class='String'>@</span><span class='Function'>+</span><span class='Number'>10</span></code> is the newline character.</p>
<p>Addition and subtraction with affine characters have all the same algebraic properties that they do with numbers. One way to see this is to think of values as a combination of &quot;characterness&quot; (0 for numbers and 1 for characters) and either numeric value or code point. Addition and subtraction are done element-wise on these pairs of numbers, and are allowed if the result is a valid value, that is, its characterness is 0 or 1 and its value is a valid code point if the characterness is 1. However, because the space of values is no longer closed under addition and subtraction, certain rearrangements of valid computations might not work, if one of the values produced in the middle isn't legal.</p>
<h2 id="modifiers"><a class="header" href="#modifiers">Modifiers</a></h2>
-<p>Functions are nice and all, but to really bring us into the space age BQN has a second level of function called <em>modifiers</em> (the space age in this case is when operators were introduced to APL in the early 60s—hey, did you know the <a href="https://aplwiki.com/wiki/APL_conference#1970">second APL conference</a> was held at Goddard Space Flight Center?). While functions apply to subjects, modifiers can apply to functions <em>or</em> subjects, and return functions. For example, the 1-modifier <code><span class='Modifier'>˜</span></code> modifies one function—that's where the 1 comes from—by swapping the arguments before calling it (Swap), or copying the right argument to the left if there's only one (Self).</p>
+<p>Functions are nice and all, but to really bring us into the space age BQN has a second level of function called <em>modifiers</em> (the space age in this case is when operators were introduced to APL in the early 60s—hey, did you know the <a href="https://aplwiki.com/wiki/APL_conference#1970">second APL conference</a> was held at Goddard Space Flight Center?). While functions apply to subjects, modifiers apply to functions <em>or</em> subjects, and return functions. For example, the 1-modifier <code><span class='Modifier'>˜</span></code> modifies one function—that's where the 1 comes from—by swapping the arguments before calling it (Swap), or copying the right argument to the left if there's only one (Self).</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MiAty5wgJ2QnICAjIFN1YnRyYWN0IGZyb20KK8ucIDMgICAgICAjIEFkZCB0byBpdHNlbGY=">↗️</a><pre> <span class='Number'>2</span> <span class='Function'>-</span><span class='Modifier'>˜</span> <span class='String'>'d'</span> <span class='Comment'># Subtract from
</span>'b'
<span class='Function'>+</span><span class='Modifier'>˜</span> <span class='Number'>3</span> <span class='Comment'># Add to itself
@@ -317,13 +317,14 @@
</tr>
</table>
-<p>Another 1-modifier is Undo (<code><span class='Modifier'>⁼</span></code>). BQN has just enough computer algebra facilities to look like a tool for Neanderthals next to a real computer algebra system, and among them is the ability to invert some primitives. In general you can't be sure when Undo will work (it might even be undecidable), but the examples I'll give here are guaranteed by <a href="../spec/inferred.html#undo">the spec</a> to always work in the same way. Starting with a <em>third</em> way to square a number:</p>
+<p>Another 1-modifier is Undo (<code><span class='Modifier'>⁼</span></code>). BQN has just enough computer algebra facilities to look like a tool for Neanderthals next to a real computer algebra system, and among them is the ability to invert some primitives. Undo has a <a href="../spec/inferred.html#undo">specification</a> that fixes results for some functions and modifiers, but allows implementations to go further. In the tutorials we'll stick to the required stuff, which is definitely enough to be practically useful. Starting with a <em>third</em> way to square a number:</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oia4oG8IDQ=">↗️</a><pre> <span class='Function'>√</span><span class='Modifier'>⁼</span> <span class='Number'>4</span>
16
</pre>
<p>But the most important use for Undo in arithmetic is the logarithm, written <code><span class='Function'>⋆</span><span class='Modifier'>⁼</span></code>. That's all a logarithm is: it undoes the Power function! With no left argument <code><span class='Function'>⋆</span><span class='Modifier'>⁼</span></code> is the natural logarithm. If there's a left argument then Undo considers it part of the function to be undone. The result in this case is that <code><span class='Function'>⋆</span><span class='Modifier'>⁼</span></code> with two arguments is the logarithm of the right argument with base given by the left one.</p>
-<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4ouG4oG8IDEwCjIg4ouG4oG8IDMyICAgICMgTG9nIGJhc2UgMgoyIOKLhiAyIOKLhuKBvCAzMgoxMCDii4bigbwgMWU0ICAjIExvZyBiYXNlIDEwIG9mIGEgbnVtYmVyIGluIHNjaWVudGlmaWMgbm90YXRpb24=">↗️</a><pre> <span class='Function'>⋆</span><span class='Modifier'>⁼</span> <span class='Number'>10</span>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4ouG4oG8IDEwCgoyIOKLhuKBvCAzMiAgICAjIExvZyBiYXNlIDIKMiDii4YgMiDii4bigbwgMzIKMTAg4ouG4oG8IDFlNCAgIyBMb2cgYmFzZSAxMCBvZiBhIG51bWJlciBpbiBzY2llbnRpZmljIG5vdGF0aW9u">↗️</a><pre> <span class='Function'>⋆</span><span class='Modifier'>⁼</span> <span class='Number'>10</span>
2.302585092994046
+
<span class='Number'>2</span> <span class='Function'>⋆</span><span class='Modifier'>⁼</span> <span class='Number'>32</span> <span class='Comment'># Log base 2
</span>5
<span class='Number'>2</span> <span class='Function'>⋆</span> <span class='Number'>2</span> <span class='Function'>⋆</span><span class='Modifier'>⁼</span> <span class='Number'>32</span>
@@ -331,14 +332,14 @@
<span class='Number'>10</span> <span class='Function'>⋆</span><span class='Modifier'>⁼</span> <span class='Number'>1e4</span> <span class='Comment'># Log base 10 of a number in scientific notation
</span>4
</pre>
-<p>Another 1-modifier, which at the moment is tremendously useless, is Constant <code><span class='Modifier'>˙</span></code>. It turns its operand into a constant function that always returns the operand (inputs to modifiers are called <em>operands</em> because <em>modificands</em> is just too horrible).</p>
+<p>Another 1-modifier, which at the moment is tremendously useless, is Constant (<code><span class='Modifier'>˙</span></code>). It turns its operand into a constant function that always returns the operand (inputs to modifiers are called <em>operands</em> because <em>modificands</em> is just too horrible).</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MiAzy5kgNA==">↗️</a><pre> <span class='Number'>2</span> <span class='Number'>3</span><span class='Modifier'>˙</span> <span class='Number'>4</span>
3
</pre>
<p>Well, I guess it's not pedagogically useless, as it does demonstrate that a modifier can be applied to subjects as well as functions. Even though <code><span class='Number'>3</span></code> is a subject, <code><span class='Number'>3</span><span class='Modifier'>˙</span></code> is a function, and can be applied to and ignore the two arguments <code><span class='Number'>2</span></code> and <code><span class='Number'>4</span></code>.</p>
<p>With three examples you may have noticed that 1-modifiers tend to cluster at the top of the line. In fact, every primitive 1-modifer is a superscript character: we've covered <code><span class='Modifier'>˜⁼˙</span></code>, and the remaining array-based modifiers <code><span class='Modifier'>˘¨⌜´˝`</span></code> will show up later.</p>
<h2 id="2-modifiers"><a class="header" href="#2-modifiers">2-modifiers</a></h2>
-<p>Made it to the last role, the 2-modifier (if you think something's been skipped, you're free to call subjects 0-modifiers. They don't modify anything. Just not when other people can hear you). To introduce them we'll use Atop <code><span class='Modifier2'>∘</span></code>, which composes two functions as in mathematics. The resulting function allows one or two arguments like any BQN function: these are all passed to the function on the right, and the result of that application is passed to the function on the left. So the function on the left is only ever called with one argument.</p>
+<p>Made it to the last role, the 2-modifier (if you think something's been skipped, you're free to call subjects 0-modifiers. They don't modify anything. Just not when other people can hear you). To introduce them we'll use Atop (<code><span class='Modifier2'>∘</span></code>), which composes two functions as in mathematics. The resulting function allows one or two arguments like any BQN function: these are all passed to the function on the right, and the result of that application is passed to the function on the left. So the function on the left is only ever called with one argument.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyDDl8uc4oiYKyA0ICAjIFNxdWFyZSBvZiAzIHBsdXMgNAot4oiYKMOXy5wpIDUgICMgTmVnYXRpdmUgc3F1YXJlIG9mIDU=">↗️</a><pre> <span class='Number'>3</span> <span class='Function'>×</span><span class='Modifier'>˜</span><span class='Modifier2'>∘</span><span class='Function'>+</span> <span class='Number'>4</span> <span class='Comment'># Square of 3 plus 4
</span>49
<span class='Function'>-</span><span class='Modifier2'>∘</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>˜</span><span class='Paren'>)</span> <span class='Number'>5</span> <span class='Comment'># Negative square of 5
@@ -387,8 +388,8 @@
</svg>
<p>This ordering is more consistent with the rule that a 1-modifier's operand should go to its left. If we tried going from right to left we'd end up with <code><span class='Function'>×</span><span class='Paren'>(</span><span class='Modifier'>˜</span><span class='Modifier2'>∘</span><span class='Function'>+</span><span class='Paren'>)</span></code>, which uses <code><span class='Modifier'>˜</span></code> as an operand to <code><span class='Modifier2'>∘</span></code>. But a modifier can't be used as an operand. To make it work we'd have to give 1-modifiers a higher precedence than 2-modifiers.</p>
-<p>In fact, the rules for modifiers are exactly the same as those for functions, but reversed. So why is there a distinction between 1- and 2-modifiers, when for functions we can look to the left to see whether there is a left argument? The reason is that it's natural to follow a 1-modifier by a subject or function that isn't supposed to be its operand. Using an example from the last section, <code><span class='Function'>+</span><span class='Modifier'>˜</span> <span class='Number'>3</span></code> has a subject to the right of the 1-modifier <code><span class='Modifier'>˜</span></code>. Even worse, <code><span class='Function'>+</span><span class='Modifier'>˜</span> <span class='Function'>÷</span> <span class='Number'>3</span></code> looks just like <code><span class='Function'>+</span><span class='Modifier2'>∘</span> <span class='Function'>÷</span> <span class='Number'>3</span></code>, but it's two functions <code><span class='Function'>+</span><span class='Modifier'>˜</span></code> and <code><span class='Function'>÷</span></code> applied to <code><span class='Number'>3</span></code> while the version with Atop is a single function <code><span class='Function'>+</span><span class='Modifier2'>∘</span><span class='Function'>÷</span></code> applied to <code><span class='Number'>3</span></code>. So the two-layer system of functions and modifiers forces modifiers to have a fixed number of operands even though every function (including those derived by applying modifiers) can be called with one or two arguments.</p>
-<p>Remember that 1-modifiers are all superscripts? The characters for 2-modifiers use a different rule: each contains an <em>unbroken</em> circle (that is, lines might touch it but not go through it). The 2-modifiers in BQN are the combinators <code><span class='Modifier2'>∘○⊸⟜⊘</span></code>, the sort-of-combinators <code><span class='Modifier2'>⌾◶⍟</span></code>, and the not-at-all-combinators <code><span class='Modifier2'>⎉⚇⎊</span></code>. And the functions that make that unbroken circle rule necessary are written <code><span class='Function'>⌽⍉</span></code>. Since every primitive is a function, 1-modifier, or 2-modifier, you can always tell what type (and role) it has: a superscript is a 1-modifier, an unbroken circle makes it a 2-modifier, and otherwise it's a function.</p>
+<p>In fact, the rules for modifiers are exactly the same as those for functions, but reversed. So why is there a distinction between 1- and 2-modifiers, when for functions we can look to the left to see whether there's a left argument? The reason is that it's natural to follow a 1-modifier by a subject or function that isn't supposed to be its operand. Using an example from the last section, <code><span class='Function'>+</span><span class='Modifier'>˜</span> <span class='Number'>3</span></code> has a subject to the right of the 1-modifier <code><span class='Modifier'>˜</span></code>. Even worse, <code><span class='Function'>+</span><span class='Modifier'>˜</span> <span class='Function'>÷</span> <span class='Number'>3</span></code> looks just like <code><span class='Function'>+</span><span class='Modifier2'>∘</span> <span class='Function'>÷</span> <span class='Number'>3</span></code>, but it's two functions <code><span class='Function'>+</span><span class='Modifier'>˜</span></code> and <code><span class='Function'>÷</span></code> applied to <code><span class='Number'>3</span></code> while the version with Atop is a single function <code><span class='Function'>+</span><span class='Modifier2'>∘</span><span class='Function'>÷</span></code> applied to <code><span class='Number'>3</span></code>. So the two-layer system of functions and modifiers forces modifiers to have a fixed number of operands even though every function (including those derived by applying modifiers) can be called with one or two arguments.</p>
+<p>Remember how 1-modifiers are all superscripts? The characters for 2-modifiers use a different rule: each contains an <em>unbroken</em> circle (that is, lines might touch it but not go through it). The 2-modifiers in BQN are the combinators <code><span class='Modifier2'>∘○⊸⟜⊘</span></code>, the sort-of-combinators <code><span class='Modifier2'>⌾◶⍟</span></code>, and the not-at-all-combinators <code><span class='Modifier2'>⎉⚇⎊</span></code>. And the functions that make that &quot;unbroken&quot; part necessary are written <code><span class='Function'>⌽⍉</span></code>. Since every primitive is a function, 1-modifier, or 2-modifier, you can always tell what type (and role) it has: a superscript is a 1-modifier, an unbroken circle makes it a 2-modifier, and otherwise it's a function.</p>
<h2 id="summary"><a class="header" href="#summary">Summary</a></h2>
<p>The objects we've seen so far are:</p>
<table>