From 5e81613ac137c5641675ceb792ca105d345d98c6 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Thu, 14 Jul 2022 21:02:14 -0400 Subject: Handle transitive dependencies in REPL link code --- docs/doc/lexical.html | 2 +- docs/doc/match.html | 2 +- docs/doc/quick.html | 22 +++++++++++----------- docs/tutorial/variable.html | 8 ++++---- 4 files changed, 17 insertions(+), 17 deletions(-) (limited to 'docs') diff --git a/docs/doc/lexical.html b/docs/doc/lexical.html index 6ff7f51e..141bef45 100644 --- a/docs/doc/lexical.html +++ b/docs/doc/lexical.html @@ -90,7 +90,7 @@

Why define things this way? It's easier to see if you imagine the variable used is also a function. It's normal for a function to call other functions defined at the top level, of course. And it would be pretty unpleasant for BQN to enforce a specific ordering for them. It would also make recursive functions impossible except by using 𝕊, and mutually recursive ones completely impossible. A simple rule that makes all these things just work smoothly seems much better than any alternative.

Closures

Let's run _makeCount from above a few more times.

-↗️
    C4_2  42 _makeCount  # Start at 4; increment by 2
+↗️
    C4_2  42 _makeCount  # Start at 4; increment by 2
     C1_4  14 _makeCount  #          1;              4
 
     C4_2 0
diff --git a/docs/doc/match.html b/docs/doc/match.html
index 13568805..d5cddee2 100644
--- a/docs/doc/match.html
+++ b/docs/doc/match.html
@@ -92,7 +92,7 @@
 ⟨ 8 12 ⟩
 

These functions both have the definition {a×𝕩}, but give different results! They are different instances of the same block, and have different environments: for T2, a is 2, and for T3, it's 3.

-↗️
    t2 = t3
+↗️
    t2 = t3
 0
 

