views:

1058

answers:

6

I want brief intro to lexical scope

+4  A: 

Lexical (AKA static) scoping refers to determining a variable's scope based solely on its position within the textual corpus of code. A variable always refers to its top-level environment. It's good to understand it in relation to dynamic scope.

Evan Meagher
A: 

take a look at this description

akf
+5  A: 

Scope defines the area, where functions, variables and such are available. The availability of a variable for example is defined within its the context, let's say the function, file, or object, they are defined in. We usually call these local variables.

The lexical part means that you can derive the scope from reading the source code.

Lexical scope is also known as static scope.

Dynamic scope defines global variables that can be called or referenced from anywhere after being defined. Sometimes they are called global variables, even though global variables in most programmin languages are of lexical scope. This means, it can be derived from reading the code that the variable is available in this context. Maybe one has to follow a uses or includes clause to find the instatiation or definition, but the code/compiler knows about the variable in this place.

In dynamic scoping, by contrast, you search in the local function first, then you search in the function that called the local function, then you search in the function that called that function, and so on, up the call stack. "Dynamic" refers to change, in that the call stack can be different every time a given function is called, and so the function might hit different variables depending on where it is called from. (see here)

To see an interesting example for dynamic scope see here.

For further details see here and here.

Some examples in Delphi/Object Pascal

Delphi has lexical scope.

unit Main;
uses aUnit;  // makes available all variables in interface section of aUnit

interface

  var aGlobal: string; // global in the scope of all units that use Main;
  type 
    TmyClass = class
      strict private aPrivateVar: Integer; // only known by objects of this class type
                                    // lexical: within class definition, 
                                    // reserved word private   
      public aPublicVar: double;    // known to everyboday that has access to a 
                                    // object of this class type
    end;

implementation

  var aLocalGlobal: string; // known to all functions following 
                            // the definition in this unit    

end.

The closest Delphi gets to dynamic scope is the RegisterClass()/GetClass() function pair. For its use see here.

Let's say that the time RegisterClass([TmyClass]) is called to register a certain class cannot be predicted by reading the code (it gets called in a button click method called by the user), code calling GetClass('TmyClass') will get a result or not. The call to RegisterClass() does not have to be in the lexical scope of the unit using GetClass();

Another possibility for dynamic scope are anonymous methods (closures) in Delphi 2009, as they know the variables of their calling function. It does not follow the calling path from there recursively and therefore is not fully dynamic.

Ralph Rickenbach
Actually private is accessable in the whole unit where the class is defined. This is why "Strict private" was introduced in D2006.
Marco van de Voort
Thanks, Marco. Corrected.
Ralph Rickenbach
+1 for plain language (as opposed to both complicated language and examples without much description)
Lord Torgamus
+22  A: 

I understand them through examples :)

Static or Lexical Scope, in C-like syntax ::

void fun()
{
    int x = 5;

    void fun2()
    {
     printf("%d", x);
    }
}

every inner level can access its outer levels.

there is another way, called Dynamic Scope used by first implementation of Lisp, again in C-like Syntax ::

void fun()
{
    printf("%d", x);
}

void dummy1()
{
    int x = 5;

    fun();
}

void dummy2()
{
    int x = 10;

    fun();
}

here fun can either access x in dummy1 or dummy2, or any x in any function that call fun with x declared in it.

dummy1();

will print 5

dummy2();

will print 10

the first one is called static because it can be deduced at compile-time, the second is called dynamic because the the outer scope is dynamic and depends on the chain call of the functions.

I find static scoping easier for the eye. Most languages went this way eventually even Lisp (can do both, right?). Dynamic scoping is like passing references of all variables to the called function. An example of why the compiler can not deduce the outer dynamic scope of a function, consider our last example, if we write something like this ::

if(/* some condition */)
    dummy1();
else
    dummy2();

the call chain depends on a run time condition. If it is true, then the call chain looks like ::

dummy1 --> fun()

If the condition is false ::

dummy2 --> fun()

The outer scope of fun in both cases is the caller plus the caller of the caller and so on.

Just to mention that C language does not allow nested functions nor dynamic scoping.

AraK
+1 for easy to understand examples.
Javier Badia
A: 

Here is an explanation in the case of R.

Tal Galili
A: 

Lets try the shortest possible definition:

Lexical Scoping (aka Closure) defines how variable names are resolved in nested functions: inner functions contain the scope of parent functions even if the parent function has returned.

That's all there is to it! To help myself understand what this means, I wrote an in depth blog post about function scope and lexical scoping in JavaScript which can be found here. Maybe this could serve someone else too.

Pierre Spring