Closure Scope
§Scope
Scope determines what one variable is referring to, and there are two categories of scope: lexical (static) scope and dynamic scope.
1 | In languages with lexical scope (also called static scope), name resolution |
Let’s look at some examples, which might make the above explanation more concrete.
public class Test {
static int x = 1;
static void g() {
System.out.println(x);
x = 2;
}
static void f() {
int x = 3;
g();
}
public static void main(String[] args) {
f();
System.out.println(x);
}
}
This Java program prints ‘1’ and ‘2’.
using System.IO;
using System;
class Program
{
static int x = 1;
static void g() {
Console.WriteLine(x);
x = 2;
}
static void f() {
int x = 3;
g();
}
static void Main() {
f();
Console.WriteLine(x);
}
}
This C# program prints 1
and 2
.
print = console.log
var x = 1;
function g() { print(x); x = 2;}
function f() { var x=3; g();}
f();
print(x);
This JavaScript program prints 1
and 2
.
x=1
function g () { echo $x ; x=2 ; }
function f () { local x=3 ; g ; }
f
echo $x
This Bash program prints 3
and 1
.
Most PL uses lexical scope, fortunately.
§Closure
Even if the rule for scoping is defined, there would still be different interpretation on the lexical environment for closures.
In some PL, variables are captured “by value”, eg. Java, while in some other PLs, variables are captured “by reference”, such as C# and JavaScript.
public class HelloWorld {
public static void main(String []args){
int x = 0;
Runnable r = () -> System.out.println(x);
x = 1;
r.run();
}
}
This Java program doesn’t compile, for the variable accessed inside the closure is not final or effectively final.
using System.IO;
using System;
class Program
{
static void Main() {
var x = 0;
Func<int,int> f = y => x + y;
x = 1;
Console.WriteLine(f(1));
}
}
This C# program prints 2
.
print = console.log
x = 0
f = ->
print x
x = 1
f()
This CoffeeScript program prints 2
.