diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2021-03-13 10:28:39 -0500 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2021-03-13 10:28:39 -0500 |
| commit | 0658e1ba9dc1095449e4c0289324955716d402ef (patch) | |
| tree | 7a0a3716d634c69bcf77afe0da9fc9ec9983ff4a /docs | |
| parent | 02d3ccdaee34c83aa26448794f4f98ef0adae58c (diff) | |
Use •Eval or •BQN instead of ⍎
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/doc/arithmetic.html | 16 | ||||
| -rw-r--r-- | docs/doc/fromDyalog.html | 6 | ||||
| -rw-r--r-- | docs/doc/fromJ.html | 15 | ||||
| -rw-r--r-- | docs/doc/oop.html | 137 | ||||
| -rw-r--r-- | docs/doc/paradigms.html | 19 | ||||
| -rw-r--r-- | docs/doc/tacit.html | 213 |
6 files changed, 403 insertions, 3 deletions
diff --git a/docs/doc/arithmetic.html b/docs/doc/arithmetic.html new file mode 100644 index 00000000..ee6e66ac --- /dev/null +++ b/docs/doc/arithmetic.html @@ -0,0 +1,16 @@ +<head> + <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/> + <link href="../style.css" rel="stylesheet"/> + <title>BQN: Arithmetic functions</title> +</head> +<div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a> / <a href="../index.html">main</a> / <a href="index.html">doc</a></div> +<h1 id="arithmetic-functions">Arithmetic functions</h1> +<p>BQN's arithmetic functions use mostly the same symbols as APL, and the functionality is actually defined by the language implementation's number system and not the specification, so there's not too much to say about them.</p> +<p>Summary of differences for APLers:</p> +<ul> +<li>Exponentiation is represented with the star character <code><span class='Function'>⋆</span></code>, since asterisk <code><span class='Value'>*</span></code> is rendered inconsistently across fonts and sometimes appears as a superscript.</li> +<li>There's a root function <code><span class='Function'>√</span></code>.</li> +<li>Not uses a different symbol <code><span class='Function'>¬</span></code>, and logical functions (described on <a href="logic.html">their own page</a>) are extended linearly in all arguments instead of using GCD or LCM.</li> +<li>Dyadic arithmetic functions use leading axis agreement like J.</li> +</ul> +<h2 id=""></h2> diff --git a/docs/doc/fromDyalog.html b/docs/doc/fromDyalog.html index f9c7eeaa..5a4f6241 100644 --- a/docs/doc/fromDyalog.html +++ b/docs/doc/fromDyalog.html @@ -280,7 +280,7 @@ <tr><td> <code><span class='Value'>*</span></code> </td><td colspan=2><code><span class='Function'>⋆</span></code></td> </tr> <tr><td> <code><span class='Modifier2'>⍟</span></code> </td><td colspan=2><code><span class='Function'>⋆</span><span class='Modifier'>⁼</span></code></td> </tr> <tr><td> <code><span class='Function'>!</span></code> </td><td><code><span class='Function'>×</span><span class='Modifier'>´</span><span class='Number'>1</span><span class='Function'>+↕</span></code> </td><td> <code><span class='Function'>-</span><span class='Modifier'>˜</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='Function'>⊢</span><span class='Paren'>)</span><span class='Number'>1</span><span class='Function'>+↕</span><span class='Modifier2'>∘</span><span class='Function'>⊣</span></code></td></tr> -<tr><td> <code><span class='Modifier2'>○</span></code> </td><td colspan=2>Some complex exponential stuff, maybe</td> </tr> +<tr><td> <code><span class='Modifier2'>○</span></code> </td><td> <code><span class='Number'>π</span><span class='Modifier2'>⊸</span><span class='Function'>×</span></code> </td><td> <code><span class='Value'>•math</span></code></td> </tr> <tr><td> <code><span class='Value'>~</span></code> </td><td> <code><span class='Function'>¬</span></code> </td><td> <code><span class='Function'>¬</span><span class='Modifier2'>∘</span><span class='Function'>∊/⊣</span></code></td> </tr> <tr><td> <code><span class='Value'>?</span></code> </td><td colspan=2>Library?</td> </tr> <tr><td> <code><span class='Value'>⍲</span></code> </td><td> </td><td> <code><span class='Function'>¬</span><span class='Modifier2'>∘</span><span class='Function'>∧</span></code></td> </tr> @@ -302,8 +302,8 @@ <tr><td> <code><span class='Function'>⍋</span></code> </td><td> <code><span class='Function'>⍋</span></code> </td><td> Give up </td> </tr> <tr><td> <code><span class='Function'>⍒</span></code> </td><td> <code><span class='Function'>⍒</span></code> </td><td> Give up </td> </tr> <tr><td> <code><span class='Function'>≢</span></code> </td><td> <code><span class='Function'>≠</span></code> </td><td> <code><span class='Function'>≢</span></code></td> </tr> -<tr><td> <code><span class='Value'>⍎</span></code> </td><td colspan=2 rowspan=2>To be decided</td> </tr> -<tr><td> <code><span class='Value'>⍕</span></code> </td> </tr> +<tr><td> <code><span class='Value'>⍎</span></code> </td><td colspan=2><code><span class='Function'>•Eval</span></code></td> </tr> +<tr><td> <code><span class='Value'>⍕</span></code> </td><td colspan=2><code><span class='Function'>•Fmt</span></code></td> </tr> <tr><td> <code><span class='Value'>⊥</span></code> </td><td> </td><td> <code><span class='Brace'>{</span><span class='Function'>+</span><span class='Modifier2'>⟜</span><span class='Paren'>(</span><span class='Value'>𝕨</span><span class='Modifier2'>⊸</span><span class='Function'>×</span><span class='Paren'>)</span><span class='Modifier'>´</span><span class='Function'>⌽</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> </td> </tr> <tr><td> <code><span class='Value'>⊤</span></code> </td><td> </td><td> <code><span class='Brace'>{</span><span class='Value'>𝕨</span><span class='Function'>|</span><span class='Number'>1</span><span class='Function'>↓⌊</span><span class='Modifier2'>∘</span><span class='Function'>÷</span><span class='Modifier'>`</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</span><span class='Value'>𝕨</span><span class='Function'>∾<</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code></td> </tr> <tr><td> <code><span class='Value'>⌹</span></code> </td><td colspan=2><code><span class='Function'>+</span><span class='Modifier'>˝</span><span class='Modifier2'>∘</span><span class='Function'>×</span><span class='Modifier2'>⎉</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>∞</span><span class='Modifier'>⁼</span></code> I guess</td> </tr> diff --git a/docs/doc/fromJ.html b/docs/doc/fromJ.html index 02fc397c..a39e156c 100644 --- a/docs/doc/fromJ.html +++ b/docs/doc/fromJ.html @@ -569,6 +569,16 @@ <td></td> </tr> <tr> +<td><code><span class='String'>"</span><span class='Number'>.</span></code></td> +<td><code><span class='Function'>•Eval</span></code></td> +<td></td> +</tr> +<tr> +<td><code><span class='String'>"</span><span class='Value'>:</span></code></td> +<td><code><span class='Function'>•Fmt</span></code></td> +<td></td> +</tr> +<tr> <td><code><span class='Value'>e.</span></code></td> <td><code><span class='Function'>><</span><span class='Modifier2'>∘</span><span class='Function'>∾∊</span><span class='Modifier'>¨</span><span class='Function'>⊢</span></code></td> <td><code><span class='Function'>∊</span></code></td> @@ -598,6 +608,11 @@ <td><code><span class='Function'>≡</span></code></td> <td></td> </tr> +<tr> +<td><code><span class='Value'>o.</span></code></td> +<td><code><span class='Number'>π</span><span class='Modifier2'>⊸</span><span class='Function'>×</span></code></td> +<td><code><span class='Value'>•math</span></code></td> +</tr> </tbody> </table> <p>Some J modifier expressions are translated below. BQN doesn't keep track of the rank of functions, so the "close" compositions <code><span class='String'>@</span></code> <code><span class='Value'>&</span></code> <code><span class='Value'>&</span><span class='Number'>.</span></code> have no BQN equivalents: instead, specify a rank after composing.</p> diff --git a/docs/doc/oop.html b/docs/doc/oop.html new file mode 100644 index 00000000..bfbdf2a7 --- /dev/null +++ b/docs/doc/oop.html @@ -0,0 +1,137 @@ +<head> + <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/> + <link href="../style.css" rel="stylesheet"/> + <title>Object-oriented programming in BQN</title> +</head> +<div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a> / <a href="../index.html">main</a> / <a href="index.html">doc</a></div> +<h1 id="object-oriented-programming-in-bqn">Object-oriented programming in BQN</h1> +<p>BQN's <a href="namespace.html">namespaces</a> can be used to support a simple form of <a href="https://en.wikipedia.org/wiki/Object-oriented_programming">object-oriented programming</a> (OOP) without type checking or inheritance. It's suitable for some program architectures but not others: making OOP work as a solution to every problem isn't a BQN design goal. In fact, BQN was never designed to support OOP at all! I added namespaces or modules as a way to structure programs. The techniques we're going to discuss are all just ways to use namespaces, and if it ever starts seeming like confusing magic it might help to go back to this model. However, thinking of namespaces as objects can be quite powerful in the right circumstances, and on this page I'm going to frame things in OOP terms. The following table shows which well-known aspects of OOP are supported in BQN:</p> +<table> +<thead> +<tr> +<th>Feature</th> +<th>In BQN?</th> +</tr> +</thead> +<tbody> +<tr> +<td>Objects</td> +<td><a href="#objects">Yes</a> (namespaces)</td> +</tr> +<tr> +<td>Classes</td> +<td><a href="#classes">Yes</a> (function returning namespace)</td> +</tr> +<tr> +<td>Fields</td> +<td><a href="#objects">Yes</a></td> +</tr> +<tr> +<td>Methods</td> +<td><a href="#objects">Yes</a></td> +</tr> +<tr> +<td>Class variables</td> +<td><a href="#class-variables">Sort of</a></td> +</tr> +<tr> +<td>Access</td> +<td>Public/instance-private</td> +</tr> +<tr> +<td><code><span class='Value'>this</span></code></td> +<td>No</td> +</tr> +<tr> +<td>Inheritance (is-a)</td> +<td>No</td> +</tr> +<tr> +<td>Composition (has-a)</td> +<td><a href="#composition">Yes</a></td> +</tr> +<tr> +<td>Interfaces</td> +<td>No</td> +</tr> +<tr> +<td>Abstract classes</td> +<td>No</td> +</tr> +<tr> +<td>Mixins</td> +<td>Not really (needs <code><span class='Value'>this</span></code>)</td> +</tr> +</tbody> +</table> +<h2 id="objects">Objects</h2> +<p>An object in BQN is simply a namespace: its fields and methods are variables in the namespace, and one of these can be accessed outside of the namespace with dot syntax if it's exported with <code><span class='Gets'>⇐</span></code>. Unexported variables are instance-private in OOP parlance, meaning that only they're only visible to the object containing them. These might be used simply as utilities or they might hold state for the object. As an example, the object below implements the <a href="https://en.wikipedia.org/wiki/Tower_of_Hanoi">Tower of Hanoi</a> puzzle with five disks. You can view the state (a list of disks occupying each of the three rods) with <code><span class='Value'>towerOfHanoi.View</span></code>, or move the top disk from one rod to another with <code><span class='Value'>towerOfHanoi.Move</span></code>.</p> +<pre><span class='Value'>towerOfHanoi</span> <span class='Gets'>←</span> <span class='Brace'>{</span> + <span class='Value'>l</span> <span class='Gets'>←</span> <span class='Function'>↕</span><span class='Modifier'>¨</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span> + <span class='Function'>View</span> <span class='Gets'>⇐</span> <span class='Brace'>{</span><span class='Value'>𝕤</span> + <span class='Value'>l</span> + <span class='Brace'>}</span> + <span class='Function'>Move</span> <span class='Gets'>⇐</span> <span class='Brace'>{</span><span class='Value'>from</span><span class='Ligature'>‿</span><span class='Value'>to:</span> + <span class='Value'>l</span> <span class='Gets'>↩</span> <span class='Function'>Transfer</span><span class='Modifier'>´</span><span class='Modifier2'>⌾</span><span class='Paren'>(</span><span class='Value'>𝕩</span><span class='Modifier2'>⊸</span><span class='Function'>⊏</span><span class='Paren'>)</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Function'>≠</span><span class='Modifier'>´</span><span class='Value'>𝕩</span><span class='Paren'>)</span> <span class='Value'>l</span> + <span class='Brace'>}</span> + <span class='Comment'># Move a disk from 𝕨 to 𝕩 +</span> <span class='Function'>Transfer</span> <span class='Gets'>←</span> <span class='Brace'>{</span> + <span class='String'>"No disk to move"</span><span class='Function'>!</span><span class='Number'>0</span><span class='Function'><≠</span><span class='Value'>𝕨</span> + <span class='String'>"Can't place larger disk on smaller one"</span><span class='Function'>!</span><span class='Paren'>(</span><span class='Number'>0</span><span class='Function'><≠</span><span class='Paren'>)</span><span class='Modifier2'>◶</span><span class='Bracket'>⟨</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Value'>𝕨</span><span class='Function'><</span><span class='Modifier2'>○</span><span class='Function'>⊑⊢</span><span class='Bracket'>⟩</span><span class='Value'>𝕩</span> + <span class='Bracket'>⟨</span><span class='Number'>1</span><span class='Function'>↓</span><span class='Value'>𝕨</span><span class='Separator'>,</span> <span class='Value'>𝕨</span><span class='Function'>⊏</span><span class='Modifier2'>⊸</span><span class='Function'>∾</span><span class='Value'>𝕩</span><span class='Bracket'>⟩</span> + <span class='Brace'>}</span> +<span class='Brace'>}</span> +</pre> +<p>Two fields <code><span class='Value'>l</span></code> and <code><span class='Function'>Transfer</span></code> aren't exported, for two different reasons. <code><span class='Value'>l</span></code> encodes the state of the tower, but it's often better to expose it with the function <code><span class='Function'>View</span></code> instead to allow the internal representation to be changed freely. <code><span class='Function'>Transfer</span></code> is just a utility function. It's not dangerous to use outside of the object but there's no reason to expose it through <code><span class='Value'>towerOfHanoi</span></code>'s interface: if it's wanted in another place it should be moved to a common location.</p> +<p>Here are the results of a few applications of these functions.</p> +<pre> <span class='Value'>t</span> <span class='Gets'>←</span> <span class='Value'>towerOfHanoi</span> + <span class='Value'>t.View</span><span class='String'>@</span> +<span class='Bracket'>⟨</span> <span class='Bracket'>⟨</span> <span class='Number'>0</span> <span class='Number'>1</span> <span class='Number'>2</span> <span class='Number'>3</span> <span class='Number'>4</span> <span class='Bracket'>⟩</span> <span class='Bracket'>⟨⟩</span> <span class='Bracket'>⟨⟩</span> <span class='Bracket'>⟩</span> + <span class='Value'>t.Move</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>2</span> +<span class='Bracket'>⟨</span> <span class='Bracket'>⟨</span> <span class='Number'>1</span> <span class='Number'>2</span> <span class='Number'>3</span> <span class='Number'>4</span> <span class='Bracket'>⟩</span> <span class='Bracket'>⟨⟩</span> <span class='Bracket'>⟨</span> <span class='Number'>0</span> <span class='Bracket'>⟩</span> <span class='Bracket'>⟩</span> + <span class='Value'>t.Move</span> <span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>2</span> +<span class='Function'>!</span> <span class='String'>"No disk to move"</span> + <span class='Value'>t.Move</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span> +<span class='Bracket'>⟨</span> <span class='Bracket'>⟨</span> <span class='Number'>2</span> <span class='Number'>3</span> <span class='Number'>4</span> <span class='Bracket'>⟩</span> <span class='Bracket'>⟨</span> <span class='Number'>1</span> <span class='Bracket'>⟩</span> <span class='Bracket'>⟨</span> <span class='Number'>0</span> <span class='Bracket'>⟩</span> <span class='Bracket'>⟩</span> + <span class='Value'>t.Move</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span> +<span class='Bracket'>⟨</span> <span class='Bracket'>⟨</span> <span class='Number'>2</span> <span class='Number'>3</span> <span class='Number'>4</span> <span class='Bracket'>⟩</span> <span class='Bracket'>⟨</span> <span class='Number'>0</span> <span class='Number'>1</span> <span class='Bracket'>⟩</span> <span class='Bracket'>⟨⟩</span> <span class='Bracket'>⟩</span> +</pre> +<h2 id="classes">Classes</h2> +<p>The object above is a singleton: there's just one of it, at least in the scope it occupies. It's often more useful to have a class that can be used to create objects. What we'll call a "class" is a namespace function, that is, a function that contains <code><span class='Gets'>⇐</span></code> and so returns a namespace. It's very easy to convert a singleton object to a class: just add a no-op <code><span class='Value'>𝕤</span></code> line to force it to be a function, and call it with <code><span class='String'>@</span></code> when needed.</p> +<pre><span class='Function'>MakeStack</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>𝕤</span> + <span class='Value'>st</span><span class='Gets'>←</span><span class='String'>@</span> + <span class='Function'>Push</span><span class='Gets'>⇐</span><span class='Brace'>{</span> <span class='Value'>st</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Ligature'>‿</span><span class='Value'>st</span><span class='Brace'>}</span> + <span class='Function'>Pop</span> <span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Value'>𝕤</span><span class='Separator'>⋄</span> <span class='Value'>r</span><span class='Ligature'>‿</span><span class='Value'>s</span><span class='Gets'>←</span><span class='Value'>st</span> <span class='Separator'>⋄</span> <span class='Value'>st</span><span class='Gets'>↩</span><span class='Value'>s</span> <span class='Separator'>⋄</span> <span class='Value'>r</span><span class='Brace'>}</span> +<span class='Brace'>}</span> +</pre> +<p>But there's no need to ignore the argument: often it's useful to initialize a class using one or two arguments. For example, the stack class above can be modified to use <code><span class='Value'>𝕩</span></code> as an initial list of values for the stack.</p> +<pre><span class='Function'>MakeStack</span> <span class='Gets'>←</span> <span class='Brace'>{</span> + <span class='Value'>st</span><span class='Gets'>←</span><span class='String'>@</span> + <span class='Function'>Push</span><span class='Gets'>⇐</span><span class='Brace'>{</span> <span class='Value'>st</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Ligature'>‿</span><span class='Value'>st</span><span class='Brace'>}</span> + <span class='Function'>Pop</span> <span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Value'>𝕤</span><span class='Separator'>⋄</span> <span class='Value'>r</span><span class='Ligature'>‿</span><span class='Value'>s</span><span class='Gets'>←</span><span class='Value'>st</span> <span class='Separator'>⋄</span> <span class='Value'>st</span><span class='Gets'>↩</span><span class='Value'>s</span> <span class='Separator'>⋄</span> <span class='Value'>r</span><span class='Brace'>}</span> + <span class='Function'>Push</span><span class='Modifier'>¨</span> <span class='Value'>𝕩</span> +<span class='Brace'>}</span> +</pre> +<p>A stack is a particularly simple class to make because its state can be represented efficiently as a BQN value. Other data structures don't allow this, and will often require an extra <code><span class='Function'>Node</span></code> class when they are implemented.</p> +<h2 id="mutability">Mutability</h2> +<pre><span class='Function'>MakeQueue</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>𝕤</span> + <span class='Value'>t</span><span class='Gets'>←</span><span class='Value'>h</span><span class='Gets'>←</span><span class='Value'>e</span><span class='Gets'>←</span><span class='Brace'>{</span><span class='Function'>SetN</span><span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Value'>h</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Brace'>}}</span> + <span class='Function'>Node</span><span class='Gets'>←</span><span class='Brace'>{</span><span class='Value'>v</span><span class='Gets'>⇐</span><span class='Value'>𝕩</span><span class='Separator'>⋄</span><span class='Value'>n</span><span class='Gets'>⇐</span><span class='Value'>e</span> <span class='Separator'>⋄</span> <span class='Function'>SetN</span><span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Value'>n</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Brace'>}}</span> + <span class='Function'>Push</span><span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Value'>t.SetN</span> <span class='Value'>n</span><span class='Gets'>←</span><span class='Function'>Node</span> <span class='Value'>𝕩</span> <span class='Separator'>⋄</span> <span class='Value'>t</span><span class='Gets'>↩</span><span class='Value'>n</span><span class='Brace'>}</span> + <span class='Function'>Pop</span> <span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Value'>𝕤</span><span class='Separator'>⋄</span><span class='Value'>v</span><span class='Gets'>←</span><span class='Value'>h.v</span><span class='Separator'>⋄</span><span class='Brace'>{</span><span class='Value'>t</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier2'>⍟</span><span class='Paren'>(</span><span class='Value'>e</span><span class='Modifier2'>⊸</span><span class='Function'>=</span><span class='Paren'>)</span><span class='Value'>h</span><span class='Gets'>↩</span><span class='Value'>h.n</span><span class='Separator'>⋄</span><span class='Value'>v</span><span class='Brace'>}</span> +<span class='Brace'>}</span> +</pre> +<h2 id="composition">Composition</h2> +<h2 id="class-variables">Class variables</h2> +<h2 id="self-reference">Self-reference</h2> +<p>An object's class is given by <code><span class='Function'>𝕊</span></code>. Remember, a class is an ordinary BQN function! It might be useful for an object to produce another object of the same class (particularly if it's immutable), and an object might also expose a field <code><span class='Value'>class</span><span class='Gets'>⇐</span><span class='Value'>𝕤</span></code> to test whether an object <code><span class='Value'>o</span></code> belongs to a class <code><span class='Value'>c</span></code> with <code><span class='Value'>o.class</span> <span class='Function'>=</span> <span class='Value'>c</span></code>.</p> +<p>It's not currently possible for an object to know its own value without some outside help, such as a special constructor:</p> +<pre><span class='Function'>IntrospectiveClass</span> <span class='Gets'>←</span> <span class='Brace'>{</span> + <span class='Value'>obj</span> <span class='Gets'>←</span> <span class='Brace'>{</span> + <span class='Value'>this</span><span class='Gets'>⇐</span><span class='String'>@</span> + <span class='Function'>SetThis</span> <span class='Gets'>⇐</span> <span class='Brace'>{</span> <span class='Function'>!</span><span class='Value'>this</span><span class='Function'>=</span><span class='String'>@</span> <span class='Separator'>⋄</span> <span class='Value'>this</span><span class='Gets'>↩</span><span class='Value'>𝕩</span> <span class='Brace'>}</span> + <span class='Brace'>}</span> + <span class='Value'>obj.setThis</span> <span class='Value'>obj</span> +<span class='Brace'>}</span> +</pre> +<p>This is a pretty clunky solution, and exports a useless method <code><span class='Function'>SetThis</span></code> (which gives an error if it's ever called). It would be possible for BQN to define a system value <code><span class='Value'>•this</span></code> that just gets the namespace's value. It would work only at the top level, so it would have to be assigned (<code><span class='Value'>this</span><span class='Gets'>←</span><span class='Value'>•this</span></code>) in order to use it in functions. This means it's always used before the namespace is done being defined, so a drawback is that it introduces the possibility that an object used in a program has undefined fields. The reason this isn't possible for objects without <code><span class='Value'>•this</span></code> is that BQN's blocks don't have any sort of control flow, so that they always execute every statement in order. The namespace becomes accessible as a value once the block finishes, and at this point every statement has been executed and every field is initialized.</p> diff --git a/docs/doc/paradigms.html b/docs/doc/paradigms.html new file mode 100644 index 00000000..091026dd --- /dev/null +++ b/docs/doc/paradigms.html @@ -0,0 +1,19 @@ +<head> + <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/> + <link href="../style.css" rel="stylesheet"/> + <title>BQN in programming paradigms</title> +</head> +<div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a> / <a href="../index.html">main</a> / <a href="index.html">doc</a></div> +<h1 id="bqn-in-programming-paradigms">BQN in programming paradigms</h1> +<p>It hangs onto weakly positive connotations somehow, but the term "multi-paradigm" should not really impress you. Let's dig into exactly which paradigms BQN supports and how.</p> +<p>This information won't really tell you what tasks BQN is good for: after all, it turns out you can write a compiler entirely using array programming, something many people assumed was impossible. Instead, it tells you what approaches you can take to writing programs, and how comfortable you'll find it to work with BQN—or how much you can use it to stretch your brain in new directions.</p> +<p>dynamically typed +high level</p> +<p>BQN is not great for <strong>imperative</strong> programming.</p> +<p>imperative in which the programmer instructs the machine how to change its state, +procedural which groups instructions into procedures, +object-oriented which groups instructions with the part of the state they operate on,</p> +<p>declarative in which the programmer merely declares properties of the desired result, but not how to compute it +functional in which the desired result is declared as the value of a series of function applications, +logic or reactive</p> +<p>macros or reflection</p> diff --git a/docs/doc/tacit.html b/docs/doc/tacit.html new file mode 100644 index 00000000..20ba910a --- /dev/null +++ b/docs/doc/tacit.html @@ -0,0 +1,213 @@ +<head> + <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/> + <link href="../style.css" rel="stylesheet"/> + <title>Tacit (point-free) programming in BQN</title> +</head> +<div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a> / <a href="../index.html">main</a> / <a href="index.html">doc</a></div> +<h1 id="tacit-point-free-programming-in-bqn">Tacit (point-free) programming in BQN</h1> +<p><a href="https://en.wikipedia.org/wiki/Tacit_programming">Tacit programming</a> (<a href="https://aplwiki.com/wiki/Tacit_programming">APL Wiki</a>) is a general term used to refer to ways to define functions that don't refer to arguments directly (say, with identifiers). Instead, tacit programs are built up by combining smaller functions together; we'll discuss the ways BQN offers to combine functions on this page. Since primitive functions like those returning the left (<code><span class='Function'>⊣</span></code>) and right (<code><span class='Function'>⊢</span></code>) arguments, and selection functions (<code><span class='Function'>⊏⊑</span></code>), are available as building blocks, tacit programming doesn't keep the programmer from pinpointing a specific part of the input, as the description might lead you to believe. Nonetheless, it has its limitations. In larger tacit programs, moving values to the right place is tedious and error-prone because of the lack of a convenient labelling mechanism, and important context tends to disappear in a sea of symbols.</p> +<p>In smaller amounts—portions of a line—tacit programming can be the clearest way to express an idea, particularly when just one or two variables are used a few times. Consider the following three expressions to filter only the positive values from a list:</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=bCDihpAgMOKAvzXigL/CrzLigL8x4oC/wq8z4oC/wq80CgooMDxsKS9sCnsoMDzwnZWpKS/wnZWpfSBsCjDiirg84oq4LyBs">↗️</a><pre> <span class='Value'>l</span> <span class='Gets'>←</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>¯2</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>¯3</span><span class='Ligature'>‿</span><span class='Number'>¯4</span> + + <span class='Paren'>(</span><span class='Number'>0</span><span class='Function'><</span><span class='Value'>l</span><span class='Paren'>)</span><span class='Function'>/</span><span class='Value'>l</span> +⟨ 5 1 ⟩ + <span class='Brace'>{</span><span class='Paren'>(</span><span class='Number'>0</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='Value'>l</span> +⟨ 5 1 ⟩ + <span class='Number'>0</span><span class='Modifier2'>⊸</span><span class='Function'><</span><span class='Modifier2'>⊸</span><span class='Function'>/</span> <span class='Value'>l</span> +⟨ 5 1 ⟩ +</pre> +<p>The first of these expressions is the most direct, but with the variable name buried inside, it can't be used on an intermediate value and its input will have to be named. The other two forms stand alone as functions, so they can easily be placed anywhere in a program, even as an operand. But with even the small amount of structure added by a BQN anonymous function, the second method has more organization than action! The third, tacit, version strips away most of the organizing syntax to leave us with the essential pieces <code><span class='Number'>0</span></code>, <code><span class='Function'><</span></code>, and <code><span class='Function'>/</span></code> joined by combinators. The explicit function uses <code><span class='Value'>𝕩</span></code> as a sort of pronoun ("I want the elements of it where it's greater than zero"), while the tacit one elides it ("give me the elements greater than zero").</p> +<p>The ability to easily combine tacit and "explicit" programming such as statements or anonymous functions, far from being only a way to mitigate the disadvantages of these two methods, brings new advantages that no single paradigm could accomplish. Purely tacit programming <em>requires</em> programs to use <em>no</em> local variable names, but partly tacit programming <em>allows</em> them to use <em>fewer</em> names. That means names can be used only for the parts of a program that represent clean, human-understandable concepts. Another possible stategic choice is to use the fact that variables in a tacit expression are expanded as it's formed but those inside a block aren't. So <code><span class='Function'>F</span><span class='Gets'>←</span><span class='Value'>a</span><span class='Modifier2'>⊸</span><span class='Function'>+</span></code> can be chosen to "freeze" the value of <code><span class='Value'>a</span></code> in <code><span class='Function'>F</span></code> without having to use an extra variable, while <code><span class='Function'>F</span><span class='Gets'>←</span><span class='Brace'>{</span><span class='Value'>a</span><span class='Function'>+</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> uses the current value of <code><span class='Value'>a</span></code> each time <code><span class='Function'>F</span></code> is called.</p> +<p>The rest of this page describes BQN's tacit programming facilities. Deciding when to use them is a matter of taste, and experience.</p> +<h2 id="identity-functions">Identity functions</h2> +<p>These are the simplest functions possible. <code><span class='Function'>⊢</span><span class='Value'>𝕩</span></code> is <code><span class='Value'>𝕩</span></code> and <code><span class='Function'>⊣</span><span class='Value'>𝕩</span></code> is <code><span class='Value'>𝕩</span></code>. <code><span class='Value'>𝕨</span><span class='Function'>⊢</span><span class='Value'>𝕩</span></code> is <code><span class='Value'>𝕩</span></code> and <code><span class='Value'>𝕨</span><span class='Function'>⊣</span><span class='Value'>𝕩</span></code> is <code><span class='Value'>𝕨</span></code>. <code><span class='Function'>⊢</span></code> returns its right argument and <code><span class='Function'>⊣</span></code> returns its left argument but will settle for the right one if there's just one. <code><span class='Function'>⊢</span></code> is <code><span class='Brace'>{</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> and <code><span class='Function'>⊣</span></code> is <code><span class='Brace'>{</span><span class='Value'>𝕩;𝕨</span><span class='Brace'>}</span></code>. We will use them quite frequently here and you can decide at the end whether it's really worth it to soak up two symbols just to do nothing. Not that you'll change <em>my</em> mind about it.</p> +<h2 id="trains">Trains</h2> +<p>In modern APL and its relatives, the backbone of tacit infrastructure is the <em>function train</em>. Trains can take some practice to understand and use well, so they're described in more depth on <a href="train.html">a dedicated page</a>.</p> +<p>Trains are closely related to the mathematical convention that, for example, two functions <code><span class='Function'>F</span></code> and <code><span class='Function'>G</span></code> can be added to get a new function <code><span class='Function'>F+G</span></code> that applies as <code><span class='Paren'>(</span><span class='Function'>F+G</span><span class='Paren'>)(</span><span class='Value'>x</span><span class='Paren'>)</span> <span class='Function'>=</span> <span class='Function'>F</span><span class='Paren'>(</span><span class='Value'>x</span><span class='Paren'>)</span><span class='Function'>+G</span><span class='Paren'>(</span><span class='Value'>x</span><span class='Paren'>)</span></code>. In fact, with a little change to the syntax, we can do exactly this in BQN:</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKKoivijL0pIOKGlTU=">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>⊢+⌽</span><span class='Paren'>)</span> <span class='Function'>↕</span><span class='Number'>5</span> +⟨ 4 4 4 4 4 ⟩ +</pre> +<p>So given a list of the first few natural numbers, that <a href="#identity-functions"><em>same</em></a> list <em>plus</em> its <em>reverse</em> gives a list of just one number repeated many times. I'm sure if I were <a href="https://en.wikipedia.org/wiki/Carl_Friedrich_Gauss#Anecdotes">Gauss</a> I'd be able to find some clever use for that fact. The mathematical convention extends to any central operator and any number of function arguments, which in BQN means we use any three functions, and call the train with a left argument as well—the only numbers of arguments BQN syntax allows are 1 and 2.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=NyAoK+KJjS0pIDI=">↗️</a><pre> <span class='Number'>7</span> <span class='Paren'>(</span><span class='Function'>+≍-</span><span class='Paren'>)</span> <span class='Number'>2</span> +⟨ 9 5 ⟩ +</pre> +<p>Here <a href="couple.html">Couple</a> (<code><span class='Function'>≍</span></code>) is used to combine two units into a list, so we get seven plus and minus two. It's also possible to leave out the leftmost function of a train, or replace it with <code><span class='Nothing'>·</span></code>. In this case the function on the right is called, then the other function is called on its result—it's identical to the mathematical composition <code><span class='Modifier2'>∘</span></code>, which is also part of BQN.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=KOKIvuKMvSkgImFiIuKAvyJjZGUi4oC/ImYiCijCt+KIvuKMvSkgImFiIuKAvyJjZGUi4oC/ImYiCuKIvuKImOKMvSAiYWIi4oC/ImNkZSLigL8iZiI=">↗️</a><pre> <span class='Paren'>(</span><span class='Function'>∾⌽</span><span class='Paren'>)</span> <span class='String'>"ab"</span><span class='Ligature'>‿</span><span class='String'>"cde"</span><span class='Ligature'>‿</span><span class='String'>"f"</span> +"fcdeab" + <span class='Paren'>(</span><span class='Nothing'>·</span><span class='Function'>∾⌽</span><span class='Paren'>)</span> <span class='String'>"ab"</span><span class='Ligature'>‿</span><span class='String'>"cde"</span><span class='Ligature'>‿</span><span class='String'>"f"</span> +"fcdeab" + <span class='Function'>∾</span><span class='Modifier2'>∘</span><span class='Function'>⌽</span> <span class='String'>"ab"</span><span class='Ligature'>‿</span><span class='String'>"cde"</span><span class='Ligature'>‿</span><span class='String'>"f"</span> +"fcdeab" +</pre> +<p>The three functions <code><span class='Function'>∾⌽</span></code>, <code><span class='Nothing'>·</span><span class='Function'>∾⌽</span></code>, and <code><span class='Function'>∾</span><span class='Modifier2'>∘</span><span class='Function'>⌽</span></code> are completely identical. Why might we want <strong>three</strong> different ways to write the same thing? If we only want to define a function, there's hardly any difference. However, these three forms have different syntax, and might be easier or harder to use in different contexts. As we'll see, we can use <code><span class='Function'>∾</span><span class='Modifier2'>∘</span><span class='Function'>⌽</span></code> inside a train without parenthesizing it, and string <code><span class='Nothing'>·</span><span class='Function'>∾⌽</span></code> but not <code><span class='Function'>∾⌽</span></code> together with other trains. Let's look at how the train syntax extends to longer expressions.</p> +<h2 id="combinators">Combinators</h2> +<svg viewBox='0 0 850 530'> + <g font-size='20px' text-anchor='middle' transform='translate(145,20)'> + <rect class='code' stroke-width='1' rx='12' x='-120.4' y='1' width='240.8' height='205'/> + <text dy='0.32em' y='223' fill='currentColor'>Atop</text> + <g font-size='21px' font-family='monospace' transform='translate(-60.87,25)'> + <text dy='0.32em' y='155' font-size='19px'><tspan class='Function'>𝔽</tspan><tspan class='Modifier2'>∘</tspan><tspan class='Function'>𝔾</tspan> <tspan class='Value'>𝕩</tspan></text> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L0 57'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 57L0 114'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='57'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='114'/> + <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔽</tspan></text> + <text dy='0.32em' x='0' y='57'><tspan class='Function'>𝔾</tspan></text> + <text dy='0.32em' x='0' y='114'><tspan class='Value'>𝕩</tspan></text> + </g> + <g font-size='21px' font-family='monospace' transform='translate(60.87,25)'> + <text dy='0.32em' y='155' font-size='19px'><tspan class='Value'>𝕨</tspan> <tspan class='Function'>𝔽</tspan><tspan class='Modifier2'>∘</tspan><tspan class='Function'>𝔾</tspan> <tspan class='Value'>𝕩</tspan></text> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L0 57'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 57L-32 114'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 57L32 114'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='57'/> + <circle r='12' class='code' stroke-width='0' cx='-32' cy='114'/> + <circle r='12' class='code' stroke-width='0' cx='32' cy='114'/> + <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔽</tspan></text> + <text dy='0.32em' x='0' y='57'><tspan class='Function'>𝔾</tspan></text> + <text dy='0.32em' x='-32' y='114'><tspan class='Value'>𝕨</tspan></text> + <text dy='0.32em' x='32' y='114'><tspan class='Value'>𝕩</tspan></text> + </g> + </g> + <g font-size='20px' text-anchor='middle' transform='translate(425,20)'> + <rect class='code' stroke-width='1' rx='12' x='-120.4' y='1' width='240.8' height='205'/> + <text dy='0.32em' y='223' fill='currentColor'>Over</text> + <g font-size='21px' font-family='monospace' transform='translate(-60.87,25)'> + <text dy='0.32em' y='155' font-size='19px'><tspan class='Function'>𝔽</tspan><tspan class='Modifier2'>○</tspan><tspan class='Function'>𝔾</tspan> <tspan class='Value'>𝕩</tspan></text> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L0 57'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 57L0 114'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='57'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='114'/> + <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔽</tspan></text> + <text dy='0.32em' x='0' y='57'><tspan class='Function'>𝔾</tspan></text> + <text dy='0.32em' x='0' y='114'><tspan class='Value'>𝕩</tspan></text> + </g> + <g font-size='21px' font-family='monospace' transform='translate(60.87,25)'> + <text dy='0.32em' y='155' font-size='19px'><tspan class='Value'>𝕨</tspan> <tspan class='Function'>𝔽</tspan><tspan class='Modifier2'>○</tspan><tspan class='Function'>𝔾</tspan> <tspan class='Value'>𝕩</tspan></text> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L-32 57'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M-32 57L-32 114'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L32 57'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M32 57L32 114'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/> + <circle r='12' class='code' stroke-width='0' cx='-32' cy='57'/> + <circle r='12' class='code' stroke-width='0' cx='32' cy='57'/> + <circle r='12' class='code' stroke-width='0' cx='-32' cy='114'/> + <circle r='12' class='code' stroke-width='0' cx='32' cy='114'/> + <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔽</tspan></text> + <text dy='0.32em' x='-32' y='57'><tspan class='Function'>𝔾</tspan></text> + <text dy='0.32em' x='32' y='57'><tspan class='Function'>𝔾</tspan></text> + <text dy='0.32em' x='-32' y='114'><tspan class='Value'>𝕨</tspan></text> + <text dy='0.32em' x='32' y='114'><tspan class='Value'>𝕩</tspan></text> + </g> + </g> + <g font-size='20px' text-anchor='middle' transform='translate(705,20)'> + <rect class='code' stroke-width='1' rx='12' x='-120.4' y='1' width='240.8' height='205'/> + <text dy='0.32em' y='223' fill='currentColor'>Constant</text> + <g font-size='21px' font-family='monospace' transform='translate(-60.87,25)'> + <text dy='0.32em' y='155' font-size='19px'><tspan class='Value'>𝕗</tspan><tspan class='Modifier'>˙</tspan> <tspan class='Value'>𝕩</tspan></text> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L0 57'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='57'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='114'/> + <text dy='0.32em' x='0' y='57'><tspan class='Value'>𝕗</tspan></text> + <text dy='0.32em' x='0' y='114'><tspan class='Value'>𝕩</tspan></text> + </g> + <g font-size='21px' font-family='monospace' transform='translate(60.87,25)'> + <text dy='0.32em' y='155' font-size='19px'><tspan class='Value'>𝕨</tspan> <tspan class='Value'>𝕗</tspan><tspan class='Modifier'>˙</tspan> <tspan class='Value'>𝕩</tspan></text> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L0 57'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='57'/> + <circle r='12' class='code' stroke-width='0' cx='-32' cy='114'/> + <circle r='12' class='code' stroke-width='0' cx='32' cy='114'/> + <text dy='0.32em' x='0' y='57'><tspan class='Value'>𝕗</tspan></text> + <text dy='0.32em' x='-32' y='114'><tspan class='Value'>𝕨</tspan></text> + <text dy='0.32em' x='32' y='114'><tspan class='Value'>𝕩</tspan></text> + </g> + </g> + <g font-size='20px' text-anchor='middle' transform='translate(145,280)'> + <rect class='code' stroke-width='1' rx='12' x='-120.4' y='1' width='240.8' height='205'/> + <text dy='0.32em' y='223' fill='currentColor'>Before</text> + <g font-size='21px' font-family='monospace' transform='translate(-60.87,25)'> + <text dy='0.32em' y='155' font-size='19px'><tspan class='Function'>𝔽</tspan><tspan class='Modifier2'>⊸</tspan><tspan class='Function'>𝔾</tspan> <tspan class='Value'>𝕩</tspan></text> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L-32 57'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M-32 57L0 114'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0Q41.6 57 0 114'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/> + <circle r='12' class='code' stroke-width='0' cx='-32' cy='57'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='114'/> + <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔾</tspan></text> + <text dy='0.32em' x='-32' y='57'><tspan class='Function'>𝔽</tspan></text> + <text dy='0.32em' x='0' y='114'><tspan class='Value'>𝕩</tspan></text> + </g> + <g font-size='21px' font-family='monospace' transform='translate(60.87,25)'> + <text dy='0.32em' y='155' font-size='19px'><tspan class='Value'>𝕨</tspan> <tspan class='Function'>𝔽</tspan><tspan class='Modifier2'>⊸</tspan><tspan class='Function'>𝔾</tspan> <tspan class='Value'>𝕩</tspan></text> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L-32 57'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M-32 57L-32 114'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0C40 57 32 51.3 32 114'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/> + <circle r='12' class='code' stroke-width='0' cx='-32' cy='57'/> + <circle r='12' class='code' stroke-width='0' cx='-32' cy='114'/> + <circle r='12' class='code' stroke-width='0' cx='32' cy='114'/> + <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔾</tspan></text> + <text dy='0.32em' x='-32' y='57'><tspan class='Function'>𝔽</tspan></text> + <text dy='0.32em' x='-32' y='114'><tspan class='Value'>𝕨</tspan></text> + <text dy='0.32em' x='32' y='114'><tspan class='Value'>𝕩</tspan></text> + </g> + </g> + <g font-size='20px' text-anchor='middle' transform='translate(425,280)'> + <rect class='code' stroke-width='1' rx='12' x='-120.4' y='1' width='240.8' height='205'/> + <text dy='0.32em' y='223' fill='currentColor'>After</text> + <g font-size='21px' font-family='monospace' transform='translate(-60.87,25)'> + <text dy='0.32em' y='155' font-size='19px'><tspan class='Function'>𝔽</tspan><tspan class='Modifier2'>⟜</tspan><tspan class='Function'>𝔾</tspan> <tspan class='Value'>𝕩</tspan></text> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0Q-41.6 57 0 114'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L32 57'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M32 57L0 114'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/> + <circle r='12' class='code' stroke-width='0' cx='32' cy='57'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='114'/> + <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔽</tspan></text> + <text dy='0.32em' x='32' y='57'><tspan class='Function'>𝔾</tspan></text> + <text dy='0.32em' x='0' y='114'><tspan class='Value'>𝕩</tspan></text> + </g> + <g font-size='21px' font-family='monospace' transform='translate(60.87,25)'> + <text dy='0.32em' y='155' font-size='19px'><tspan class='Value'>𝕨</tspan> <tspan class='Function'>𝔽</tspan><tspan class='Modifier2'>⟜</tspan><tspan class='Function'>𝔾</tspan> <tspan class='Value'>𝕩</tspan></text> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0C-40 57 -32 51.3 -32 114'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0L32 57'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M32 57L32 114'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/> + <circle r='12' class='code' stroke-width='0' cx='32' cy='57'/> + <circle r='12' class='code' stroke-width='0' cx='-32' cy='114'/> + <circle r='12' class='code' stroke-width='0' cx='32' cy='114'/> + <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔽</tspan></text> + <text dy='0.32em' x='32' y='57'><tspan class='Function'>𝔾</tspan></text> + <text dy='0.32em' x='-32' y='114'><tspan class='Value'>𝕨</tspan></text> + <text dy='0.32em' x='32' y='114'><tspan class='Value'>𝕩</tspan></text> + </g> + </g> + <g font-size='20px' text-anchor='middle' transform='translate(705,280)'> + <rect class='code' stroke-width='1' rx='12' x='-120.4' y='1' width='240.8' height='205'/> + <text dy='0.32em' y='223' fill='currentColor'>Self/Swap</text> + <g font-size='21px' font-family='monospace' transform='translate(-60.87,25)'> + <text dy='0.32em' y='155' font-size='19px'><tspan class='Function'>𝔽</tspan><tspan class='Modifier'>˜</tspan> <tspan class='Value'>𝕩</tspan></text> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0Q-41.6 57 0 114'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0Q41.6 57 0 114'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='114'/> + <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔽</tspan></text> + <text dy='0.32em' x='0' y='114'><tspan class='Value'>𝕩</tspan></text> + </g> + <g font-size='21px' font-family='monospace' transform='translate(60.87,25)'> + <text dy='0.32em' y='155' font-size='19px'><tspan class='Value'>𝕨</tspan> <tspan class='Function'>𝔽</tspan><tspan class='Modifier'>˜</tspan> <tspan class='Value'>𝕩</tspan></text> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0C-40 28.5 0 57 32 114'/> + <path class='yellow' style='fill:none' stroke-width='2' d='M0 0C40 28.5 0 57 -32 114'/> + <circle r='12' class='code' stroke-width='0' cx='0' cy='0'/> + <circle r='12' class='code' stroke-width='0' cx='-32' cy='114'/> + <circle r='12' class='code' stroke-width='0' cx='32' cy='114'/> + <text dy='0.32em' x='0' y='0'><tspan class='Function'>𝔽</tspan></text> + <text dy='0.32em' x='-32' y='114'><tspan class='Value'>𝕨</tspan></text> + <text dy='0.32em' x='32' y='114'><tspan class='Value'>𝕩</tspan></text> + </g> + </g> +</svg> + |
