From e2b07a5fd0bbaad232c717fb90a31d6c61d72bd4 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Thu, 14 Jul 2022 20:06:50 -0400 Subject: Try to include previous variable definitions in REPL links --- docs/doc/lexical.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/doc/lexical.html') diff --git a/docs/doc/lexical.html b/docs/doc/lexical.html index 4d34cdae..6ff7f51e 100644 --- a/docs/doc/lexical.html +++ b/docs/doc/lexical.html @@ -51,7 +51,7 @@ 42

So the Count function above increments and prints a global counter by a global amount inc, which is visible in Count because it's visible everywhere. Or, not quite… if a block defines its own copy of inc, then it will lose access to the outer one. However, code that comes before that definition can still see the outer variable. So it can copy its value at the start of the block (this won't reflect later changes to the value. Don't shadow variables you want to use!).

-↗️
    { inc3  inc }  # inc is shadowed
+↗️
    { inc3  inc }  # inc is shadowed
 3
 
     inc  # But it's still here in the outer scope
@@ -61,11 +61,11 @@
 6
 

Each scope can only define a given name once. Trying to shadow a name that's in the current scope and not a higher one gives an error at compilation.

-↗️
    { inc3  inc4 }
+↗️
    { inc3  inc4 }
 Error: Redefinition
 

Let's go all in on shadowing and make a modifier that creates its own copies of counter and inc, returning a custom version of the Count function above.

-↗️
    _makeCount  { counterinc𝕗  { counter + 𝕩 × inc } }
+↗️
    _makeCount  { counterinc𝕗  { counter + 𝕩 × inc } }
 
     C3_7  37 _makeCount  # Start at 3; inc by 7
 
@@ -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
@@ -139,7 +139,7 @@
 30
 

Only source code with access to a variable can modify it! This means that if none of the code in a variable's scope modifies it, then the variable is constant. That is, constant once it's defined: remember that it's still possible to get an error if the variable is accessed before being defined.

-↗️
    { { a }  a4 }
+↗️
    { { a }  a4 }
 Error: Reading variable before its defined
 

With lexical scoping, variable mutation automatically leads to mutable data. This is because a function or modifier that depends on the variable value changes its behavior when the variable changes. So do objects; this slightly more concrete case is discussed here. The behavior change is observed by calling operations, and by accessing object fields. These are the only two actions that might behave differently when applied to the same values!

-- cgit v1.2.3