Some definitions should help to make things clearer. A "block" is not actually a BQN value, but a region of source code enclosed in {} brackets. When the program encounters a block function or modifier, it creates an instance of this block, and then uses this instance in the rest of the expression (actually, an immediate block also creates an instance, but this instance is immediately run, and discarded when it finishes, so it can't be accessed as a value). Every time the function Gen is run, it evaluates the statements it contains, and the second statement {a×𝕩} creates a block instance. So Gen creates a new block instance each time. This is necessary for Gen to work correctly: each time it runs, it creates a new scope, so it needs to create a new function that will be tied to that scope.

diff --git a/docs/doc/quick.html b/docs/doc/quick.html index af70a7b7..cbda94a9 100644 --- a/docs/doc/quick.html +++ b/docs/doc/quick.html @@ -138,7 +138,7 @@
hw case.Upper(¨)
 

This statement consists of the name hw just defined, a compound function, and then the new character . This is another form of assignment, like , but it changes the value of an existing variable instead of defining a new one. There's also some special syntax here: the expression val Fn is shorthand for val Fn val, avoiding the need to write the name hw twice (and val Fn arg means val val Fn arg, like += and so on from C). So we are modifying hw by applying this function case.Upper(¨).

-↗️
    hw  <˘ 2  "helloworld"
+↗️
    hw  <˘ 2  "helloworld"
 
     case.Upper(¨) hw
 ⟨ "Hello" "World" ⟩
@@ -147,14 +147,14 @@
 ⟨ "Hello" "World" ⟩
 

That converts the first character of each string to uppercase! case.Upper is the case conversion function defined before, so that part makes sense. The rest of the function, (¨), would be pronounced "Under the First of Each", which… pretty much makes sense too? The First Each function extracts the first element of each list in hw, the part that used to be "hw" but is now "HW".

-↗️
    ¨ hw
+↗️
    ¨ hw
 "HW"
 
     case.Upper "hw"
 "HW"
 

The Under modifier keeps track of where that string came from and puts it back, to produce a new, altered array. It's kind of special, like Undo, but works on all sorts of fancy selections. It's also worth pointing out that case.Upper applies to a string here, not an individual character. That's because arithmetic is pervasive, so that functions made of arithmetic naturally work on arrays. Although in this case it wasn't really necessary, because it's also possible to map over the two strings and uppercase the first character of each separately:

-↗️
    case.Upper¨ "hello""world"
+↗️
    case.Upper¨ "hello""world"
 ⟨ "Hello" "World" ⟩
 

Modifiers are applied from left to right, opposite to functions (1-modifiers also take the operand on the left while prefix functions have the argument on the right). So case.Upper¨ means (case.Upper)¨.

@@ -163,14 +163,14 @@
•Out hw   ⥊⍉ [hw, ", ""!"]  # Hello, World!
 

None of these functions have a subject to the left, so they're all evaluated as prefix functions. But first, we have the array notation []. This syntax forms an array from its major cells hw and ", ""!" (another strand, a list of two strings). Because the major cells are both lists, we have another rank 2 array.

-↗️
    [hw, ", ""!"]
+↗️
    [hw, ", ""!"]
 ┌─                 
 ╵ "Hello" "World"  
   ", "    "!"      
                   ┘
 

The reason for forming this array is to interleave the elements, or we might say to read down the columns rather than across the rows. This ordering is done with a Transpose to exchange the two axes, then a Deshape to flatten it out, giving a list.

-↗️
     [hw, ", ""!"]
+↗️
     [hw, ", ""!"]
 ┌─              
 ╵ "Hello" ", "  
   "World" "!"   
@@ -180,7 +180,7 @@
 ⟨ "Hello" ", " "World" "!" ⟩
 

Finally, Join combines this list of strings into a single string.

-↗️
    hw   ⥊⍉ [hw, ", ""!"]
+↗️
    hw   ⥊⍉ [hw, ", ""!"]
     hw
 "Hello, World!"
 
@@ -249,7 +249,7 @@ (¨ GV ˜ ·+`GS) r

The first line here applies Proc to each character and the one before it, using ' ' as the character "before" the first. Proc{»𝔽¨} 𝕩 is a fancy way to write (»𝕩) Proc¨ 𝕩, which we'll explain in a moment. First, here's what the Nudge function » does.

-↗️
    hw
+↗️
    hw
 "Hello, World!"
     »hw
 " Hello, World"
@@ -257,7 +257,7 @@
 

It moves its argument forward by one, adding a space character (the array's fill) but keeping the same length. This gives the previous characters that we want to use for Proc's left argument. Here Each is used with two arguments, so that it iterates over them simultaneously, like a "zip" in some languages.

What about the fancy syntax Proc{»𝔽¨} 𝕩? The block {»𝔽¨} is an immediate 1-modifier because it uses 𝔽 for an operand but not the arguments 𝕨 or 𝕩. This means it acts on Proc only, giving »Proc¨, which is a train because it ends in a function . Following the rules for a 3-train, (»Proc¨)𝕩 expands to (»𝕩) Proc¨ (𝕩), and since is the identity function, 𝕩 is 𝕩.

Since a display of lots of namespaces isn't too enlightening, we'll skip ahead and show what the results of GV and GS on those lists would be. GV turns each character into a string, except it makes a space into the empty string. GS has a 1 in the places where we want to split the string.

-↗️
    sp  ' '=hw
+↗️
    sp  ' '=hw
     gv  (1-sp) ¨ hw
     gs  sp  »= hw
 
@@ -312,18 +312,18 @@
 
 
 

There are actually three train groupings here: from right to left, ·+`GS, GV ˜ , and ¨ . Two of them are 2-trains, which apply one function to the result of another, but the one with is a 3-train, applying a function to two results. In the end, functions GS and GV are applied to r. In fact, to evaluate the entire train we can replace these two functions with their results, giving ¨ (GV r) ˜ ·+`(GS r).

-↗️
    ¨ gv ˜ ·+`gs
+↗️
    ¨ gv ˜ ·+`gs
 ⟨ "Hel" "lo," "World!" ⟩
 

In this expression, Nothing can be removed without changing the meaning. It's used in the train to force +` to apply to GS as a 2-train instead of also taking ˜ as a left argument. The Scan +` is a prefix sum, progressively adding up the numbers in gs.

-↗️
    gs
+↗️
    gs
 ⟨ 0 0 0 1 0 0 1 0 0 0 0 0 0 ⟩
 
     +`gs
 ⟨ 0 0 0 1 1 1 2 2 2 2 2 2 2 ⟩
 

The next bit uses Swap to switch the order: gv ˜ +`gs is (+`gs) gv, but sometimes the different order can read better (here it was mostly to squeeze Nothing into the program, I'll admit). Group then splits gv up based on the indices given: the first three elements become element 0 of the result, the next three element 1, and the rest element 2.

-↗️
    (+`gs)  gv
+↗️
    (+`gs)  gv
 ┌─                                                                
 · ⟨ "H" "e" "l" ⟩ ⟨ "l" "o" "," ⟩ ⟨ ⟨⟩ "W" "o" "r" "l" "d" "!" ⟩  
                                                                  ┘
diff --git a/docs/tutorial/variable.html b/docs/tutorial/variable.html
index 5e05d336..9314a878 100644
--- a/docs/tutorial/variable.html
+++ b/docs/tutorial/variable.html
@@ -24,11 +24,11 @@
 ⟨ 3 7 ⟩
 

A variable can't be defined twice in the same scope. Later we'll work with functions and other pieces of code that create their own scopes, but for now all you need to know is that all the code in a tutorial runs in the same scope. So three is already defined, and can't be defined again.

-↗️
    three  4
+↗️
    three  4
 Error: Redefinition
 

It's a little crazy to call them variables if the definition can never change, right? Doesn't "variable" mean "able to change"? Fortunately, this is one way in which BQN isn't crazy. You can modify a variable's value with the arrow provided it's already been defined. This never does anything to the original value: that value stays the same; it's just (probably) not the value of the modified variable any more.

-↗️
    three  4
+↗️
    three  4
 
     three = 3   # Wait why did I do that
 0
@@ -46,7 +46,7 @@
 

Does BQN not know about capital letters? Does it object to self-reference? Why is "BQN" green? At least there's an error message, and a "role" is something we've heard about before. Assignment means anything written with a leftward arrow—either definition or modification.

I'll first confuse you a little more by pointing out that BQN's variables are case-insensitive, and even underscore-insensitive!

-↗️
    three
+↗️
    three
 3
     thrEe
 3
@@ -60,7 +60,7 @@
 3
 

But the syntax highlighter still seems to care, and you'll get a strange result if you try to apply a function to one of the uppercase spellings:

-↗️
    - Three
+↗️
    - Three
 -3{𝔽}
 
     - _three
-- 
cgit v1.2.3