diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-01-28 16:34:41 -0500 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2022-01-28 16:34:41 -0500 |
| commit | 0c716e4c6b7c2c44bbfd02b6503cae66af7b7480 (patch) | |
| tree | ac880382ea281825027b34768d6512d340596e56 /docs/doc/embed.html | |
| parent | 4821f231a00dc93c42fb437359ea657c59c63053 (diff) | |
Separate syntax highlighting category for header/body characters ;:?
Diffstat (limited to 'docs/doc/embed.html')
| -rw-r--r-- | docs/doc/embed.html | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/docs/doc/embed.html b/docs/doc/embed.html index bdd03679..b02342cc 100644 --- a/docs/doc/embed.html +++ b/docs/doc/embed.html @@ -9,16 +9,16 @@ <p>There is only one mechanism to interface between the host language and BQN: the function <code><span class='Value'>bqn</span></code> evaluates a string containing a BQN program and returns the result. Doesn't sound like much, especially considering these programs can't share any state such as global variables (BQN doesn't have those). But taking first-class functions and closures into account, it's all you could ever need!</p> <h2 id="passing-closures"><a class="header" href="#passing-closures">Passing closures</a></h2> <p>Probably you can figure out the easy things like calling <code><span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>"×´1+↕6"</span><span class='Paren'>)</span></code> to compute six factorial. But how do you get JS and BQN to <em>talk</em> to each other, for example to compute the factorial of a number <code><span class='Value'>n</span></code>? Constructing a source string with <code><span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>"×´1+↕"</span><span class='Function'>+</span><span class='Value'>n</span><span class='Paren'>)</span></code> isn't the best way—in fact I would recommend you never use this strategy.</p> -<p>Instead, return a function from BQN and call it: <code><span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>"{×´1+↕𝕩}"</span><span class='Paren'>)(</span><span class='Value'>n</span><span class='Paren'>)</span></code>. This strategy also has the advantage that you can store the function, so that it will only be compiled once. Define <code><span class='Value'>let</span> <span class='Value'>fact</span> <span class='Function'>=</span> <span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>"{×´1+↕𝕩}"</span><span class='Paren'>)</span><span class='Value'>;</span></code> at the top of your program and use it as a function elsewhere.</p> +<p>Instead, return a function from BQN and call it: <code><span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>"{×´1+↕𝕩}"</span><span class='Paren'>)(</span><span class='Value'>n</span><span class='Paren'>)</span></code>. This strategy also has the advantage that you can store the function, so that it will only be compiled once. Define <code><span class='Value'>let</span> <span class='Value'>fact</span> <span class='Function'>=</span> <span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>"{×´1+↕𝕩}"</span><span class='Paren'>)</span><span class='Head'>;</span></code> at the top of your program and use it as a function elsewhere.</p> <p>BQN can also call JS functions, to use functionality that isn't native to BQN or interact with a program written in JS. For example, <code><span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>"{𝕏'a'+↕26}"</span><span class='Paren'>)(</span><span class='Value'>alert</span><span class='Paren'>)</span></code> calls the argument <code><span class='Value'>alert</span></code> from within BQN. The displayed output isn't quite right here, because a BQN string is stored as a JS array, not a string. See the next section for more information.</p> <p>Cool, but none of these examples really use closures, just self-contained functions. <a href="lexical.html#closures">Closures</a> are functions that use outside state, which is maintained over the course of the program. Here's an example program that defines <code><span class='Value'>i</span></code> and then returns a function that manipulates <code><span class='Value'>i</span></code> and returns its new value.</p> <pre><span class='Value'>let</span> <span class='Value'>push</span> <span class='Function'>=</span> <span class='Value'>bqn</span><span class='Paren'>(</span><span class='Modifier'>`</span> <span class='Value'>i</span><span class='Gets'>←</span><span class='Number'>4</span><span class='Function'>⥊</span><span class='Number'>0</span> <span class='Brace'>{</span><span class='Value'>i</span><span class='Function'>+</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Function'>»</span><span class='Value'>i</span><span class='Brace'>}</span> -<span class='Modifier'>`</span><span class='Paren'>)</span><span class='Value'>;</span> -<span class='Value'>push</span><span class='Paren'>(</span><span class='Number'>3</span><span class='Paren'>)</span><span class='Value'>;</span> <span class='Function'>//</span> <span class='Value'>[</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Value'>]</span> -<span class='Value'>push</span><span class='Paren'>(</span><span class='Function'>-</span><span class='Number'>2</span><span class='Paren'>)</span><span class='Value'>;</span> <span class='Function'>//</span> <span class='Value'>[</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Value'>]</span> -<span class='Value'>push</span><span class='Paren'>(</span><span class='Number'>4</span><span class='Paren'>)</span><span class='Value'>;</span> <span class='Function'>//</span> <span class='Value'>[</span><span class='Number'>5</span><span class='Separator'>,</span><span class='Number'>4</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Value'>]</span> +<span class='Modifier'>`</span><span class='Paren'>)</span><span class='Head'>;</span> +<span class='Value'>push</span><span class='Paren'>(</span><span class='Number'>3</span><span class='Paren'>)</span><span class='Head'>;</span> <span class='Function'>//</span> <span class='Value'>[</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Value'>]</span> +<span class='Value'>push</span><span class='Paren'>(</span><span class='Function'>-</span><span class='Number'>2</span><span class='Paren'>)</span><span class='Head'>;</span> <span class='Function'>//</span> <span class='Value'>[</span><span class='Number'>1</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Value'>]</span> +<span class='Value'>push</span><span class='Paren'>(</span><span class='Number'>4</span><span class='Paren'>)</span><span class='Head'>;</span> <span class='Function'>//</span> <span class='Value'>[</span><span class='Number'>5</span><span class='Separator'>,</span><span class='Number'>4</span><span class='Separator'>,</span><span class='Number'>3</span><span class='Separator'>,</span><span class='Number'>0</span><span class='Value'>]</span> </pre> <p>Note that this program doesn't have any outer braces. It's only run once, and it initializes <code><span class='Value'>i</span></code> and returns a function. Just putting braces around it wouldn't have any effect—it just changes it from a program that does something to a program that runs a block that does the same thing—but adding braces and using <code><span class='Value'>𝕨</span></code> or <code><span class='Value'>𝕩</span></code> inside them would turn it into a function that could be run multiple times to create different closures. For example, <code><span class='Value'>pushGen</span> <span class='Function'>=</span> <span class='Value'>bqn</span><span class='Paren'>(</span><span class='String'>"{i←4⥊𝕩⋄{i+↩𝕩»i}}"</span><span class='Paren'>)</span></code> causes <code><span class='Value'>pushGen</span><span class='Paren'>(</span><span class='Value'>n</span><span class='Paren'>)</span></code> to create a new closure with <code><span class='Value'>i</span></code> initialized to <code><span class='Number'>4</span><span class='Function'>⥊</span><span class='Value'>n</span></code>.</p> <p>The program also returns only one function, which can be limiting. But it's possible to get multiple closures out of the same program by returning a list of functions. For example, the following program defines three functions that manipulate a shared array in different ways.</p> @@ -28,7 +28,7 @@ <span class='Function'>RotY</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>a</span><span class='Gets'>↩</span><span class='Value'>𝕩</span><span class='Function'>⌽</span><span class='Value'>a</span><span class='Brace'>}</span> <span class='Function'>Flip</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>𝕤</span><span class='Separator'>⋄</span><span class='Value'>a</span><span class='Gets'>↩</span><span class='Function'>⍉</span><span class='Value'>a</span><span class='Brace'>}</span> <span class='Function'>RotX</span><span class='Ligature'>‿</span><span class='Function'>RotY</span><span class='Ligature'>‿</span><span class='Function'>Flip</span> -<span class='Modifier'>`</span><span class='Paren'>)</span><span class='Value'>;</span> +<span class='Modifier'>`</span><span class='Paren'>)</span><span class='Head'>;</span> </pre> <p>When defining closures for their side effects like this, make sure they are actually functions! For example, since <code><span class='Value'>flip</span></code> ignores its argument (you can call it with <code><span class='Value'>flip</span><span class='Paren'>()</span></code>, because a right argument of <code><span class='Value'>undefined</span></code> isn't valid but will just be ignored), it needs an extra <code><span class='Value'>𝕤</span></code> in the definition to be a function instead of an immediate block.</p> <p>You can also use an array to pass multiple functions or other values from JS into BQN all at once. However, a JS array can't be used directly in BQN because its shape isn't known. The function <code><span class='Value'>list</span><span class='Paren'>()</span></code> converts a JS array into a BQN list by using its length for the shape; the next section has a few more details.</p> |
