aboutsummaryrefslogtreecommitdiff
path: root/docs/doc
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2022-07-17 21:41:03 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2022-07-17 21:41:03 -0400
commit9095821c40b1e233065f5ec5eead50543bdbbfdf (patch)
tree3bfd14fa2770cbfb7ea3213621efd1561b796c18 /docs/doc
parent9e7de4f0dfe3bedded4a0e992082481194a20ce4 (diff)
Add a larger example to tacit.md
Diffstat (limited to 'docs/doc')
-rw-r--r--docs/doc/tacit.html54
1 files changed, 54 insertions, 0 deletions
diff --git a/docs/doc/tacit.html b/docs/doc/tacit.html
index 52a9eed3..ef2483c6 100644
--- a/docs/doc/tacit.html
+++ b/docs/doc/tacit.html
@@ -229,3 +229,57 @@
</span>3.5
</pre>
<p>For more complicated &quot;if-else&quot; or &quot;select&quot; type conditionals, use <a href="choose.html">Choose</a> (<code><span class='Modifier2'>◶</span></code>). Watch for ordering here: <code><span class='Function'>F</span><span class='Modifier2'>◶</span><span class='Bracket'>⟨</span><span class='Function'>G0</span><span class='Separator'>,</span><span class='Function'>G1</span><span class='Bracket'>⟩</span></code> puts the two parts in the opposite order to Repeat, and list element 1 comes after element 0 even though it might seem more intuitive for the &quot;true&quot; value to come first.</p>
+<h2 id="example-combinations"><a class="header" href="#example-combinations">Example: combinations</a></h2>
+<p>As an example, we'll look at the following <a href="https://en.wikipedia.org/wiki/Binomial_coefficient">combinations function</a> implementation from bqncrate (substituting the conventional <code><span class='Value'>k</span></code> and <code><span class='Value'>n</span></code> in for <code><span class='Value'>i0</span></code> and <code><span class='Value'>j0</span></code>):</p>
+<pre><span class='Value'>k</span><span class='Paren'>(</span><span class='Function'>-÷</span><span class='Modifier2'>○</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Paren'>)</span><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Paren'>)</span><span class='Modifier2'>⟜</span><span class='Function'>↕</span><span class='Modifier'>˜</span><span class='Value'>n</span> <span class='Comment'># Number of unordered selections (combinations) of k items from n choices
+</span></pre>
+<p>This function takes the typical approach of multiplying numbers that start at <code><span class='Value'>n</span></code> and go down, and dividing by numbers starting at <code><span class='Number'>1</span></code> and going up. It's easier to understand from the BQN code, really:</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=buKGkDUg4ouEIGvihpAzCgrin6huLeKGlWssIDEr4oaVa+KfqQoKKMOXwrRuLeKGlWspIMO3ICjDl8K0MSvihpVrKQ==">↗️</a><pre> <span class='Value'>n</span><span class='Gets'>←</span><span class='Number'>5</span> <span class='Separator'>⋄</span> <span class='Value'>k</span><span class='Gets'>←</span><span class='Number'>3</span>
+
+ <span class='Bracket'>⟨</span><span class='Value'>n</span><span class='Function'>-↕</span><span class='Value'>k</span><span class='Separator'>,</span> <span class='Number'>1</span><span class='Function'>+↕</span><span class='Value'>k</span><span class='Bracket'>⟩</span>
+⟨ ⟨ 5 4 3 ⟩ ⟨ 1 2 3 ⟩ ⟩
+
+ <span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Value'>n</span><span class='Function'>-↕</span><span class='Value'>k</span><span class='Paren'>)</span> <span class='Function'>÷</span> <span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Number'>1</span><span class='Function'>+↕</span><span class='Value'>k</span><span class='Paren'>)</span>
+10
+</pre>
+<p>(The <code><span class='Number'>3</span></code> can be eliminated by replacing <code><span class='Value'>k</span></code> with <code><span class='Value'>k</span><span class='Function'>⌊</span><span class='Value'>n</span><span class='Function'>-</span><span class='Value'>k</span></code>. Figuring out how to do that can be a tacit exercise for later?)</p>
+<p>This says there are 10 ways to choose 3 out of 5 different options. Of course it's easy enough to make it into a function of <code><span class='Value'>k</span></code> and <code><span class='Value'>n</span></code>:</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=buKGkDUg4ouEIGvihpAzCmsgeyjDl8K08J2VqS3ihpXwnZWoKcO3w5fCtDEr4oaV8J2VqH0gbg==">↗️</a><pre> <span class='Value'>k</span> <span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Value'>𝕩</span><span class='Function'>-↕</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>÷×</span><span class='Modifier'>´</span><span class='Number'>1</span><span class='Function'>+↕</span><span class='Value'>𝕨</span><span class='Brace'>}</span> <span class='Value'>n</span>
+10
+</pre>
+<p>But we are on the tacit page, so we'd like to make it tacit. For better or for worse. There's a mechanical way to do this for many functions, using only identity functions and trains, and making no simplifications. First parenthesize all monadic functions, as these will become 2-trains. Then replace <code><span class='Value'>𝕨</span></code> and <code><span class='Value'>𝕩</span></code> with <code><span class='Function'>⊣</span></code> and <code><span class='Function'>⊢</span></code>, and add a <code><span class='Modifier'>˙</span></code> to constants. For the number <code><span class='Number'>1</span></code> the added <code><span class='Modifier'>˙</span></code> isn't necessary unless it comes at the end of a train, but we include it here to show the principle.</p>
+<pre><span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Value'>𝕩</span><span class='Function'>-↕</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>÷×</span><span class='Modifier'>´</span><span class='Number'>1</span><span class='Function'>+↕</span><span class='Value'>𝕨</span><span class='Brace'>}</span>
+
+<span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Value'>𝕩</span><span class='Function'>-</span><span class='Paren'>(</span><span class='Function'>↕</span><span class='Value'>𝕨</span><span class='Paren'>))</span><span class='Function'>÷</span><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='Function'>↕</span><span class='Value'>𝕨</span><span class='Paren'>))</span><span class='Brace'>}</span> <span class='Comment'># Parenthesize monadic functions
+</span>
+ <span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Function'>⊢-</span><span class='Paren'>(</span><span class='Function'>↕⊣</span><span class='Paren'>))</span><span class='Function'>÷</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Number'>1</span><span class='Modifier'>˙</span><span class='Function'>+</span><span class='Paren'>(</span><span class='Function'>↕⊣</span><span class='Paren'>))</span> <span class='Comment'># 𝕨 to ⊣ and 𝕩 to ⊢
+</span></pre>
+<p>It's not pretty, but does give the same result.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=buKGkDUg4ouEIGvihpAzCmsgKCjDl8K04oqiLSjihpXiiqMpKcO3KMOXwrQxy5krKOKGleKKoykpKSBu">↗️</a><pre> <span class='Value'>k</span> <span class='Paren'>((</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Function'>⊢-</span><span class='Paren'>(</span><span class='Function'>↕⊣</span><span class='Paren'>))</span><span class='Function'>÷</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Number'>1</span><span class='Modifier'>˙</span><span class='Function'>+</span><span class='Paren'>(</span><span class='Function'>↕⊣</span><span class='Paren'>)))</span> <span class='Value'>n</span>
+10
+</pre>
+<p>This misses entirely the draw of tacit programming for this example, which is that it allows us to combine the repeated <code><span class='Function'>↕</span></code> and <code><span class='Function'>×</span><span class='Modifier'>´</span></code> functions—not that we can't do it in a block function, but it turns out to be more natural in tacit code. Here's a list of transformations that turn the block into <em>nice</em> tacit code, not just any tacit code.</p>
+<pre><span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Value'>𝕩</span><span class='Function'>-↕</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>÷×</span><span class='Modifier'>´</span><span class='Number'>1</span><span class='Function'>+↕</span><span class='Value'>𝕨</span><span class='Brace'>}</span>
+
+<span class='Function'>↕</span><span class='Modifier2'>⊸</span><span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Value'>𝕩</span><span class='Function'>-</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>÷×</span><span class='Modifier'>´</span><span class='Number'>1</span><span class='Function'>+</span><span class='Value'>𝕨</span><span class='Brace'>}</span> <span class='Comment'># The ↕ is applied to every instance of 𝕨
+</span>
+<span class='Function'>↕</span><span class='Modifier2'>⊸</span><span class='Paren'>((</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Function'>⊢-⊣</span><span class='Paren'>)</span><span class='Function'>÷</span><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='Comment'># Mechanically transform to tacit
+</span>
+<span class='Function'>↕</span><span class='Modifier2'>⊸</span><span class='Paren'>((</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Function'>-</span><span class='Modifier'>˜</span><span class='Paren'>)</span><span class='Function'>÷</span><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='Comment'># ⊢-⊣ is -˜
+</span>
+<span class='Function'>↕</span><span class='Modifier2'>⊸</span><span class='Paren'>(</span><span class='Function'>-</span><span class='Modifier'>˜</span><span class='Function'>÷</span><span class='Modifier2'>○</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Paren'>)</span><span class='Number'>1</span><span class='Function'>+⊣</span><span class='Paren'>)</span> <span class='Comment'># Both arguments to ÷ have ×´ applied
+</span>
+<span class='Paren'>(</span><span class='Function'>-÷</span><span class='Modifier2'>○</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Paren'>)</span><span class='Number'>1</span><span class='Function'>+⊢</span><span class='Paren'>)</span><span class='Modifier2'>⟜</span><span class='Function'>↕</span><span class='Modifier'>˜</span> <span class='Comment'># Move ˜ to the outside
+</span></pre>
+<p>The bqncrate version changes <code><span class='Number'>1</span><span class='Function'>+⊢</span></code> to <code><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span></code>, but otherwise matches the final line. As you can see, there are a few slightly different ways to write this function. This is a common situation. You might choose one version based on personal style, or which parts of the function you want to emphasize.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=buKGkDUg4ouEIGvihpAzCmsgKC3Dt+KXiyjDl8K0KTHiirgrKeKfnOKGlcucIG4=">↗️</a><pre> <span class='Value'>k</span> <span class='Paren'>(</span><span class='Function'>-÷</span><span class='Modifier2'>○</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Paren'>)</span><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Paren'>)</span><span class='Modifier2'>⟜</span><span class='Function'>↕</span><span class='Modifier'>˜</span> <span class='Value'>n</span>
+10
+</pre>
+<p>A side effect of moving to tacit code is that the function is now defined in the monadic case, where it gave an error previously. It copies the left argument over to the right, and the number of ways to choose <code><span class='Value'>n</span></code> items out of <code><span class='Value'>n</span></code> is always <code><span class='Number'>1</span></code>, so this is a pretty useless addition.</p>
+<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eyjDl8K08J2VqS3ihpXwnZWoKcO3w5fCtDEr4oaV8J2VqH0gMTAKCigtw7fil4sow5fCtCkx4oq4Kynin5zihpXLnCAxMA==">↗️</a><pre> <span class='Brace'>{</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Value'>𝕩</span><span class='Function'>-↕</span><span class='Value'>𝕨</span><span class='Paren'>)</span><span class='Function'>÷×</span><span class='Modifier'>´</span><span class='Number'>1</span><span class='Function'>+↕</span><span class='Value'>𝕨</span><span class='Brace'>}</span> <span class='Number'>10</span>
+<span class='Error'>Error: This block cannot be called monadically</span>
+
+ <span class='Paren'>(</span><span class='Function'>-÷</span><span class='Modifier2'>○</span><span class='Paren'>(</span><span class='Function'>×</span><span class='Modifier'>´</span><span class='Paren'>)</span><span class='Number'>1</span><span class='Modifier2'>⊸</span><span class='Function'>+</span><span class='Paren'>)</span><span class='Modifier2'>⟜</span><span class='Function'>↕</span><span class='Modifier'>˜</span> <span class='Number'>10</span>
+1
+</pre>
+<p>But it can confuse the reader, who might try to work out what the monadic case does before realizing this. So it's good practice to make sure the context indicates how many arguments a tacit function takes, because the function itself doesn't tell. This is also a reason to move to blocks with headers as functions get larger.</p>