diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-04-13 22:28:55 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-04-13 22:28:55 -0400 |
| commit | 7273e5bec783772f6d61e056b5c138c70fd58663 (patch) | |
| tree | 050d63a412d86d7b0f7a12509d601d09262dbc50 /doc | |
| parent | d291cb7faf2c1856e2cea486b0d935bbb16db2c9 (diff) | |
Documentation for Constant
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/README.md | 1 | ||||
| -rw-r--r-- | doc/constant.md | 28 | ||||
| -rw-r--r-- | doc/primitive.md | 22 |
3 files changed, 40 insertions, 11 deletions
diff --git a/doc/README.md b/doc/README.md index 0560a3a6..26374f5c 100644 --- a/doc/README.md +++ b/doc/README.md @@ -42,6 +42,7 @@ Primitives: - [Array dimensions](shape.md) (`≢=≠`) - [Assert and Catch](assert.md) (`!` and `⎊`) - [Atop and Over](compose.md) (`∘○`) +- [Constant](constant.md) (`˙`) - [Deshape and Reshape](reshape.md) (`⥊`) - [Enclose](enclose.md) (`<`) - [Find](find.md) (`⍷`) diff --git a/doc/constant.md b/doc/constant.md new file mode 100644 index 00000000..73413a03 --- /dev/null +++ b/doc/constant.md @@ -0,0 +1,28 @@ +*View this file with results and syntax highlighting [here](https://mlochbaum.github.io/BQN/doc/constant.html).* + +# Constant + +<!--GEN combinator.bqn +DrawComp ≍"˙" +--> + +It's one of the simple ones: `f˙𝕩` is `f`. And `𝕨f˙𝕩`? It's `f`. Like the [identity functions](identity.md), Constant doesn't compute anything but just returns one of its inputs. It's somewhat different in that it's a deferred modifier, so you have to first apply Constant to its operand and *then* to some arguments for that non-event to happen. + +The design of BQN makes Constant unnecessary in most cases, because when a non-operation (number, character, array, namespace) is applied it already returns itself: `π˙` is the same function as `π`. If you've used much [tacit](tacit.md) programming, you've probably written a few [trains](train.md) like `2×+` (twice the sum), which is nicer than the equivalent `2˙×+`. However, a train has to end with a function, so you can't just put a number at the end. Applying `˙` is a convenient way to change the number from a subject to a function role. + + +÷2 # A number + + +÷2˙ # A function + + 3 (+÷2˙) 7 + +When programming with [first-class functions](functional.md), the constant application shortcut becomes a hazard! Consider the program `{𝕨⌾(2⊸⊑) 𝕩}` to insert `𝕨` into an array `𝕩` as an element. It works fine with a number, but with a function it's broken: + + ∞ {𝕨⌾(2⊸⊑) 𝕩} 1‿2‿3‿4 + + M ← - + m {𝕨⌾(2⊸⊑) 𝕩} 1‿2‿3‿4 + +Here `m` is applied to `2⊑𝕩` even though we want to discard that value. Spelled as `m`, our [context-free grammar](context.md) knows it's a function argument, but this [doesn't affect](../problems.md#syntactic-type-erasure) later usage. Under always applies `𝔽` as a function. The proper definition of the insertion function should use a `˙`, like this: + + m {𝕨˙⌾(2⊸⊑) 𝕩} 1‿2‿3‿4 diff --git a/doc/primitive.md b/doc/primitive.md index f2b47341..c358d80a 100644 --- a/doc/primitive.md +++ b/doc/primitive.md @@ -65,17 +65,17 @@ Functions that have significant differences from APL equivalents or don't appear *Combinators* only control the application of functions. Because a non-function operand applies as a constant function, some combinators have extra meanings when passed a constant. For example, `0˜` is identical to `0˙`—a constant function that always returns 0—and `0⊸<` is the function that tests whether its right argument is greater than 0. -Glyph | Name(s) | Definition | Description -------|--------------------|--------------------------------|--------------------------------------- -`˙` | Constant | `{𝕩⋄𝕗}` | Return a function that returns the operand -`˜` | [Self/Swap](swap.md) | `{𝕩𝔽𝕨⊣𝕩}` | Duplicate one argument or exchange two -`∘` | [Atop](compose.md) | `{𝔽𝕨𝔾𝕩}` | Apply `𝔾` to both arguments and `𝔽` to the result -`○` | [Over](compose.md) | `{(𝔾𝕨)𝔽𝔾𝕩}` | Apply `𝔾` to each argument and `𝔽` to the results -`⊸` | Before/Bind | `{(𝔽𝕨⊣𝕩)𝔾𝕩}` | `𝔾`'s left argument comes from `𝔽` -`⟜` | After/Bind | `{(𝕨⊣𝕩)𝔽𝔾𝕩}` | `𝔽`'s right argument comes from `𝔾` -`⌾` | Under | `{𝔾⁼∘𝔽○𝔾}` OR `{(𝔾𝕩)↩𝕨𝔽○𝔾𝕩⋄𝕩}` | Apply `𝔽` over `𝔾`, then undo `𝔾` -`⊘` | Valences | `{𝔽𝕩;𝕨𝔾𝕩}` | Apply `𝔽` if there's one argument but `𝔾` if there are two -`◶` | Choose | `{f←(𝕨𝔽𝕩)⊑𝕘 ⋄ 𝕨F𝕩}` | Select one of the functions in list `𝕘` based on `𝔽` +Glyph | Name(s) | Definition | Description +------|-------------------------|--------------------------------|--------------------------------------- +`˙` | [Constant](constant.md) | `{𝕩⋄𝕗}` | Return a function that returns the operand +`˜` | [Self/Swap](swap.md) | `{𝕩𝔽𝕨⊣𝕩}` | Duplicate one argument or exchange two +`∘` | [Atop](compose.md) | `{𝔽𝕨𝔾𝕩}` | Apply `𝔾` to both arguments and `𝔽` to the result +`○` | [Over](compose.md) | `{(𝔾𝕨)𝔽𝔾𝕩}` | Apply `𝔾` to each argument and `𝔽` to the results +`⊸` | Before/Bind | `{(𝔽𝕨⊣𝕩)𝔾𝕩}` | `𝔾`'s left argument comes from `𝔽` +`⟜` | After/Bind | `{(𝕨⊣𝕩)𝔽𝔾𝕩}` | `𝔽`'s right argument comes from `𝔾` +`⌾` | Under | `{𝔾⁼∘𝔽○𝔾}` OR `{(𝔾𝕩)↩𝕨𝔽○𝔾𝕩⋄𝕩}` | Apply `𝔽` over `𝔾`, then undo `𝔾` +`⊘` | Valences | `{𝔽𝕩;𝕨𝔾𝕩}` | Apply `𝔽` if there's one argument but `𝔾` if there are two +`◶` | Choose | `{f←(𝕨𝔽𝕩)⊑𝕘 ⋄ 𝕨F𝕩}` | Select one of the functions in list `𝕘` based on `𝔽` Choose isn't really a combinator since it calls the function `⊑`, and Under is not a true combinator since it has an "undo" step at the end. This step might be implemented using the left operand's inverse (*computational* Under) or its structural properties (*structural* Under). |
