aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/block.md20
-rw-r--r--docs/doc/block.html20
2 files changed, 20 insertions, 20 deletions
diff --git a/doc/block.md b/doc/block.md
index b6b83cc9..8cdaed9c 100644
--- a/doc/block.md
+++ b/doc/block.md
@@ -2,7 +2,7 @@
# Blocks
-In BQN, a *block* is any piece of code surrounded with curly braces `{}`. Blocks can be used simply to group statements, or can define functions or modifiers. They are the sole large-scale structure used to organize programs.
+In BQN, a *block* is any piece of code surrounded with curly braces `{}`. Blocks can be used simply to group statements, or can define functions or modifiers. They are the sole large-scale structure used to organize programs. An important aspect of organization is [namespaces](namespace.md), which are created with blocks but not discussed on this page.
Blocks are most commonly used to define functions by including one of the special names for arguments, `𝕨` or `𝕩`. With the operands `𝔽` or `𝔾`, they can also define 1-modifiers or 2-modifiers.
@@ -16,7 +16,7 @@ Because they use [lexical scoping](lexical.md), blocks can also be used to encap
## Headerless blocks
-In the simplest case a block is just a list of statements, which are executed to *evaluate* the block. A block with no special names like `𝕨` or `𝕩` is called an *immediate block*, and is evaluated as soon as it is reached. The only think such a block does is group some statements, and create a scope for them so that definitions made there are discarded when the block finishes. Even this small amount of functionality could be useful; as an example the following program can build up an array from named components without polluting the rest of the program with those names.
+In the simplest case a block is just a list of statements, which are executed to *evaluate* the block. A block with no special names like `𝕨` or `𝕩` is called an *immediate block*, and is evaluated as soon as it is reached. The only thing such a block does is group some statements, and create a scope for them so that definitions made there are discarded when the block finishes. Even this small amount of functionality could be useful; as an example the following program can build up an array from named components without polluting the rest of the program with those names.
updown ← { up←↕5 β‹„ downβ†βŒ½up β‹„ up∾down }
updown
@@ -32,11 +32,11 @@ An immediate block is only ever evaluated once, and can't be used for control fl
| `π•˜` | `𝔾` | Right [operand](#operands)
| `𝕣` | none | Modifier [self-reference](#self-reference)
-Of these, `𝕣` is sort of a "more special" character, as we'll discuss below. Except for `𝕣`, every special name is a single character and can't have underscores added to spell it as a modifier, allowing a modifier to be applied to a special name with no spacing as in `𝕗_m`, something that can't be done with ordinary names.
+Of these, `𝕣` is sort of a "more special" character, as we'll discuss below. Except for `𝕣`, every special name is a single character and can't have underscores added to spell it as a modifier. This allows a modifier to be applied to a special name with no spacing, as in `𝕗_m`, where it couldn't be with ordinary names.
### Arguments
-The names `𝕨` and `𝕩`, and their uppercase spellings, represent function arguments. As the argument to a function is typically data, it's more common to use the lowercase forms for these. Either of these names will turn an immediate block into a function (or an immediate modifier into a deferred one; see the next section). Instead of being evaluated as soon as it appears in the source, a function is evaluated when it's called, with the special names set to appropriate values. Unlike in Dyalog APL's dfns, their values can be changed like ordinary variables.
+The names `𝕨` and `𝕩`, and their uppercase spellings, represent function arguments. As the argument to a function is typically data, it's more common to use the lowercase forms for these. Having either of these names turns an immediate block into a function (or an immediate modifier into a deferred one; see the next section). Instead of being evaluated as soon as it appears in the source, a function is evaluated when it's called, with the special names set to appropriate values. Their values can be changed like ordinary variables.
{'c'=𝕩} "abcd"
{ 𝕩+↩2 β‹„ 0≍𝕩 } 3
@@ -118,8 +118,8 @@ Its syntax mirrors an application of the block. As suggested by the positioning,
{ π•Šπ•©:
…
- # An immediate or deferred 2-modifier
- { F _op_ val:
+ # An immediate 2-modifier with some destructuring
+ { F _op_ Β·β€Ώval:
…
In all cases special names still work just like in a headerless function. In this respect the effect of the header is the same as a series of assignments at the beginning of a function, such as the following translation of the second header above:
@@ -147,24 +147,24 @@ The name `𝕨` in this context can refer to either a left argument or no left a
### Short headers
-A header does not need to include all inputs, as shown by the `F _op_ val:` header above. The simplest case, when no inputs are given, is called a *label*. While it doesn't restrict the inputs, a label specifies the type of the block and gives an internal name that can be used to refer to it.
+A header can also be a plain name with no inputs, called a *label*. A label specifies the type of the block and gives an internal name that can be used to refer to it, but doesn't specify the inputs.
{ b: # Block
{ π•Š: # Function
{ _𝕣: # 1-Modifier
{ _𝕣_: # 2-Modifier
-For immediate blocks, this is the only type of header possible, and it must use an identifier as there is no applicable special name. However, the name can't be used: it doesn't make sense to refer to a value while it is still being computed!
+For immediate blocks, this is the only type of header possible, and it must use an identifier as there is no applicable special name. However, the name can't be used in code: it doesn't make sense to refer to a value while it is still being computed!
## Multiple bodies
-Blocks that define functions and deferred modifiers can include more than one body, separated by semicolons `;`. The body used for a particular evaluation is chosen based on the arguments the the block. One special case applies when there are exactly two bodies either without headers or with labels only: in this case, the first applies when there is one argument and the second when there are two.
+Blocks can include more than one body, separated by semicolons `;`. The body used for a particular evaluation is chosen based on the arguments the the block. One special case is that functions and deferred modifiers can have two headerless bodies (that is, no headers or predicatesβ€”see below): the first applies when there's one argument and the second when there are two.
Ambiv ← { ⟨1,π•©βŸ© ; ⟨2,𝕨,π•©βŸ© }
Ambiv 'a'
'a' Ambiv 'b'
-Bodies before the last two must have headers that include arguments. When a block that includes this type of header is called, its headers are checked in order for compatibility with the arguments. The first body with a compatible header is used.
+Bodies with headers come before any that don't have them. When a block is called, its headers are checked in order for compatibility with the arguments, and the first body with a compatible header is used.
CaseAdd ← { 2π•Š3:0β€Ώ5 ; 2π•Šπ•©:⟨1,2+π•©βŸ© ; π•Šπ•©:2‿𝕩 }
2 CaseAdd 3
diff --git a/docs/doc/block.html b/docs/doc/block.html
index a31d33f3..31f59aed 100644
--- a/docs/doc/block.html
+++ b/docs/doc/block.html
@@ -5,7 +5,7 @@
</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="blocks"><a class="header" href="#blocks">Blocks</a></h1>
-<p>In BQN, a <em>block</em> is any piece of code surrounded with curly braces <code><span class='Brace'>{}</span></code>. Blocks can be used simply to group statements, or can define functions or modifiers. They are the sole large-scale structure used to organize programs.</p>
+<p>In BQN, a <em>block</em> is any piece of code surrounded with curly braces <code><span class='Brace'>{}</span></code>. Blocks can be used simply to group statements, or can define functions or modifiers. They are the sole large-scale structure used to organize programs. An important aspect of organization is <a href="namespace.html">namespaces</a>, which are created with blocks but not discussed on this page.</p>
<p>Blocks are most commonly used to define functions by including one of the special names for arguments, <code><span class='Value'>𝕨</span></code> or <code><span class='Value'>𝕩</span></code>. With the operands <code><span class='Function'>𝔽</span></code> or <code><span class='Function'>𝔾</span></code>, they can also define 1-modifiers or 2-modifiers.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=e/CdlakrMX0gMwrDl3vwnZWp8J2UvfCdlal9IDQ=">↗️</a><pre> <span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Function'>+</span><span class='Number'>1</span><span class='Brace'>}</span> <span class='Number'>3</span>
4
@@ -18,7 +18,7 @@
⟨ "inner" "outer" ⟩
</pre>
<h2 id="headerless-blocks"><a class="header" href="#headerless-blocks">Headerless blocks</a></h2>
-<p>In the simplest case a block is just a list of statements, which are executed to <em>evaluate</em> the block. A block with no special names like <code><span class='Value'>𝕨</span></code> or <code><span class='Value'>𝕩</span></code> is called an <em>immediate block</em>, and is evaluated as soon as it is reached. The only think such a block does is group some statements, and create a scope for them so that definitions made there are discarded when the block finishes. Even this small amount of functionality could be useful; as an example the following program can build up an array from named components without polluting the rest of the program with those names.</p>
+<p>In the simplest case a block is just a list of statements, which are executed to <em>evaluate</em> the block. A block with no special names like <code><span class='Value'>𝕨</span></code> or <code><span class='Value'>𝕩</span></code> is called an <em>immediate block</em>, and is evaluated as soon as it is reached. The only thing such a block does is group some statements, and create a scope for them so that definitions made there are discarded when the block finishes. Even this small amount of functionality could be useful; as an example the following program can build up an array from named components without polluting the rest of the program with those names.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=dXBkb3duIOKGkCB7IHVw4oaQ4oaVNSDii4QgZG93buKGkOKMvXVwIOKLhCB1cOKIvmRvd24gfQp1cGRvd24=">↗️</a><pre> <span class='Value'>updown</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Value'>up</span><span class='Gets'>←</span><span class='Function'>↕</span><span class='Number'>5</span> <span class='Separator'>β‹„</span> <span class='Value'>down</span><span class='Gets'>←</span><span class='Function'>⌽</span><span class='Value'>up</span> <span class='Separator'>β‹„</span> <span class='Value'>up</span><span class='Function'>∾</span><span class='Value'>down</span> <span class='Brace'>}</span>
<span class='Value'>updown</span>
⟨ 0 1 2 3 4 4 3 2 1 0 ⟩
@@ -65,9 +65,9 @@
</tr>
</tbody>
</table>
-<p>Of these, <code><span class='Value'>𝕣</span></code> is sort of a &quot;more special&quot; character, as we'll discuss below. Except for <code><span class='Value'>𝕣</span></code>, every special name is a single character and can't have underscores added to spell it as a modifier, allowing a modifier to be applied to a special name with no spacing as in <code><span class='Value'>𝕗</span><span class='Modifier'>_m</span></code>, something that can't be done with ordinary names.</p>
+<p>Of these, <code><span class='Value'>𝕣</span></code> is sort of a &quot;more special&quot; character, as we'll discuss below. Except for <code><span class='Value'>𝕣</span></code>, every special name is a single character and can't have underscores added to spell it as a modifier. This allows a modifier to be applied to a special name with no spacing, as in <code><span class='Value'>𝕗</span><span class='Modifier'>_m</span></code>, where it couldn't be with ordinary names.</p>
<h3 id="arguments"><a class="header" href="#arguments">Arguments</a></h3>
-<p>The names <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code>, and their uppercase spellings, represent function arguments. As the argument to a function is typically data, it's more common to use the lowercase forms for these. Either of these names will turn an immediate block into a function (or an immediate modifier into a deferred one; see the next section). Instead of being evaluated as soon as it appears in the source, a function is evaluated when it's called, with the special names set to appropriate values. Unlike in Dyalog APL's dfns, their values can be changed like ordinary variables.</p>
+<p>The names <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code>, and their uppercase spellings, represent function arguments. As the argument to a function is typically data, it's more common to use the lowercase forms for these. Having either of these names turns an immediate block into a function (or an immediate modifier into a deferred one; see the next section). Instead of being evaluated as soon as it appears in the source, a function is evaluated when it's called, with the special names set to appropriate values. Their values can be changed like ordinary variables.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eydjJz3wnZWpfSAiYWJjZCIKeyDwnZWpK+KGqTIg4ouEIDDiiY3wnZWpIH0gMwo0IHsg4p+o8J2VqeKLhC3wnZWo4p+pIH0gNQ==">↗️</a><pre> <span class='Brace'>{</span><span class='String'>'c'</span><span class='Function'>=</span><span class='Value'>𝕩</span><span class='Brace'>}</span> <span class='String'>&quot;abcd&quot;</span>
⟨ 0 0 1 0 ⟩
<span class='Brace'>{</span> <span class='Value'>𝕩</span><span class='Function'>+</span><span class='Gets'>↩</span><span class='Number'>2</span> <span class='Separator'>β‹„</span> <span class='Number'>0</span><span class='Function'>≍</span><span class='Value'>𝕩</span> <span class='Brace'>}</span> <span class='Number'>3</span>
@@ -153,8 +153,8 @@
</span><span class='Brace'>{</span> <span class='Function'>π•Š</span><span class='Value'>𝕩</span><span class='Head'>:</span>
<span class='Value'>…</span>
-<span class='Comment'># An immediate or deferred 2-modifier
-</span><span class='Brace'>{</span> <span class='Function'>F</span> <span class='Modifier2'>_op_</span> <span class='Value'>val</span><span class='Head'>:</span>
+<span class='Comment'># An immediate 2-modifier with some destructuring
+</span><span class='Brace'>{</span> <span class='Function'>F</span> <span class='Modifier2'>_op_</span> <span class='Nothing'>Β·</span><span class='Ligature'>β€Ώ</span><span class='Value'>val</span><span class='Head'>:</span>
<span class='Value'>…</span>
</pre>
<p>In all cases special names still work just like in a headerless function. In this respect the effect of the header is the same as a series of assignments at the beginning of a function, such as the following translation of the second header above:</p>
@@ -175,22 +175,22 @@
<p>Any element of a function or modifier header can be left nameless by using the corresponding special name in that position, instead of an identifier. For example, the header <code><span class='Value'>𝕨</span> <span class='Function'>𝔽</span><span class='Modifier2'>_𝕣_</span><span class='Function'>𝔾</span> <span class='Value'>𝕩</span><span class='Head'>:</span></code> incorporates as much vagueness as possible. It indicates a deferred 2-modifier, but provides no other information.</p>
<p>The name <code><span class='Value'>𝕨</span></code> in this context can refer to either a left argument or no left argument, allowing a header with arguments to be used even for an ambiguous function. Recall that <code><span class='Value'>𝕨</span></code> is the only token other than <code><span class='Nothing'>Β·</span></code> that can have no value. If an identifier or list is given as the left argument, then the function must be called with a left argument.</p>
<h3 id="short-headers"><a class="header" href="#short-headers">Short headers</a></h3>
-<p>A header does not need to include all inputs, as shown by the <code><span class='Function'>F</span> <span class='Modifier2'>_op_</span> <span class='Value'>val</span><span class='Head'>:</span></code> header above. The simplest case, when no inputs are given, is called a <em>label</em>. While it doesn't restrict the inputs, a label specifies the type of the block and gives an internal name that can be used to refer to it.</p>
+<p>A header can also be a plain name with no inputs, called a <em>label</em>. A label specifies the type of the block and gives an internal name that can be used to refer to it, but doesn't specify the inputs.</p>
<pre><span class='Brace'>{</span> <span class='Value'>b</span><span class='Head'>:</span> <span class='Comment'># Block
</span><span class='Brace'>{</span> <span class='Function'>π•Š</span><span class='Head'>:</span> <span class='Comment'># Function
</span><span class='Brace'>{</span> <span class='Modifier'>_𝕣</span><span class='Head'>:</span> <span class='Comment'># 1-Modifier
</span><span class='Brace'>{</span> <span class='Modifier2'>_𝕣_</span><span class='Head'>:</span> <span class='Comment'># 2-Modifier
</span></pre>
-<p>For immediate blocks, this is the only type of header possible, and it must use an identifier as there is no applicable special name. However, the name can't be used: it doesn't make sense to refer to a value while it is still being computed!</p>
+<p>For immediate blocks, this is the only type of header possible, and it must use an identifier as there is no applicable special name. However, the name can't be used in code: it doesn't make sense to refer to a value while it is still being computed!</p>
<h2 id="multiple-bodies"><a class="header" href="#multiple-bodies">Multiple bodies</a></h2>
-<p>Blocks that define functions and deferred modifiers can include more than one body, separated by semicolons <code><span class='Head'>;</span></code>. The body used for a particular evaluation is chosen based on the arguments the the block. One special case applies when there are exactly two bodies either without headers or with labels only: in this case, the first applies when there is one argument and the second when there are two.</p>
+<p>Blocks can include more than one body, separated by semicolons <code><span class='Head'>;</span></code>. The body used for a particular evaluation is chosen based on the arguments the the block. One special case is that functions and deferred modifiers can have two headerless bodies (that is, no headers or predicatesβ€”see below): the first applies when there's one argument and the second when there are two.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=QW1iaXYg4oaQIHsg4p+oMSzwnZWp4p+pIDsg4p+oMizwnZWoLPCdlanin6kgfQpBbWJpdiAnYScKJ2EnIEFtYml2ICdiJw==">↗️</a><pre> <span class='Function'>Ambiv</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Bracket'>⟨</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span> <span class='Head'>;</span> <span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Value'>𝕨</span><span class='Separator'>,</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span> <span class='Brace'>}</span>
<span class='Function'>Ambiv</span> <span class='String'>'a'</span>
⟨ 1 'a' ⟩
<span class='String'>'a'</span> <span class='Function'>Ambiv</span> <span class='String'>'b'</span>
⟨ 2 'a' 'b' ⟩
</pre>
-<p>Bodies before the last two must have headers that include arguments. When a block that includes this type of header is called, its headers are checked in order for compatibility with the arguments. The first body with a compatible header is used.</p>
+<p>Bodies with headers come before any that don't have them. When a block is called, its headers are checked in order for compatibility with the arguments, and the first body with a compatible header is used.</p>
<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Q2FzZUFkZCDihpAgeyAy8J2VijM6MOKAvzUgOyAy8J2VivCdlak64p+oMSwyK/Cdlanin6kgOyDwnZWK8J2VqToy4oC/8J2VqSB9CjIgQ2FzZUFkZCAzCjIgQ2FzZUFkZCA0CiAgQ2FzZUFkZCA0">↗️</a><pre> <span class='Function'>CaseAdd</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Number'>2</span><span class='Function'>π•Š</span><span class='Number'>3</span><span class='Head'>:</span><span class='Number'>0</span><span class='Ligature'>β€Ώ</span><span class='Number'>5</span> <span class='Head'>;</span> <span class='Number'>2</span><span class='Function'>π•Š</span><span class='Value'>𝕩</span><span class='Head'>:</span><span class='Bracket'>⟨</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Number'>2</span><span class='Function'>+</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span> <span class='Head'>;</span> <span class='Function'>π•Š</span><span class='Value'>𝕩</span><span class='Head'>:</span><span class='Number'>2</span><span class='Ligature'>β€Ώ</span><span class='Value'>𝕩</span> <span class='Brace'>}</span>
<span class='Number'>2</span> <span class='Function'>CaseAdd</span> <span class='Number'>3</span>
⟨ 0 5 ⟩