From 30b5188c23576d5e119bbc8d27cd08a3015a75c9 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Wed, 3 Nov 2021 15:41:10 -0400 Subject: Enlist/Pair documentation --- doc/fill.md | 2 +- doc/pair.md | 53 ++++++++++++++++++++++++++++++++++++++++ doc/primitive.md | 1 + docs/doc/fill.html | 4 +-- docs/doc/pair.html | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ docs/doc/primitive.html | 5 ++++ 6 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 doc/pair.md create mode 100644 docs/doc/pair.html diff --git a/doc/fill.md b/doc/fill.md index 6b4bd53c..8c7c626c 100644 --- a/doc/fill.md +++ b/doc/fill.md @@ -54,7 +54,7 @@ Most other primitives fit in one of three broad categories as shown in the table | `∩` | `>∾` | `∾≍»«` | `0` | `≢/⍋⍒∊⊐⊒` | `⍋⍒⊐⊒∊⍷` -Besides these, there are a few primitives with special fills. [Enclose](enclose.md) (`<`) uses a fill derived directly from `𝕩`, with all numbers replaced by `0` and characters by `' '` (if it contains non-data atoms, the fill doesn't exist). [Range](range.md) (`↕`) does the same, although the reason is less obvious: the result elements don't match `𝕩`, but they have the same structure. +Besides these, there are a few primitives with special fills. [Enclose](enclose.md) (`<`) uses a fill derived directly from `𝕩`, with all numbers replaced by `0` and characters by `' '` (if it contains non-data atoms, the fill doesn't exist). [Enlist](pair.md) works the same way, while [Pair](pair.md) sets the fill this way based on both `𝕨` and `𝕩`, if they agree. [Range](range.md) (`↕`) does the same, although the reason is less obvious: the result elements don't match `𝕩`, but they have the same structure. [Prefixes and Suffixes](prefixes.md) (`↑↓`) use `0↑𝕩` for the fill, as do [Group](group.md) and Group Indices (`⊔`) in the single-axis case. Fills for multi-axis `⊔` are more complicated, but follow the rule that variable-length axes are changed to length 0. The *elements* of the result of `⊔` also have a fill specified: the same as `𝕩` for Group, or `0` for Group Indices. diff --git a/doc/pair.md b/doc/pair.md new file mode 100644 index 00000000..c36e3abd --- /dev/null +++ b/doc/pair.md @@ -0,0 +1,53 @@ +*View this file with results and syntax highlighting [here](https://mlochbaum.github.io/BQN/doc/pair.html).* + +# Pair + +The function `⋈` forms a list of all its arguments. When there's one argument, it's called "Enlist", and with two, it's called "Pair". + + ⋈ "enlist" # ⟨𝕩⟩ + + "pa" ⋈ "ir" # ⟨𝕨,𝕩⟩ + +It's usually preferable to use [list notation](arrayrepr.md#brackets) directly for such arrays, because it's easy to add or remove any number of elements. Pair is useful when a standalone function is needed, for example to be used as an operand. + + 2‿4‿1 ⋈⌜ "north"‿"south" # Cartesian product + + ⋈¨ "+-×÷" # Glyphs to strings + +Another common pattern is to use Pair in a [train](train.md), giving the results from applying each of two functions. + + 'c' (+⋈-) 1‿2 + +For longer lists, this pattern can be extended with the function `<⊸∾`, which prepends a single element to a list. + + "e0" <⊸∾ "e1" <⊸∾ "e2" ⋈ "e3" + +However, before making a long list of this sort, consider that your goal might be more easily accomplished with a list of functions. + + 6 (+ <⊸∾ - <⊸∾ × ⋈ ÷) 3 + + {6𝕏3}¨ +‿-‿×‿÷ + +## Pair versus Couple + +Enlist and Pair closely related to [Solo and Couple](couple.md), in that `⋈` is equivalent to `≍○<` and `≍` is equivalent to `>∘⋈`. However, the result of `⋈` is always a list (rank 1) while Solo or Couple return an array of rank at least 1. + + "abc" ≍ "def" + + "abc" ⋈ "def" + +And the arguments to Couple must have the same shape, while Enlist takes any two arguments. + + "abc" ≍ "defg" + + "abc" ⋈ "defg" + +The difference is that Couple treats the arguments as cells, and adds a dimension, while Pair treats them as elements, adding a layer of depth. Couple is a "flat" version of Pair, much like Cells (`˘`) is a flat version of Each (`¨`). Pair is more versatile, but—precisely because of its restrictions—Couple may allow more powerful array operations on the result. + +## Fill element + +Enlist and Pair set the result's [fill](fill.md) element, while list notation doesn't have to. So the following result is guaranteed: + + 4 ↑ "a"‿5 ⋈ "b"‿7 + +This means that `⋈` may always behave the same as the obvious implementation `{⟨𝕩⟩;⟨𝕨,𝕩⟩}`. However, `≍○<` and even `>∘{⟨𝕩⟩;⟨𝕨,𝕩⟩}○<` compute the result fill as `⋈` does and are identical implementations. diff --git a/doc/primitive.md b/doc/primitive.md index 4cb8f13c..2d5a3b6b 100644 --- a/doc/primitive.md +++ b/doc/primitive.md @@ -39,6 +39,7 @@ Functions that have significant differences from APL equivalents or don't appear | `⥊` | [Deshape](reshape.md) | [Reshape](reshape.md)* | `∾` | [Join](join.md)* | [Join to](join.md) | `≍` | [Solo](couple.md)* | [Couple](couple.md)* +| `⋈` | [Enlist](pair.md)* | [Pair](pair.md)* | `↑` | [Prefixes](prefixes.md)* | [Take](take.md) | `↓` | [Suffixes](prefixes.md)* | [Drop](take.md) | `↕` | [Range](range.md) | [Windows](windows.md)* diff --git a/docs/doc/fill.html b/docs/doc/fill.html index e350fa6e..ef6e1422 100644 --- a/docs/doc/fill.html +++ b/docs/doc/fill.html @@ -21,7 +21,7 @@ ⟨ ⟨ 0 3 3 3 ⟩ " qrs" ⟩ 3⟨⟩ # Fill unknown -ERROR +⟨ 0 0 0 ⟩ »⟨⟩ # Fill not needed ⟨⟩ @@ -77,7 +77,7 @@ -

Besides these, there are a few primitives with special fills. Enclose (<) uses a fill derived directly from 𝕩, with all numbers replaced by 0 and characters by ' ' (if it contains non-data atoms, the fill doesn't exist). Range () does the same, although the reason is less obvious: the result elements don't match 𝕩, but they have the same structure.

+

Besides these, there are a few primitives with special fills. Enclose (<) uses a fill derived directly from 𝕩, with all numbers replaced by 0 and characters by ' ' (if it contains non-data atoms, the fill doesn't exist). Enlist works the same way, while Pair sets the fill this way based on both 𝕨 and 𝕩, if they agree. Range () does the same, although the reason is less obvious: the result elements don't match 𝕩, but they have the same structure.

Prefixes and Suffixes (↑↓) use 0𝕩 for the fill, as do Group and Group Indices () in the single-axis case. Fills for multi-axis are more complicated, but follow the rule that variable-length axes are changed to length 0. The elements of the result of also have a fill specified: the same as 𝕩 for Group, or 0 for Group Indices.

↗️
    6  ↑↕3  # Two fills at the end
 ⟨ ⟨⟩ ⟨ 0 ⟩ ⟨ 0 1 ⟩ ⟨ 0 1 2 ⟩ ⟨⟩ ⟨⟩ ⟩
diff --git a/docs/doc/pair.html b/docs/doc/pair.html
new file mode 100644
index 00000000..46f4c82d
--- /dev/null
+++ b/docs/doc/pair.html
@@ -0,0 +1,65 @@
+
+  
+  
+  BQN: Pair
+
+
+

Pair

+

The function forms a list of all its arguments. When there's one argument, it's called "Enlist", and with two, it's called "Pair".

+↗️
     "enlist"    # ⟨𝕩⟩
+⟨ "enlist" ⟩
+
+    "pa"  "ir"   # ⟨𝕨,𝕩⟩
+⟨ "pa" "ir" ⟩
+
+

It's usually preferable to use list notation directly for such arrays, because it's easy to add or remove any number of elements. Pair is useful when a standalone function is needed, for example to be used as an operand.

+↗️
    241  "north""south"  # Cartesian product
+┌─                             
+╵ ⟨ 2 "north" ⟩ ⟨ 2 "south" ⟩  
+  ⟨ 4 "north" ⟩ ⟨ 4 "south" ⟩  
+  ⟨ 1 "north" ⟩ ⟨ 1 "south" ⟩  
+                              ┘
+
+    ¨ "+-×÷"  # Glyphs to strings
+⟨ "+" "-" "×" "÷" ⟩
+
+

Another common pattern is to use Pair in a train, giving the results from applying each of two functions.

+↗️
    'c' (+⋈-)  12
+⟨ "de" "ba" ⟩
+
+

For longer lists, this pattern can be extended with the function <, which prepends a single element to a list.

+↗️
    "e0" < "e1" < "e2"  "e3"
+⟨ "e0" "e1" "e2" "e3" ⟩
+
+

However, before making a long list of this sort, consider that your goal might be more easily accomplished with a list of functions.

+↗️
    6 (+ < - < ×  ÷) 3
+⟨ 9 3 18 2 ⟩
+
+    {6𝕏3}¨ +-×÷
+⟨ 9 3 18 2 ⟩
+
+

Pair versus Couple

+

Enlist and Pair closely related to Solo and Couple, in that is equivalent to < and is equivalent to >. However, the result of is always a list (rank 1) while Solo or Couple return an array of rank at least 1.

+↗️
    "abc"  "def"
+┌─     
+╵"abc  
+  def" 
+      ┘
+
+    "abc"  "def"
+⟨ "abc" "def" ⟩
+
+

And the arguments to Couple must have the same shape, while Enlist takes any two arguments.

+↗️
    "abc"  "defg"
+ERROR
+
+    "abc"  "defg"
+⟨ "abc" "defg" ⟩
+
+

The difference is that Couple treats the arguments as cells, and adds a dimension, while Pair treats them as elements, adding a layer of depth. Couple is a "flat" version of Pair, much like Cells (˘) is a flat version of Each (¨). Pair is more versatile, but—precisely because of its restrictions—Couple may allow more powerful array operations on the result.

+

Fill element

+

Enlist and Pair set the result's fill element, while list notation doesn't have to. So the following result is guaranteed:

+↗️
    4  "a"5  "b"7
+⟨ ⟨ "a" 5 ⟩ ⟨ "b" 7 ⟩ ⟨ " " 0 ⟩ ⟨ " " 0 ⟩ ⟩
+
+

This means that may always behave the same as the obvious implementation {𝕩;𝕨,𝕩}. However, < and even >{𝕩;𝕨,𝕩}< compute the result fill as does and are identical implementations.

diff --git a/docs/doc/primitive.html b/docs/doc/primitive.html index ebb09c09..05cb3dbc 100644 --- a/docs/doc/primitive.html +++ b/docs/doc/primitive.html @@ -145,6 +145,11 @@ Couple* + +Enlist* +Pair* + + Prefixes* Take -- cgit v1.2.3