From fc2687ffc8dcb8117bb957bea6b4e7bbdb45ca71 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Thu, 16 Dec 2021 22:15:39 -0500 Subject: =?UTF-8?q?=E2=80=A2ReBQN=20documentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/doc/index.html | 1 + docs/doc/rebqn.html | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ docs/index.html | 2 +- 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 docs/doc/rebqn.html (limited to 'docs') diff --git a/docs/doc/index.html b/docs/doc/index.html index cd9f7f0e..2935fc92 100644 --- a/docs/doc/index.html +++ b/docs/doc/index.html @@ -76,4 +76,5 @@

Environment:

diff --git a/docs/doc/rebqn.html b/docs/doc/rebqn.html new file mode 100644 index 00000000..9911d7c0 --- /dev/null +++ b/docs/doc/rebqn.html @@ -0,0 +1,78 @@ + + + + ReBQN + + +

ReBQN

+

The function •BQN evaluates a source code string passed to it as BQN in an isolated environment and returns the result. There are a few things you might want to change about this. •ReBQN is a function that generates •BQN-like functions, using a namespace 𝕩 for configuration. It can create a "REPL" function that saves state between evaluations, or redefine primitives, and might support extra functionality like keywords in the future.

+

Here are some quick examples of •ReBQN functionality. First, let's make a REPL function by setting repl to "strict" (no re-definitions allowed) instead of the default "none". We can now define a variable in one Repl call and refer to it later.

+↗️
    repl  •ReBQN {repl"strict"}  # Lowercase for function result
+
+    Repl "a ← ↕10"                 # Uppercase to call
+⟨ 0 1 2 3 4 5 6 7 8 9 ⟩
+
+    Repl "⌽ a"
+⟨ 9 8 7 6 5 4 3 2 1 0 ⟩
+
+

This option also powers the results shown on the BQN website: to process a document, a REPL function is created, and used to evaluate every line! Next, we can define a little ASCII calculator using a list of primitives. To mix it up a bit I've made monadic / here a Range function.

+↗️
    calcFns  '+'+, '-'-, '*'×, '/'(÷)
+
+    calc  •ReBQN {primitivescalcFns}
+
+    Calc "7 / 9 - 2*2"  # BQN order of operations
+1.4
+
+    Calc "/ 9"
+⟨ 0 1 2 3 4 5 6 7 8 ⟩
+
+

Options can be used in any combination. Here's a calculator REPL:

+↗️
    calcRepl  •ReBQN {repl"strict", primitivescalcFns}
+
+    CalcRepl "b ← 1 - a←6"
+¯5
+
+    CalcRepl "a * b"
+¯30
+
+

REPL mode

+

The repl property can have the values "none", "strict", and "loose". If no value is given it's equivalent to "none", which means that the resulting function has no memory and each evaluation is independent from the others. But the values "strict" and "loose" make evaluations take place in a shared scope. Now a variable defined at the top level of one source string is visible when later ones are evaluated, and can be viewed and modified.

+↗️
    do  •ReBQN {repl"loose"}
+
+    Do¨ "a←4""⟨a,b←5⟩""{⟨a↩𝕩,b⟩}8"
+⟨ 4 ⟨ 4 5 ⟩ ⟨ 8 5 ⟩ ⟩
+
+

A different •ReBQN result has its own scope and can't access these variables.

+↗️
    doNot  •ReBQN {repl"loose"}
+
+    DoNot "b" # surprised when this fails
+ERROR
+
+

The difference in "strict" and "loose" is that a loose REPL can define a variable again, which just changes its value (under the covers, the is treated as a ).

+↗️
    Do "a ← ¯1"
+¯1
+    Do "a ← b‿a"
+⟨ 5 ¯1 ⟩
+
+    (•ReBQN {repl"strict"})@¨ "a←1""a←2"  # Second one errors
+⟨ 1 @ ⟩
+
+

Primitives

+

The primitives property specifies the full set of primitives available to the new interpreter. Without it, the existing set of primitives is kept. With it, they're all thrown out, and the ones provided are used instead. Since you often would rather extend or modify what's there, the system value •primitives returns the current primitives set in the form used by •ReBQN.

+↗️
    3  •primitives
+⟨ ⟨ '+' + ⟩ ⟨ '-' - ⟩ ⟨ '×' × ⟩ ⟩
+
+    ext  •ReBQN {primitives•primitives'∑',+´'∏',×´}
+
+    Ext "∏1+↕7"
+5040
+    Ext "∑(1↓↕)⊸(⊣/˜0=|)28"  # Sum of divisors
+28
+
+

Appending to •primitives means everything from BQN's there in addition to the given functions.

+

What's allowed? The format for primitives is a list of pairs, where each pair contains one character—the glyph—and one function or modifier. A primitive can't be data, at least at present, because the compiler is only designed to handle the primitive types found in base BQN and extending this doesn't seem terribly important. The type of the primitive's value is very important, because it determines the role it has. Said another way, it's setting the rules of syntax!

+↗️
    (•ReBQN {primitives'^'{𝕨𝔽𝕩𝔽𝕨},'%'}){𝔽} "0 %^ 1‿2"
+⟨ 0 1 2 0 ⟩
+
+

Above, ^ becomes a 1-modifier, so that it modifies % rather than being called directly on 12 as a function.

+

The glyph can be any character that's not being used by BQN already. Characters like c or or : will result in an error, as they'd break BQN syntax. Other than that, the sky's the limit! Or rather, the Unicode consortium is the limit. If they don't recognize your symbol, you're going to have to petition to make it an emoji or something. Oh well.

diff --git a/docs/index.html b/docs/index.html index c14dcff4..6aa53d48 100644 --- a/docs/index.html +++ b/docs/index.html @@ -27,13 +27,13 @@
  • A low-dependency C implementation using bytecode compilation: installation
  • Basic system functions for common math, file, and IO operations
  • Documentation with examples, visuals, explanations, and rationale for features
  • +
  • Replace or extend primitives to make a BQN-like language suited for specialized domains
  • BQN will provide:

    At present, I think BQN is a good choice for learning array programming, scripting, medium-scale number crunching, and recreational programming. For some examples of BQN in action, this repository holds the dreaded self-hosted compiler and the friendlier markdown processor used to generate the site. See also my scripts at bqn-libs, this gnuplot interface, some nicely commented Advent of Code 2021 solutions, or something else from the community page.

    What kind of name is "BQN"?

    -- cgit v1.2.3