aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2022-04-26 21:25:24 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2022-04-26 21:25:24 -0400
commita2d8557e3e8f58d9adfc028e66caf190d0911aca (patch)
tree117701bf6645b33c5ebf260da03dfb760f34e038
parentb08a79d7f0108b2e587bb348f13635329549eaf0 (diff)
Section on composing multiple hook modifiers
-rw-r--r--doc/hook.md30
-rw-r--r--docs/doc/hook.html29
2 files changed, 59 insertions, 0 deletions
diff --git a/doc/hook.md b/doc/hook.md
index 0eb5d5ce..368d3854 100644
--- a/doc/hook.md
+++ b/doc/hook.md
@@ -59,3 +59,33 @@ As in a train, if you want to use a function as a constant then you need to be e
3 ⋈⟜(⌊˙)⊸⥊ 'a'+↕12
In the more extreme case of wanting a *modifier* operand, you might try `⋈⟜({∘}˙)⊸⥊`, or `(⊣⋈{∘}˙)⊸⥊`, or just cheat with `∾⟜⟨∘⟩⊸⥊`.
+
+## Combinations
+
+If you like to go [tacit](tacit.md), you'll likely end up stringing together a few `⊸`s and `⟜`s at times. Of course the effects are entirely determined by the left-to-right precedence rule for modifiers, but it's interesting to examine what happens in more detail.
+
+In the pattern `F⊸G⟜H`, the ordering doesn't matter at all! That is, it means `(F⊸G)⟜H`, but this is exactly the same function as `F⊸(G⟜H)`. In both cases, `F` is applied to `𝕨`, `H` is applied to `𝕩`, and `G` acts on both the results.
+
+ 4 -⊸⋈⟜⋆ 2
+
+I once named this pattern "split compose", but now I think it makes more sense to think of it as two pre-functions added separately to one central function (`⋈` above). The whole is exactly the sum of its parts. When applied to just one argument, `𝕩` is reused on both sides, making the composition equivalent to a 3-[train](train.md).
+
+ -⊸⋈⟜⋆ 2
+
+ (-⋈⋆) 2 # Same thing
+
+More `⟜`s can be added on the right, making `𝕩` flow through all the added functions. So for example `F⟜G⟜H x` is `x F G H x`, and could also be written `F⟜(G H) x`.
+
+A sequence of `⊸`s is more interesting. It doesn't just compose the functions (for that you need `G∘F⊸H`, but note the weird ordering—`F` applies before `G`!), but instead passes the current value *and* the initial function each time. Consider `F⊸G⊸H⊸I`, or `((F⊸G)⊸H)⊸I`: every function but `F` is on the ring side, meaning it's dyadic!
+
+Here's a long example, that might show up if you want to [sort](order.md#sort) an array but have an intolerance for the character `∧`. In quicksort, you select a partition element from the array, then divide it into elements less than, and greater than or equal to, the pivot. You'd probably pick a [random](../spec/system.md#random-generation) element for the pivot, but here I'll go with the middle element to avoid having a webpage that generates differently every time!
+
+ (⌊≠÷2˙) "quicksort" # Index of the pivot
+
+ (⌊≠÷2˙)⊸⊑ "quicksort" # Select pivot from 𝕩
+
+ (⌊≠÷2˙)⊸⊑⊸≤ "quicksort" # Compare with 𝕩
+
+ (⌊≠÷2˙)⊸⊑⊸≤⊸⊔ "quicksort" # Use to partition 𝕩
+
+Three is rare, but I use two `⊸`s all the time, as well as `⟜` followed by `⊸`, for example the `<⟜'a'⊸/` filter on the [front page](../README.md). I think a combination like `lots∘of○stuff⊸/ x` reads very nicely when moving from left to right. When I see `⊸/` I know that I'm filtering `x` and can read the rest with that context. The reason `⊸` that has all this power, but not `⟜`, has nothing to do with the modifiers themselves, as they're completely symmetrical. It's all in the way BQN defines modifier grammar, left to right.
diff --git a/docs/doc/hook.html b/docs/doc/hook.html
index 22054800..e300796a 100644
--- a/docs/doc/hook.html
+++ b/docs/doc/hook.html
@@ -159,3 +159,32 @@
</pre>
<p>In the more extreme case of wanting a <em>modifier</em> operand, you might try <code><span class='Function'>⋈</span><span class='Modifier2'>⟜</span><span class='Paren'>(</span><span class='Brace'>{</span><span class='Modifier2'>∘</span><span class='Brace'>}</span><span class='Modifier'>˙</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>⥊</span></code>, or <code><span class='Paren'>(</span><span class='Function'>⊣⋈</span><span class='Brace'>{</span><span class='Modifier2'>∘</span><span class='Brace'>}</span><span class='Modifier'>˙</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>⥊</span></code>, or just cheat with <code><span class='Function'>∾</span><span class='Modifier2'>⟜</span><span class='Bracket'>⟨</span><span class='Modifier2'>∘</span><span class='Bracket'>⟩</span><span class='Modifier2'>⊸</span><span class='Function'>⥊</span></code>.</p>
+<h2 id="combinations"><a class="header" href="#combinations">Combinations</a></h2>
+<p>If you like to go <a href="tacit.html">tacit</a>, you'll likely end up stringing together a few <code><span class='Modifier2'>⊸</span></code>s and <code><span class='Modifier2'>⟜</span></code>s at times. Of course the effects are entirely determined by the left-to-right precedence rule for modifiers, but it's interesting to examine what happens in more detail.</p>
+<p>In the pattern <code><span class='Function'>F</span><span class='Modifier2'>⊸</span><span class='Function'>G</span><span class='Modifier2'>⟜</span><span class='Function'>H</span></code>, the ordering doesn't matter at all! That is, it means <code><span class='Paren'>(</span><span class='Function'>F</span><span class='Modifier2'>⊸</span><span class='Function'>G</span><span class='Paren'>)</span><span class='Modifier2'>⟜</span><span class='Function'>H</span></code>, but this is exactly the same function as <code><span class='Function'>F</span><span class='Modifier2'>⊸</span><span class='Paren'>(</span><span class='Function'>G</span><span class='Modifier2'>⟜</span><span class='Function'>H</span><span class='Paren'>)</span></code>. In both cases, <code><span class='Function'>F</span></code> is applied to <code><span class='Value'>𝕨</span></code>, <code><span class='Function'>H</span></code> is applied to <code><span class='Value'>𝕩</span></code>, and <code><span class='Function'>G</span></code> acts on both the results.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=NCAt4oq44ouI4p+c4ouGIDI=">↗️</a><pre> <span class='Number'>4</span> <span class='Function'>-</span><span class='Modifier2'>⊸</span><span class='Function'>⋈</span><span class='Modifier2'>⟜</span><span class='Function'>⋆</span> <span class='Number'>2</span>
+⟨ ¯4 7.38905609893065 ⟩
+</pre>
+<p>I once named this pattern &quot;split compose&quot;, but now I think it makes more sense to think of it as two pre-functions added separately to one central function (<code><span class='Function'>⋈</span></code> above). The whole is exactly the sum of its parts. When applied to just one argument, <code><span class='Value'>𝕩</span></code> is reused on both sides, making the composition equivalent to a 3-<a href="train.html">train</a>.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=LeKKuOKLiOKfnOKLhiAyCgooLeKLiOKLhikgMiAgIyBTYW1lIHRoaW5n">↗️</a><pre> <span class='Function'>-</span><span class='Modifier2'>⊸</span><span class='Function'>⋈</span><span class='Modifier2'>⟜</span><span class='Function'>⋆</span> <span class='Number'>2</span>
+⟨ ¯2 7.38905609893065 ⟩
+
+ <span class='Paren'>(</span><span class='Function'>-⋈⋆</span><span class='Paren'>)</span> <span class='Number'>2</span> <span class='Comment'># Same thing
+</span>⟨ ¯2 7.38905609893065 ⟩
+</pre>
+<p>More <code><span class='Modifier2'>⟜</span></code>s can be added on the right, making <code><span class='Value'>𝕩</span></code> flow through all the added functions. So for example <code><span class='Function'>F</span><span class='Modifier2'>⟜</span><span class='Function'>G</span><span class='Modifier2'>⟜</span><span class='Function'>H</span> <span class='Value'>x</span></code> is <code><span class='Value'>x</span> <span class='Function'>F</span> <span class='Function'>G</span> <span class='Function'>H</span> <span class='Value'>x</span></code>, and could also be written <code><span class='Function'>F</span><span class='Modifier2'>⟜</span><span class='Paren'>(</span><span class='Function'>G</span> <span class='Function'>H</span><span class='Paren'>)</span> <span class='Value'>x</span></code>.</p>
+<p>A sequence of <code><span class='Modifier2'>⊸</span></code>s is more interesting. It doesn't just compose the functions (for that you need <code><span class='Function'>G</span><span class='Modifier2'>∘</span><span class='Function'>F</span><span class='Modifier2'>⊸</span><span class='Function'>H</span></code>, but note the weird ordering—<code><span class='Function'>F</span></code> applies before <code><span class='Function'>G</span></code>!), but instead passes the current value <em>and</em> the initial function each time. Consider <code><span class='Function'>F</span><span class='Modifier2'>⊸</span><span class='Function'>G</span><span class='Modifier2'>⊸</span><span class='Function'>H</span><span class='Modifier2'>⊸</span><span class='Function'>I</span></code>, or <code><span class='Paren'>((</span><span class='Function'>F</span><span class='Modifier2'>⊸</span><span class='Function'>G</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>H</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>I</span></code>: every function but <code><span class='Function'>F</span></code> is on the ring side, meaning it's dyadic!</p>
+<p>Here's a long example, that might show up if you want to <a href="order.html#sort">sort</a> an array but have an intolerance for the character <code><span class='Function'>∧</span></code>. In quicksort, you select a partition element from the array, then divide it into elements less than, and greater than or equal to, the pivot. You'd probably pick a <a href="../spec/system.html#random-generation">random</a> element for the pivot, but here I'll go with the middle element to avoid having a webpage that generates differently every time!</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKMiuKJoMO3MsuZKSAgICAgICAicXVpY2tzb3J0IiAgIyBJbmRleCBvZiB0aGUgcGl2b3QKCijijIriiaDDtzLLmSniirjiipEgICAgICJxdWlja3NvcnQiICAjIFNlbGVjdCBwaXZvdCBmcm9tIPCdlakKCijijIriiaDDtzLLmSniirjiipHiirjiiaQgICAicXVpY2tzb3J0IiAgIyBDb21wYXJlIHdpdGgg8J2VqQoKKOKMiuKJoMO3MsuZKeKKuOKKkeKKuOKJpOKKuOKKlCAicXVpY2tzb3J0IiAgIyBVc2UgdG8gcGFydGl0aW9uIPCdlak=">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>⌊≠÷</span><span class='Number'>2</span><span class='Modifier'>˙</span><span class='Paren'>)</span> <span class='String'>&quot;quicksort&quot;</span> <span class='Comment'># Index of the pivot
+</span>4
+
+ <span class='Paren'>(</span><span class='Function'>⌊≠÷</span><span class='Number'>2</span><span class='Modifier'>˙</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>⊑</span> <span class='String'>&quot;quicksort&quot;</span> <span class='Comment'># Select pivot from 𝕩
+</span>'k'
+
+ <span class='Paren'>(</span><span class='Function'>⌊≠÷</span><span class='Number'>2</span><span class='Modifier'>˙</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>⊑</span><span class='Modifier2'>⊸</span><span class='Function'>≤</span> <span class='String'>&quot;quicksort&quot;</span> <span class='Comment'># Compare with 𝕩
+</span>⟨ 1 1 0 0 1 1 1 1 1 ⟩
+
+ <span class='Paren'>(</span><span class='Function'>⌊≠÷</span><span class='Number'>2</span><span class='Modifier'>˙</span><span class='Paren'>)</span><span class='Modifier2'>⊸</span><span class='Function'>⊑</span><span class='Modifier2'>⊸</span><span class='Function'>≤</span><span class='Modifier2'>⊸</span><span class='Function'>⊔</span> <span class='String'>&quot;quicksort&quot;</span> <span class='Comment'># Use to partition 𝕩
+</span>⟨ "ic" "quksort" ⟩
+</pre>
+<p>Three is rare, but I use two <code><span class='Modifier2'>⊸</span></code>s all the time, as well as <code><span class='Modifier2'>⟜</span></code> followed by <code><span class='Modifier2'>⊸</span></code>, for example the <code><span class='Function'>&lt;</span><span class='Modifier2'>⟜</span><span class='String'>'a'</span><span class='Modifier2'>⊸</span><span class='Function'>/</span></code> filter on the <a href="../index.html">front page</a>. I think a combination like <code><span class='Value'>lots</span><span class='Modifier2'>∘</span><span class='Value'>of</span><span class='Modifier2'>○</span><span class='Value'>stuff</span><span class='Modifier2'>⊸</span><span class='Function'>/</span> <span class='Value'>x</span></code> reads very nicely when moving from left to right. When I see <code><span class='Modifier2'>⊸</span><span class='Function'>/</span></code> I know that I'm filtering <code><span class='Value'>x</span></code> and can read the rest with that context. The reason <code><span class='Modifier2'>⊸</span></code> that has all this power, but not <code><span class='Modifier2'>⟜</span></code>, has nothing to do with the modifiers themselves, as they're completely symmetrical. It's all in the way BQN defines modifier grammar, left to right.</p>