aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--doc/README.md1
-rw-r--r--doc/block.md190
-rw-r--r--doc/syntax.md8
-rw-r--r--docs/doc/block.html214
-rw-r--r--docs/doc/index.html1
-rw-r--r--docs/doc/syntax.html7
-rw-r--r--docs/index.html2
8 files changed, 417 insertions, 8 deletions
diff --git a/README.md b/README.md
index 10dff2e6..e6fbbc3d 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ BQN maintains many of the ideas that made APL\360 revolutionary in 1966:
It incorporates concepts developed over years of APL practice:
* The [**leading axis model**](doc/leading.md), which allows for simpler built-in functions.
* Trains and combinators for **tacit programming**.
-* Lightweight **anonymous functions** (like [dfns](https://aplwiki.com/wiki/Dfn)).
+* Lightweight [**anonymous functions**](doc/block.md) (like [dfns](https://aplwiki.com/wiki/Dfn)).
But BQN is redesigned from the ground up, with brand new ideas to make these paradigms easier to use and less likely to fail.
* The [**based array model**](doc/based.md) makes non-arrays a fundamental part of the language, and removes the surprise of floating arrays and the hassle of explicit boxes. New **array notation** eliminates the gotchas of [stranding](https://aplwiki.com/wiki/Strand_notation).
diff --git a/doc/README.md b/doc/README.md
index 13927751..823456a9 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -11,6 +11,7 @@ Overview:
Concepts:
- [Based array theory](based.md)
+- [Blocks](block.md) (including function and modifier definition)
- [Context-free grammar](context.md)
- [Functional programming](functional.md)
- [Array indices](indices.md)
diff --git a/doc/block.md b/doc/block.md
new file mode 100644
index 00000000..c75ea321
--- /dev/null
+++ b/doc/block.md
@@ -0,0 +1,190 @@
+*View this file with results and syntax highlighting [here](https://mlochbaum.github.io/BQN/doc/block.html).*
+
+# 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.
+
+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.
+
+ {𝕩+1} 3
+ Γ—{𝕩𝔽𝕩} 4
+
+Because they use [lexical scoping](https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scoping), blocks can also be used to encapsulate code. If a block uses only variables that it initializes, then it has no dependence on its environment and would work the same way if defined anywhere. But it can also use external variables, defined in a containing block.
+
+ a←b←"outer"
+ { a←"inner" β‹„ aβ€Ώb }
+
+## 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.
+
+ updown ← { up←↕5 β‹„ downβ†βŒ½up β‹„ up∾down }
+ updown
+
+An immediate block is only ever evaluated once, and can't be used for control flow in a program. Including special names in a headerless block lets us define functions and modifiers, which have a broader range of uses. All special names are listed below:
+
+| Lowercase | Uppercase | Meaning
+|-----------|-----------|---------
+| `𝕩` | `𝕏` | Right [argument](#arguments)
+| `𝕨` | `π•Ž` | Left [argument](#arguments), or Nothing (`Β·`)
+| `𝕀` | `π•Š` | Function [self-reference](#self-reference)
+| `𝕗` | `𝔽` | Left [operand](#operands)
+| `π•˜` | `𝔾` | 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.
+
+### 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.
+
+ {'c'=𝕩} "abcd"
+ { 𝕩+↩2 β‹„ 0βˆΎπ•© } 3
+ 4 { βŸ¨π•©β‹„-π•¨βŸ© } 5
+
+A function with `𝕨` in its definition doesn't have to be called with two arguments. If it has only one, then `𝕨` is given the special value Nothing `Β·`. This is the only time a variable can ever be Nothing, as an assignment such as `v←·` is not allowed.
+
+ 3 { (2×𝕨)-𝕩 } 1
+ { (2×𝕨)-𝕩 } 1
+
+In the second function, `𝕨` behaves just like `Β·`, so that the function `2×𝕨` is not evaluated and `-` doesn't have a left argument. It has a similar effect when used as the left argument to a function in a train.
+
+ "abc" { (π•¨β‰βŒ½) 𝕩 } "def"
+ { (π•¨β‰βŒ½) 𝕩 } "def"
+
+However, `Β·` can only be used as an argument, and not a list element or operand. Don't use `𝕨` in these ways in a function that could be called monadically. Another potential issue is that `⊸` and `⟜` don't work the way you might expect.
+
+ { 𝕨 β‹†βŠΈ- 𝕩 } 5
+
+Called dyadically, this function will expand to `(⋆𝕨)-𝕩`, so we might expect the monadic result to be `-𝕩`. This sort of expansion isn't right with `Β·` on the left. `β‹†βŠΈ-` taken as a whole is a function, so `Β· β‹†βŠΈ- 𝕩` is just `β‹†βŠΈ- 𝕩`, or `(⋆𝕩)-𝕩`, giving the large result seen above.
+
+### Operands
+
+The special names `𝔽` and `𝔾`, and their lowercase forms, represent operands. Since operands are more often functions, they're typically shown with the uppercase spelling. If `𝔽` is present in a block then it defines a 1-modifier or 2-modifier depending on whether `𝔾` is present; if `𝔾` is there it's always a 2-modifier.
+
+ 4 {Γ—Λœπ•—}
+ 2 {𝕗+π•˜} 3
+
+As shown above, modifiers without `𝕨`, `𝕩`, or `𝕀` behave essentially like functions with a higher precedence. These *immediate modifiers* take operands and return a result of any type. The result is given a function role, so it's most common to return a function, rather than a number as shown above.
+
+ _dot_ ← {π”½Β΄βˆ˜π”Ύ}
+ 1β€Ώ2β€Ώ3 +_dot_Γ— 1β€Ώ0β€Ώ1
+
+However, if one of these names is included, then a *deferred modifier* is created instead: rather than evaluate the contents when the modifier is called, the operands are bound to it to create a derived function. When this function is called, the statements in the block are evaluated.
+
+ +{𝕩𝔽𝕩} 6
+ 2 β₯Š{βŸ¨π”½π•¨,π”Ύπ•©βŸ©}- 5
+
+The distinction between an immediate and deferred modifier only matters inside the braces. Once defined, the object is simply a modifier that can be called on operands to return a result. For a deferred modifier this result will always be a function; for an immediate modifier it could be anything.
+
+### Self-reference
+
+If a block is assigned a name after it is created, this name can be used for recursion:
+
+ Fact ← { 𝕩 Γ— (0⊸<)β—Ά1β€ΏFact 𝕩-1 }
+ Fact 7
+ (Γ—Β΄1+↕) 7 # There's often a simpler solution than recursion
+
+This is somewhat unsatisfying because it is external to the function being defined, even though it doesn't depend on outside information. Instead, the special name `π•Š` can be used to refer to the function it appears in. This allows anonymous recursive functions to be defined.
+
+ { 𝕩 Γ— (0⊸<)β—Ά1β€ΏFact 𝕩-1 } 7
+
+For modifiers, `𝕣` refers to the containing modifier. `π•Š` makes the modifier a deferred modifier like `𝕨` and `𝕩` do, and refers to the derived function. For example, this tail-recursive factorial function uses the operand to accumulate a result, a task that is usually done with a second `factorial_helper` function in elementary Scheme.
+
+ Fact_mod ← 1 { (0⊸<)β—ΆβŸ¨1, (𝕨×𝕩)_π•£βŸ© 𝕩-1 }
+ Fact_mod 7
+
+Because `𝕣` only ever refers to a 1-modifier or 2-modifer, it can never make sense to refer to it as a function, and the uppercase letter `ℝ` is not recognized by BQN. In order to allow `𝕣` to be spelled as a 1-modifier `_𝕣` or 2-modifier `_𝕣_`, it is treated as an ordinary identifier character, so it must be separated from letters or numbers by spaces.
+
+## Block headers
+
+As a program becomes larger, it often becomes necessary to name inputs to blocks rather than just using special names. It can also become difficult to identify what kind of block is being defined, as it requires scanning through the block for special names. A *block header*, which is separated from the body of a block by a colon `:`, specifies the kind of block and can declare names for the block and its inputs. Its syntax mirrors an application of the block. As suggested by the positioning, the names given in a header apply only inside the block.
+
+ # A dyadic function called Func
+ { l Func r:
+ …
+
+ # A deferred 1-modifier with a list argument
+ { Fn _apply ⟨a,b⟩:
+ …
+
+ # A monadic function with no names given
+ { π•Šπ•©:
+ …
+
+ # An immediate or deferred 2-modifier
+ { F _op_ val:
+ …
+
+In all cases special names are defined just as with 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:
+
+ { # Fn _apply ⟨a,b⟩:
+ Fn ← 𝔽
+ _apply ← _𝕣
+ ⟨a,b⟩ ← 𝕩
+ …
+
+Unlike these assignments, the header also constrains what inputs the block can take: a monadic 1-modifier like the one above can't take a right operand or left argument, and consequently its body can't contain `𝔾` or `𝕨`. Calling it with a left argument, or a right argument that isn't a two-element list, will result in an error.
+
+### Destructuring
+
+Arguments, but not operands, allow destructuring like assignment does. While assignment only tolerates lists of variables, header destructuring also allows constants. The argument must match the given structure, including the constants where they appear, or an error results.
+
+ Destruct ← { π•Š aβ€Ώ1β€ΏβŸ¨b,2⟩: a≍b }
+ Destruct 5β€Ώ1β€ΏβŸ¨7,2⟩
+
+### Special names in headers
+
+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 `𝕨 𝔽_𝕣_𝔾 𝕩:` incorporates as much vagueness as possible. It indicates a deferred 2-modifier, but provides no other information.
+
+The name `𝕨` 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 `𝕨` is the only token other than `Β·` 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.
+
+### 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.
+
+ { 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, this name can't be used, except for [returns](#returns): 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.
+
+ 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.
+
+ CaseAdd ← { 2π•Š3:0β€Ώ5 ; 2π•Šπ•©:⟨1,2+π•©βŸ© ; π•Šπ•©:2‿𝕩 }
+ 2 CaseAdd 3
+ 2 CaseAdd 4
+ CaseAdd 4
+
+If no header is compatible, the call results in an error.
+
+ 3 CaseAdd 3
+ ERROR
+
+### Case headers
+
+A special rule allows for convenient case-matching syntax for one-argument functions. In any function header with one argument, the function name can be omitted as long as the argument is *not* a plain identifierβ€”it must be `𝕩` or a compound value like a list to distinguish it from an immediate block label.
+
+ Test ← {
+ "abc": "string"
+ ⟨2,b⟩: βŒ½π•©
+ 5: "number"
+ 𝕩: "default"
+ }
+
+These case-style headers function exactly the same as if they were preceded by `π•Š`, and can be mixed with other kinds of headers.
+
+## Returns
+
+*This feature is not yet included in any BQN implementation.*
+
+The glyph `β†’` indicates an early return from a block. It must be preceded either by one of the self-reference special names `π•Š` or `𝕣` or by an internal name for a containing block. The combination of name and return tokenβ€”like `Fβ†’`, let's sayβ€”is a function that returns from the current instance of the indicated block. If that instance has already returned, then it instead results in an error.
diff --git a/doc/syntax.md b/doc/syntax.md
index 3f8b9800..9c34bc2a 100644
--- a/doc/syntax.md
+++ b/doc/syntax.md
@@ -16,13 +16,13 @@ Glyph(s) | Meaning
`()` | Expression grouping
`←` | [Define](#assignment)
`↩` | [Change](#assignment)
-`β†’` | Return
+`β†’` | [Return](block.md#returns)
`β‹„,` or newline | Statement or element [separator](#separators)
`⟨⟩` | [List](#list-notation) (rank-1 array)
`β€Ώ` | [Strand](#list-notation) (lightweight list syntax)
`{}` | [Block](#blocks) such as a function definition
-`:` | Block header
-`;` | Block body separator
+`:` | [Block header](block.md#block-headers)
+`;` | [Block body separator](block.md#multiple-bodies)
`π•¨π•Ž` | [Left argument](#blocks)
`𝕩𝕏` | [Right argument](#blocks)
`π•€π•Š` | [Function self-reference](#blocks)
@@ -92,6 +92,8 @@ If added, [sets and dictionaries](extensions.md#sets-and-dictionaries) would als
### Blocks
+*[Full documentation](block.md)*
+
Blocks are written with curly braces `{}` and can be used to group expressions or define functions and modifiers. The contents are simply a sequence of expressions, where each is evaluated and the result of the last is returned in order to evaluate the block. This result can have any value, and its syntactic role in the calling context is determined by the normal rules: functions return subjects and modifiers return functions. Blocks have lexical scope.
The special names `𝕨` and `𝕩`, which stand for arguments, and `𝕗` and `π•˜`, which stand for operands, are available inside curly braces. Like ordinary names, the lowercase forms indicate subjects and the uppercase forms `π•Žπ•π”½π”Ύ` indicate functions. The type and syntactic role of the block is determined by its contents: a 2-modifier contains `π•˜`, a 1-modifier contains `𝕗` but not `π•˜`, and a function contains neither but does have one of `π•¨π•©π•€π•Žπ•π•Š`. If no special names are present the block is an *immediate block* and is evaluated as soon as it appears, with the result having a subject role.
diff --git a/docs/doc/block.html b/docs/doc/block.html
new file mode 100644
index 00000000..7c077588
--- /dev/null
+++ b/docs/doc/block.html
@@ -0,0 +1,214 @@
+<head>
+ <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/>
+ <link href="../style.css" rel="stylesheet"/>
+ <title>BQN: Blocks</title>
+</head>
+<div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a></div>
+<h1 id="blocks">Blocks</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>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=&run">↗️</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
+ <span class='Function'>Γ—</span><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>
+16
+</pre>
+<p>Because they use <a href="https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scoping">lexical scoping</a>, blocks can also be used to encapsulate code. If a block uses only variables that it initializes, then it has no dependence on its environment and would work the same way if defined anywhere. But it can also use external variables, defined in a containing block.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=YeKGkGLihpAib3V0ZXIiCnsgYeKGkCJpbm5lciIg4ouEIGHigL9iIH0=&run">↗️</a><pre> <span class='Value'>a</span><span class='Gets'>←</span><span class='Value'>b</span><span class='Gets'>←</span><span class='String'>&quot;outer&quot;</span>
+ <span class='Brace'>{</span> <span class='Value'>a</span><span class='Gets'>←</span><span class='String'>&quot;inner&quot;</span> <span class='Separator'>β‹„</span> <span class='Value'>a</span><span class='Ligature'>β€Ώ</span><span class='Value'>b</span> <span class='Brace'>}</span>
+⟨ "inner" "outer" ⟩
+</pre>
+<h2 id="headerless-blocks">Headerless blocks</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>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=dXBkb3duIOKGkCB7IHVw4oaQ4oaVNSDii4QgZG93buKGkOKMvXVwIOKLhCB1cOKIvmRvd24gfQp1cGRvd24=&run">↗️</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 ⟩
+</pre>
+<p>An immediate block is only ever evaluated once, and can't be used for control flow in a program. Including special names in a headerless block lets us define functions and modifiers, which have a broader range of uses. All special names are listed below:</p>
+<table>
+<thead>
+<tr>
+<th>Lowercase</th>
+<th>Uppercase</th>
+<th>Meaning</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><code><span class='Value'>𝕩</span></code></td>
+<td><code><span class='Function'>𝕏</span></code></td>
+<td>Right <a href="#arguments">argument</a></td>
+</tr>
+<tr>
+<td><code><span class='Value'>𝕨</span></code></td>
+<td><code><span class='Function'>π•Ž</span></code></td>
+<td>Left <a href="#arguments">argument</a>, or Nothing (<code><span class='Nothing'>Β·</span></code>)</td>
+</tr>
+<tr>
+<td><code><span class='Value'>𝕀</span></code></td>
+<td><code><span class='Function'>π•Š</span></code></td>
+<td>Function <a href="#self-reference">self-reference</a></td>
+</tr>
+<tr>
+<td><code><span class='Value'>𝕗</span></code></td>
+<td><code><span class='Function'>𝔽</span></code></td>
+<td>Left <a href="#operands">operand</a></td>
+</tr>
+<tr>
+<td><code><span class='Value'>π•˜</span></code></td>
+<td><code><span class='Function'>𝔾</span></code></td>
+<td>Right <a href="#operands">operand</a></td>
+</tr>
+<tr>
+<td><code><span class='Value'>𝕣</span></code></td>
+<td>none</td>
+<td>Modifier <a href="#self-reference">self-reference</a></td>
+</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>
+<h3 id="arguments">Arguments</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>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eydjJz3wnZWpfSAiYWJjZCIKeyDwnZWpK+KGqTIg4ouEIDDiiL7wnZWpIH0gMwo0IHsg4p+o8J2VqeKLhC3wnZWo4p+pIH0gNQ==&run">↗️</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>
+⟨ 0 5 ⟩
+ <span class='Number'>4</span> <span class='Brace'>{</span> <span class='Bracket'>⟨</span><span class='Value'>𝕩</span><span class='Separator'>β‹„</span><span class='Function'>-</span><span class='Value'>𝕨</span><span class='Bracket'>⟩</span> <span class='Brace'>}</span> <span class='Number'>5</span>
+⟨ 5 ¯4 ⟩
+</pre>
+<p>A function with <code><span class='Value'>𝕨</span></code> in its definition doesn't have to be called with two arguments. If it has only one, then <code><span class='Value'>𝕨</span></code> is given the special value Nothing <code><span class='Nothing'>Β·</span></code>. This is the only time a variable can ever be Nothing, as an assignment such as <code><span class='Value'>v</span><span class='Gets'>←</span><span class='Nothing'>Β·</span></code> is not allowed.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MyB7ICgyw5fwnZWoKS3wnZWpIH0gMQogIHsgKDLDl/CdlagpLfCdlakgfSAx&run">↗️</a><pre> <span class='Number'>3</span> <span class='Brace'>{</span> <span class='Paren'>(</span><span class='Number'>2</span><span class='Function'>Γ—</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>-</span><span class='Value'>𝕩</span> <span class='Brace'>}</span> <span class='Number'>1</span>
+5
+ <span class='Brace'>{</span> <span class='Paren'>(</span><span class='Number'>2</span><span class='Function'>Γ—</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>-</span><span class='Value'>𝕩</span> <span class='Brace'>}</span> <span class='Number'>1</span>
+Β―1
+</pre>
+<p>In the second function, <code><span class='Value'>𝕨</span></code> behaves just like <code><span class='Nothing'>Β·</span></code>, so that the function <code><span class='Number'>2</span><span class='Function'>Γ—</span><span class='Value'>𝕨</span></code> is not evaluated and <code><span class='Function'>-</span></code> doesn't have a left argument. It has a similar effect when used as the left argument to a function in a train.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=ImFiYyIgeyAo8J2VqOKJjeKMvSkg8J2VqSB9ICJkZWYiCiAgICAgIHsgKPCdlajiiY3ijL0pIPCdlakgfSAiZGVmIg==&run">↗️</a><pre> <span class='String'>&quot;abc&quot;</span> <span class='Brace'>{</span> <span class='Paren'>(</span><span class='Value'>𝕨</span><span class='Function'>β‰βŒ½</span><span class='Paren'>)</span> <span class='Value'>𝕩</span> <span class='Brace'>}</span> <span class='String'>&quot;def&quot;</span>
+β”Œβ”€
+β•΅"abc
+ fed"
+ β”˜
+ <span class='Brace'>{</span> <span class='Paren'>(</span><span class='Value'>𝕨</span><span class='Function'>β‰βŒ½</span><span class='Paren'>)</span> <span class='Value'>𝕩</span> <span class='Brace'>}</span> <span class='String'>&quot;def&quot;</span>
+β”Œβ”€
+β•΅"fed"
+ β”˜
+</pre>
+<p>However, <code><span class='Nothing'>Β·</span></code> can only be used as an argument, and not a list element or operand. Don't use <code><span class='Value'>𝕨</span></code> in these ways in a function that could be called monadically. Another potential issue is that <code><span class='Modifier2'>⊸</span></code> and <code><span class='Modifier2'>⟜</span></code> don't work the way you might expect.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eyDwnZWoIOKLhuKKuC0g8J2VqSB9IDU=&run">↗️</a><pre> <span class='Brace'>{</span> <span class='Value'>𝕨</span> <span class='Function'>⋆</span><span class='Modifier2'>⊸</span><span class='Function'>-</span> <span class='Value'>𝕩</span> <span class='Brace'>}</span> <span class='Number'>5</span>
+143.413159102577
+</pre>
+<p>Called dyadically, this function will expand to <code><span class='Paren'>(</span><span class='Function'>⋆</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>-</span><span class='Value'>𝕩</span></code>, so we might expect the monadic result to be <code><span class='Function'>-</span><span class='Value'>𝕩</span></code>. This sort of expansion isn't right with <code><span class='Nothing'>Β·</span></code> on the left. <code><span class='Function'>⋆</span><span class='Modifier2'>⊸</span><span class='Function'>-</span></code> taken as a whole is a function, so <code><span class='Nothing'>Β·</span> <span class='Function'>⋆</span><span class='Modifier2'>⊸</span><span class='Function'>-</span> <span class='Value'>𝕩</span></code> is just <code><span class='Function'>⋆</span><span class='Modifier2'>⊸</span><span class='Function'>-</span> <span class='Value'>𝕩</span></code>, or <code><span class='Paren'>(</span><span class='Function'>⋆</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Function'>-</span><span class='Value'>𝕩</span></code>, giving the large result seen above.</p>
+<h3 id="operands">Operands</h3>
+<p>The special names <code><span class='Function'>𝔽</span></code> and <code><span class='Function'>𝔾</span></code>, and their lowercase forms, represent operands. Since operands are more often functions, they're typically shown with the uppercase spelling. If <code><span class='Function'>𝔽</span></code> is present in a block then it defines a 1-modifier or 2-modifier depending on whether <code><span class='Function'>𝔾</span></code> is present; if <code><span class='Function'>𝔾</span></code> is there it's always a 2-modifier.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=NCB7w5fLnPCdlZd9CjIge/CdlZcr8J2VmH0gMw==&run">↗️</a><pre> <span class='Number'>4</span> <span class='Brace'>{</span><span class='Function'>Γ—</span><span class='Modifier'>˜</span><span class='Value'>𝕗</span><span class='Brace'>}</span>
+16
+ <span class='Number'>2</span> <span class='Brace'>{</span><span class='Value'>𝕗</span><span class='Function'>+</span><span class='Value'>π•˜</span><span class='Brace'>}</span> <span class='Number'>3</span>
+5
+</pre>
+<p>As shown above, modifiers without <code><span class='Value'>𝕨</span></code>, <code><span class='Value'>𝕩</span></code>, or <code><span class='Value'>𝕀</span></code> behave essentially like functions with a higher precedence. These <em>immediate modifiers</em> take operands and return a result of any type. The result is given a function role, so it's most common to return a function, rather than a number as shown above.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=X2RvdF8g4oaQIHvwnZS9wrTiiJjwnZS+fQox4oC/MuKAvzMgK19kb3Rfw5cgMeKAvzDigL8x&run">↗️</a><pre> <span class='Modifier2'>_dot_</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Function'>𝔽</span><span class='Modifier'>Β΄</span><span class='Modifier2'>∘</span><span class='Function'>𝔾</span><span class='Brace'>}</span>
+ <span class='Number'>1</span><span class='Ligature'>β€Ώ</span><span class='Number'>2</span><span class='Ligature'>β€Ώ</span><span class='Number'>3</span> <span class='Function'>+</span><span class='Modifier2'>_dot_</span><span class='Function'>Γ—</span> <span class='Number'>1</span><span class='Ligature'>β€Ώ</span><span class='Number'>0</span><span class='Ligature'>β€Ώ</span><span class='Number'>1</span>
+4
+</pre>
+<p>However, if one of these names is included, then a <em>deferred modifier</em> is created instead: rather than evaluate the contents when the modifier is called, the operands are bound to it to create a derived function. When this function is called, the statements in the block are evaluated.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=K3vwnZWp8J2UvfCdlal9IDYKMiDipYp74p+o8J2UvfCdlags8J2UvvCdlanin6l9LSA1&run">↗️</a><pre> <span class='Function'>+</span><span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Function'>𝔽</span><span class='Value'>𝕩</span><span class='Brace'>}</span> <span class='Number'>6</span>
+12
+ <span class='Number'>2</span> <span class='Function'>β₯Š</span><span class='Brace'>{</span><span class='Bracket'>⟨</span><span class='Function'>𝔽</span><span class='Value'>𝕨</span><span class='Separator'>,</span><span class='Function'>𝔾</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span><span class='Brace'>}</span><span class='Function'>-</span> <span class='Number'>5</span>
+⟨ ⟨ 2 ⟩ ¯5 ⟩
+</pre>
+<p>The distinction between an immediate and deferred modifier only matters inside the braces. Once defined, the object is simply a modifier that can be called on operands to return a result. For a deferred modifier this result will always be a function; for an immediate modifier it could be anything.</p>
+<h3 id="self-reference">Self-reference</h3>
+<p>If a block is assigned a name after it is created, this name can be used for recursion:</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=RmFjdCDihpAgeyDwnZWpIMOXICgw4oq4PCnil7Yx4oC/RmFjdCDwnZWpLTEgfQpGYWN0IDcKKMOXwrQxK+KGlSkgNyAgIyBUaGVyZSdzIG9mdGVuIGEgc2ltcGxlciBzb2x1dGlvbiB0aGFuIHJlY3Vyc2lvbg==&run">↗️</a><pre> <span class='Function'>Fact</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Value'>𝕩</span> <span class='Function'>Γ—</span> <span class='Paren'>(</span><span class='Number'>0</span><span class='Modifier2'>⊸</span><span class='Function'>&lt;</span><span class='Paren'>)</span><span class='Modifier2'>β—Ά</span><span class='Number'>1</span><span class='Ligature'>β€Ώ</span><span class='Function'>Fact</span> <span class='Value'>𝕩</span><span class='Function'>-</span><span class='Number'>1</span> <span class='Brace'>}</span>
+ <span class='Function'>Fact</span> <span class='Number'>7</span>
+5040
+ <span class='Paren'>(</span><span class='Function'>Γ—</span><span class='Modifier'>Β΄</span><span class='Number'>1</span><span class='Function'>+↕</span><span class='Paren'>)</span> <span class='Number'>7</span> <span class='Comment'># There's often a simpler solution than recursion
+</span>5040
+</pre>
+<p>This is somewhat unsatisfying because it is external to the function being defined, even though it doesn't depend on outside information. Instead, the special name <code><span class='Function'>π•Š</span></code> can be used to refer to the function it appears in. This allows anonymous recursive functions to be defined.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eyDwnZWpIMOXICgw4oq4PCnil7Yx4oC/RmFjdCDwnZWpLTEgfSA3&run">↗️</a><pre> <span class='Brace'>{</span> <span class='Value'>𝕩</span> <span class='Function'>Γ—</span> <span class='Paren'>(</span><span class='Number'>0</span><span class='Modifier2'>⊸</span><span class='Function'>&lt;</span><span class='Paren'>)</span><span class='Modifier2'>β—Ά</span><span class='Number'>1</span><span class='Ligature'>β€Ώ</span><span class='Function'>Fact</span> <span class='Value'>𝕩</span><span class='Function'>-</span><span class='Number'>1</span> <span class='Brace'>}</span> <span class='Number'>7</span>
+5040
+</pre>
+<p>For modifiers, <code><span class='Value'>𝕣</span></code> refers to the containing modifier. <code><span class='Function'>π•Š</span></code> makes the modifier a deferred modifier like <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code> do, and refers to the derived function. For example, this tail-recursive factorial function uses the operand to accumulate a result, a task that is usually done with a second <code><span class='Value'>factorial_helper</span></code> function in elementary Scheme.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=RmFjdF9tb2Qg4oaQIDEgeyAoMOKKuDwp4pe24p+oMSwgKPCdlajDl/CdlakpX/CdlaPin6kg8J2VqS0xIH0KRmFjdF9tb2QgNw==&run">↗️</a><pre> <span class='Function'>Fact_mod</span> <span class='Gets'>←</span> <span class='Number'>1</span> <span class='Brace'>{</span> <span class='Paren'>(</span><span class='Number'>0</span><span class='Modifier2'>⊸</span><span class='Function'>&lt;</span><span class='Paren'>)</span><span class='Modifier2'>β—Ά</span><span class='Bracket'>⟨</span><span class='Number'>1</span><span class='Separator'>,</span> <span class='Paren'>(</span><span class='Value'>𝕨</span><span class='Function'>Γ—</span><span class='Value'>𝕩</span><span class='Paren'>)</span><span class='Modifier'>_𝕣</span><span class='Bracket'>⟩</span> <span class='Value'>𝕩</span><span class='Function'>-</span><span class='Number'>1</span> <span class='Brace'>}</span>
+ <span class='Function'>Fact_mod</span> <span class='Number'>7</span>
+1
+</pre>
+<p>Because <code><span class='Value'>𝕣</span></code> only ever refers to a 1-modifier or 2-modifer, it can never make sense to refer to it as a function, and the uppercase letter <code><span class='Value'>ℝ</span></code> is not recognized by BQN. In order to allow <code><span class='Value'>𝕣</span></code> to be spelled as a 1-modifier <code><span class='Modifier'>_𝕣</span></code> or 2-modifier <code><span class='Modifier2'>_𝕣_</span></code>, it is treated as an ordinary identifier character, so it must be separated from letters or numbers by spaces.</p>
+<h2 id="block-headers">Block headers</h2>
+<p>As a program becomes larger, it often becomes necessary to name inputs to blocks rather than just using special names. It can also become difficult to identify what kind of block is being defined, as it requires scanning through the block for special names. A <em>block header</em>, which is separated from the body of a block by a colon <code><span class='Value'>:</span></code>, specifies the kind of block and can declare names for the block and its inputs. Its syntax mirrors an application of the block. As suggested by the positioning, the names given in a header apply only inside the block.</p>
+<pre><span class='Comment'># A dyadic function called Func
+</span><span class='Brace'>{</span> <span class='Value'>l</span> <span class='Function'>Func</span> <span class='Value'>r:</span>
+ <span class='Value'>…</span>
+
+<span class='Comment'># A deferred 1-modifier with a list argument
+</span><span class='Brace'>{</span> <span class='Function'>Fn</span> <span class='Modifier'>_apply</span> <span class='Bracket'>⟨</span><span class='Value'>a</span><span class='Separator'>,</span><span class='Value'>b</span><span class='Bracket'>⟩</span><span class='Value'>:</span>
+ <span class='Value'>…</span>
+
+<span class='Comment'># A monadic function with no names given
+</span><span class='Brace'>{</span> <span class='Function'>π•Š</span><span class='Value'>𝕩:</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='Value'>…</span>
+</pre>
+<p>In all cases special names are defined just as with 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>
+<pre><span class='Brace'>{</span> <span class='Comment'># Fn _apply ⟨a,b⟩:
+</span> <span class='Function'>Fn</span> <span class='Gets'>←</span> <span class='Function'>𝔽</span>
+ <span class='Modifier'>_apply</span> <span class='Gets'>←</span> <span class='Modifier'>_𝕣</span>
+ <span class='Bracket'>⟨</span><span class='Value'>a</span><span class='Separator'>,</span><span class='Value'>b</span><span class='Bracket'>⟩</span> <span class='Gets'>←</span> <span class='Value'>𝕩</span>
+ <span class='Value'>…</span>
+</pre>
+<p>Unlike these assignments, the header also constrains what inputs the block can take: a monadic 1-modifier like the one above can't take a right operand or left argument, and consequently its body can't contain <code><span class='Function'>𝔾</span></code> or <code><span class='Value'>𝕨</span></code>. Calling it with a left argument, or a right argument that isn't a two-element list, will result in an error.</p>
+<h3 id="destructuring">Destructuring</h3>
+<p>Arguments, but not operands, allow destructuring like assignment does. While assignment only tolerates lists of variables, header destructuring also allows constants. The argument must match the given structure, including the constants where they appear, or an error results.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=RGVzdHJ1Y3Qg4oaQIHsg8J2ViiBh4oC/MeKAv+KfqGIsMuKfqTogYeKJjWIgfQpEZXN0cnVjdCAgICAgICA14oC/MeKAv+KfqDcsMuKfqQ==&run">↗️</a><pre> <span class='Function'>Destruct</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Function'>π•Š</span> <span class='Value'>a</span><span class='Ligature'>β€Ώ</span><span class='Number'>1</span><span class='Ligature'>β€Ώ</span><span class='Bracket'>⟨</span><span class='Value'>b</span><span class='Separator'>,</span><span class='Number'>2</span><span class='Bracket'>⟩</span><span class='Value'>:</span> <span class='Value'>a</span><span class='Function'>≍</span><span class='Value'>b</span> <span class='Brace'>}</span>
+ <span class='Function'>Destruct</span> <span class='Number'>5</span><span class='Ligature'>β€Ώ</span><span class='Number'>1</span><span class='Ligature'>β€Ώ</span><span class='Bracket'>⟨</span><span class='Number'>7</span><span class='Separator'>,</span><span class='Number'>2</span><span class='Bracket'>⟩</span>
+⟨ 5 7 ⟩
+</pre>
+<h3 id="special-names-in-headers">Special names in headers</h3>
+<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></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">Short headers</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></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>
+<pre><span class='Brace'>{</span> <span class='Value'>b:</span> <span class='Comment'># Block
+</span><span class='Brace'>{</span> <span class='Function'>π•Š</span><span class='Value'>:</span> <span class='Comment'># Function
+</span><span class='Brace'>{</span> <span class='Modifier'>_𝕣</span><span class='Value'>:</span> <span class='Comment'># 1-Modifier
+</span><span class='Brace'>{</span> <span class='Modifier2'>_𝕣_</span><span class='Value'>:</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, this name can't be used, except for <a href="#returns">returns</a>: it doesn't make sense to refer to a value while it is still being computed!</p>
+<h2 id="multiple-bodies">Multiple bodies</h2>
+<p>Blocks that define functions and deferred modifiers can include more than one body, separated by semicolons <code><span class='Value'>;</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>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=QW1iaXYg4oaQIHsg4p+oMSzwnZWp4p+pIDsg4p+oMizwnZWoLPCdlanin6kgfQpBbWJpdiAnYScKJ2EnIEFtYml2ICdiJw==&run">↗️</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='Value'>;</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>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Q2FzZUFkZCDihpAgeyAy8J2VijM6MOKAvzUgOyAy8J2VivCdlak64p+oMSwyK/Cdlanin6kgOyDwnZWK8J2VqToy4oC/8J2VqSB9CjIgQ2FzZUFkZCAzCjIgQ2FzZUFkZCA0CiAgQ2FzZUFkZCA0&run">↗️</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='Value'>:</span><span class='Number'>0</span><span class='Ligature'>β€Ώ</span><span class='Number'>5</span> <span class='Value'>;</span> <span class='Number'>2</span><span class='Function'>π•Š</span><span class='Value'>𝕩:</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='Value'>;</span> <span class='Function'>π•Š</span><span class='Value'>𝕩:</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 ⟩
+ <span class='Number'>2</span> <span class='Function'>CaseAdd</span> <span class='Number'>4</span>
+⟨ 1 6 ⟩
+ <span class='Function'>CaseAdd</span> <span class='Number'>4</span>
+⟨ 2 4 ⟩
+</pre>
+<p>If no header is compatible, the call results in an error.</p>
+<pre> <span class='Number'>3</span> <span class='Function'>CaseAdd</span> <span class='Number'>3</span>
+<span class='Function'>ERROR</span>
+</pre>
+<h3 id="case-headers">Case headers</h3>
+<p>A special rule allows for convenient case-matching syntax for one-argument functions. In any function header with one argument, the function name can be omitted as long as the argument is <em>not</em> a plain identifierβ€”it must be <code><span class='Value'>𝕩</span></code> or a compound value like a list to distinguish it from an immediate block label.</p>
+<pre><span class='Function'>Test</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
+ <span class='String'>&quot;abc&quot;</span><span class='Value'>:</span> <span class='String'>&quot;string&quot;</span>
+ <span class='Bracket'>⟨</span><span class='Number'>2</span><span class='Separator'>,</span><span class='Value'>b</span><span class='Bracket'>⟩</span><span class='Value'>:</span> <span class='Function'>⌽</span><span class='Value'>𝕩</span>
+ <span class='Number'>5</span><span class='Value'>:</span> <span class='String'>&quot;number&quot;</span>
+ <span class='Value'>𝕩:</span> <span class='String'>&quot;default&quot;</span>
+<span class='Brace'>}</span>
+</pre>
+<p>These case-style headers function exactly the same as if they were preceded by <code><span class='Function'>π•Š</span></code>, and can be mixed with other kinds of headers.</p>
+<h2 id="returns">Returns</h2>
+<p><em>This feature is not yet included in any BQN implementation.</em></p>
+<p>The glyph <code><span class='Gets'>β†’</span></code> indicates an early return from a block. It must be preceded either by one of the self-reference special names <code><span class='Function'>π•Š</span></code> or <code><span class='Value'>𝕣</span></code> or by an internal name for a containing block. The combination of name and return tokenβ€”like <code><span class='Function'>F</span><span class='Gets'>β†’</span></code>, let's sayβ€”is a function that returns from the current instance of the indicated block. If that instance has already returned, then it instead results in an error.</p>
+
diff --git a/docs/doc/index.html b/docs/doc/index.html
index 59d601bb..ca968875 100644
--- a/docs/doc/index.html
+++ b/docs/doc/index.html
@@ -15,6 +15,7 @@
<p>Concepts:</p>
<ul>
<li><a href="based.html">Based array theory</a></li>
+<li><a href="block.html">Blocks</a> (including function and modifier definition)</li>
<li><a href="context.html">Context-free grammar</a></li>
<li><a href="functional.html">Functional programming</a></li>
<li><a href="indices.html">Array indices</a></li>
diff --git a/docs/doc/syntax.html b/docs/doc/syntax.html
index c37f0db1..42fe714a 100644
--- a/docs/doc/syntax.html
+++ b/docs/doc/syntax.html
@@ -42,7 +42,7 @@
</tr>
<tr>
<td><code><span class='Gets'>β†’</span></code></td>
-<td>Return</td>
+<td><a href="block.html#returns">Return</a></td>
</tr>
<tr>
<td><code><span class='Separator'>β‹„,</span></code> or newline</td>
@@ -62,11 +62,11 @@
</tr>
<tr>
<td><code><span class='Value'>:</span></code></td>
-<td>Block header</td>
+<td><a href="block.html#block-headers">Block header</a></td>
</tr>
<tr>
<td><code><span class='Value'>;</span></code></td>
-<td>Block body separator</td>
+<td><a href="block.html#multiple-bodies">Block body separator</a></td>
</tr>
<tr>
<td><code><span class='Value'>𝕨</span><span class='Function'>π•Ž</span></code></td>
@@ -147,6 +147,7 @@
<p>Lists (1-dimensional arrays) are enclosed in angle brackets <code><span class='Bracket'>⟨⟩</span></code>, with the results of the expressions in between being the list's elements. Lists of two elements or more can also be written with the ligature character <code><span class='Ligature'>β€Ώ</span></code>. This character has higher binding strength than any part of an expression. If one of the elements is a compound expression, then it will need to be enclosed in parentheses.</p>
<p>If added, <a href="extensions.html#sets-and-dictionaries">sets and dictionaries</a> would also use a list-like notation.</p>
<h3 id="blocks">Blocks</h3>
+<p><em><a href="block.html">Full documentation</a></em></p>
<p>Blocks are written with curly braces <code><span class='Brace'>{}</span></code> and can be used to group expressions or define functions and modifiers. The contents are simply a sequence of expressions, where each is evaluated and the result of the last is returned in order to evaluate the block. This result can have any value, and its syntactic role in the calling context is determined by the normal rules: functions return subjects and modifiers return functions. Blocks have lexical scope.</p>
<p>The special names <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code>, which stand for arguments, and <code><span class='Value'>𝕗</span></code> and <code><span class='Value'>π•˜</span></code>, which stand for operands, are available inside curly braces. Like ordinary names, the lowercase forms indicate subjects and the uppercase forms <code><span class='Function'>π•Žπ•π”½π”Ύ</span></code> indicate functions. The type and syntactic role of the block is determined by its contents: a 2-modifier contains <code><span class='Value'>π•˜</span></code>, a 1-modifier contains <code><span class='Value'>𝕗</span></code> but not <code><span class='Value'>π•˜</span></code>, and a function contains neither but does have one of <code><span class='Value'>𝕨𝕩𝕀</span><span class='Function'>π•Žπ•π•Š</span></code>. If no special names are present the block is an <em>immediate block</em> and is evaluated as soon as it appears, with the result having a subject role.</p>
<p>A modifier can be evaluated twice: once when passed operands and again when the resulting function is passed arguments. If it contains <code><span class='Value'>𝕨</span></code> or <code><span class='Value'>𝕩</span></code>, the first evaluation simply remembers the operands, and the contents will be executed only on the second evaluation, when the arguments are available. If it doesn't contain these, then the contents are executed on the first evaluation and the result is treated as a function.</p>
diff --git a/docs/index.html b/docs/index.html
index 11cee23a..dcd1075e 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -25,7 +25,7 @@
<ul>
<li>The <a href="doc/leading.html"><strong>leading axis model</strong></a>, which allows for simpler built-in functions.</li>
<li>Trains and combinators for <strong>tacit programming</strong>.</li>
-<li>Lightweight <strong>anonymous functions</strong> (like <a href="https://aplwiki.com/wiki/Dfn">dfns</a>).</li>
+<li>Lightweight <a href="doc/block.html"><strong>anonymous functions</strong></a> (like <a href="https://aplwiki.com/wiki/Dfn">dfns</a>).</li>
</ul>
<p>But BQN is redesigned from the ground up, with brand new ideas to make these paradigms easier to use and less likely to fail.</p>
<ul>