Happy Eliza Doolittle day all; today seems like an appropriate day for careful elocution of technical jargon. So today, yet another question about “scope”. As one of the more over-used jargon terms in programming languages, I get a lot of questions about it.

I’ll remind you all again that in C# the term “scope” has a very carefully defined meaning: the scope of a named entity is the region of program text in which the unqualified name can be used to refer to the entity.[1. Scope is often confused with the closely related concepts of declaration space (the region of code in which no two things may be declared to have the same name), accessibility domain (the region of program text in which a member’s accessibility modifier permits it to be looked up), and lifetime (the portion of the execution of the program during which the contents of a variable are not eligable for garbage collection.)]

For example, the scope of a local variable is the text of the block which declares it. The scope of a private method is the text of the body of the class or struct which declares it. And so on; the C# specification has careful definitions which define the scope of everything that has a name.

The word “lexical” means, in a broad sense “relating to text”, and clearly we have defined “scope” as being a relationship involving text, so is this kind of scoping also called “lexical scoping”?

Sort of, but not exactly. Let me explain.

Programming languages can be broadly divided into two categories: the lexically scoped languages and the dynamically scoped languages. The difference between the two is: in a lexically scoped language, the meaning of an unqualified name can be completely determined by looking at the program text; the analysis can be done “statically”. In a dynamically scoped language the meaning of an unqualified name can change at runtime; the name analysis can only be done “dynamically”.

Let me give you an example; it is easiest to show this with lambdas.

class C { public static Func<int> M() { int x = 123; return () => x; } } class P { static void Main() { int x = 456; Func<int> f = C.M(); System.Console.WriteLine(f()); } }

The question is: what gets printed out? C# is a lexically scoped language, so the meaning of x in the lambda is determined at compile time, by analyzing the text where the lambda was written. C# prints out 123 . If C# were a dynamically scoped language then the meaning of x would be determined by analyzing the location where the delegate was executed at runtime, so it would print out 456 .

Dynamically scoped languages essentially make the C# definition of scope useless; any method that executes a lambda in a dynamically scoped language makes the region of program text in which its locals can be referred to by their names arbitrarily large.

JavaScript, though a very dynamic language, is actually for the most part lexically scoped:

function M() { var x = 123; return function () { return x; }; } function N() { var x = 456; var f = M(); print(f()); // 123 }

However, JavaScript does have one feature which makes it dynamically scoped:

function Q(y) { var x = 123; with(y) return x; } print(Q({ x : 456 })); // 456 print(Q(789)); // 123

Here the meaning of unqualified name x changes at runtime depending on whether y has a member x or not. For this reason I recommend avoiding the with block in JavaScript; it makes it hard for the reader to understand the meaning of the program.

Most modern languages are lexically scoped; experience has shown that lexical scoping is easier on all concerned; developers and maintenance programmers have an easier time understanding lexically scoped languages, and compiler developers have an easier time writing efficient compilers. Some variants of Lisp use dynamic scoping, though Scheme requires lexical scoping. There are still a few dynamically scoped languages in common usage though; PostScript, the programming language which runs on printers, is perhaps the most commonly used of them.

Next time on FAIC: We solve the mystery of the inserted method.