What are lexical scope and dynamic scope and what are their main differences?

38

What are lexical scope and dynamic scope and what are their main differences?

    
asked by Carlos Cinelli 15.04.2014 в 18:21
source

3 answers

26

The scope of a variable determines in which parts of the program that variable can be accessed. The simplest (and best known) example of scope is the global scope and local scope :

var x = 10;       // Escopo global - pode ser acessada em qualquer lugar, inclusive em f
function f() {
    var y = 20;   // Escopo local - pode ser acessada somente dentro de f
}

Modern programming languages support the concept of nested structures . That is, a code structure contained in another code structure (rather than at the top-level):

class Foo {
    int x;
    void bar() { 
        int y;
    }

    class Baz { ... }
}

It is at this moment that a doubt arises: do the "inside" structures have access to "outside" structures or not? Each language implements this in a way.

var x = 0;

function foo() {
    var x = 10;
    return function() {
        return x;
    }
}
var bar = foo();

function baz() {
    var x = 20;
    bar();
}
baz(); // O que é retornado?

Dynamic Scope

In dynamic-scoped languages, functions can access any variable present in the execution stack >. In the example above, as baz set x = 20 and then called bar , bar can access that x , and its value will be 20 .

Thistypeofscopeisdeprecated,sinceitisdifficulttokeeptrackofwhichvariablesarevisibleatanygiventime,aswellasharmingtheencapsulation(i.e.anyfunctioncallcouldatfirstmodifyanylocalcallingfunctionvariable).Thevastmajorityofmodernlanguagesdonotusethiskindofscope.

LexicalScope

Inlexical-scopedlanguages,whatcountsisthe"grammatical" structure of the program, that is, if in the source code one structure is nested in another, the one inside can access variables in the outside. In the example, bar is nested to foo , so it can access its x variable - even though foo has already returned and is no longer in the stack.

Theabovefigureisasimplificationofthe Abstract Synthetic Tree > ( Abstract Syntax Tree - AST) of the sample code. Notice that - in a well-coded code - the level of each instruction in that tree corresponds to its identation level in the source code. In the anonymous function nested to foo , the variable x corresponds to the closest definition in the scopes hierarchy (in green).

The anonymous function does not define variables, foo defines a x , and the top-level defines x , foo , bar and baz . Since% w / w% of% w / w is "closer" than% w / w of top-level , it is who is accessible in the anonymous function. The x of foo is not considered - since it is not part of the lexical hierarchy - even though it is the caller anonymous function (saved in x ).

That is, you can precisely determine which variables are accessible by simple reading source code , without having to mentally visualize who calls what and in what order.

This type of scope is most commonly used in modern languages. In those that allow nested functions (as in the example above, in JavaScript), the access of an internal function to the local variables of the external function is called closure (cloister) , and requires a "spaghetti stack " to be possible. Others, which do not allow nested functions (such as Java), still use lexical scope to determine that inner classes have access to the fields of the outer classes (in the second example of this response, class x has access to the baz field of the bar class).

    
answered by 20.04.2014 / 03:34
source
15

From the text of Wikipedia ( Lexical scope vs dynamic scope ):

What is it?

In Computer Science, scope is a bounding context to which values and expressions are associated. Programming languages have several types of scopes. The type of scope will determine what types of entities it can contain and how they are affected, in other words, its semantics. Typically, the scope is used to define the degree of information concealment, ie visibility and accessibility to variables in different parts of the program.

Lexical scope vs. Dynamic scope

The lexical (or static ) scope was introduced by the ALGOL 60 language. Scope is so named because it can be determined statically, ie before execution.

The lexical scope defines the scope in terms of the lexical structure of the program. With lexical scope, a name always refers to its lexical (more or less) local environment. This is a property of program text and is made independent of the call stack at runtime by the implementation of the language. That is, the lexical scope of a statement is the part of the text of the program, where the use of the identifier is a reference to that particular statement of the identifier.

Because this correspondence only requires analysis of the text of the static program, this type of scope delimitation is also called a static scope.

Static scope is standard in all languages based on ALGOL, such as Pascal, ADA and C, because it allows the programmer to elaborate reasoning on values, parameters and object references (ie variables, constants, functions etc.). ), such as simple name substitutions. This makes it much easier to make the modular code and to reason about it, since the local naming structure can be understood in isolation. Because of the understanding that static scoping makes programming more reliable, there is a tendency to reject dynamic scoping.

In contrast, dynamic scope forces the programmer to anticipate all possible dynamic contexts in which module code can be invoked.

With dynamic scope, each identifier has a global stack of bindings. Entering a local variable with the name of x stacks a binding on the global heap x in> which may be empty ), which will be unstacked when the control flow leaves the scope. Evaluating x in any context always produces the top binding.

In other words, a global identifier refers to the identifier associated with the most recent environment. Note that this can not be done at compile time, because the binding stack only exists at runtime, which is why this type of delimitation is called dynamic scope .

Consider this example made in Pascal:

program A;

var I:integer; // Variável global
    K:char; --------------------------
                                      |  
    procedure B;                      |  
    var K:real; -----------------------
        L:integer;                    |
                                      | 
        procedure C;                  |
        var M:real;                   | 
        begin                         |
         (*escopo A+B+C*)             |
        end;                          |
                                      |
        procedure D;                  |
        var K:integer; ----------------
        begin
         (*escopo A+B+D*)
        end;

    begin
     (*escopo A+B*)
    end;
begin
 (*escopo A*)
end.

The variable I is visible at all points, because it is never overturned by another variable of the same name. The variable char K is visible only in the main program , because it is hidden by the variable K B , C , and D only.

The L variable is also visible only in procedures B , C and D , but not hides any other variable. The M variable is visible only in the C process and therefore is not accessible either from the B procedure, > D , or the main program.

In addition, the C and D procedures are only visible in procedures B , C , and D ( C and D are procedures with the same static parent and therefore see each other ), and therefore can not be called from the main program. >

In addition, there could still be another C procedure declared in the program, out of process B . The exact place in the program where C is called then determines which C procedure is called, and this is precisely analogous to the scope of variables.     

answered by 15.04.2014 в 18:37
8

What does a variable scope mean?

The scope of a variable represents the area of the program where it is visible.

  • A variable is visible in a command if it can be referenced in that command.
  • A variable is local to a program unit if it is declared in it.
  • A variable is non-local to a program unit if it is visible but has not been declared in it.

Binding the data type of a variable can be specified in a static lexical or dynamic form.

Static scope (lexicon)

In programming languages with static scope (or lexicon), the scope is determined through the textual structure of the program. Using static scope (lexicon), the binding of a name in the environment is determined by the following algorithm:

  • If the name was declared in the execution block, that binding will be used. Otherwise,
  • If the name was not declared in the running block, it should be the blocks that surround it, from the immediate surroundings to the further. If all the surrounding blocks have been checked and the statement not found,
  • If the name is in the global environment, that binding will be used, otherwise there is no binding for that name in the environment.
  • It can be informally stated that the code snippet where a name is visible is the block where it was declared and all nested blocks within it, and for this reason it is often used "lexical scope" strong> as synonymous with "static scope" .

    Dynamic Scope

    In dynamic-scoped programming languages, the scope is determined through the program execution line, and therefore depends on the order of execution of the routines. Using dynamic scope, the valid binding for a name is the one most recently created during program execution, based on program unit call sequences, not on textual layout.

    Example

    x: integer
    procedure print_x()
    begin
        print(x);
    end
    procedure p2
    x: integer;
    begin
        x= 4;
        print_x();
    end
    begin
        x = 3;
        p2();
    end
    

    If the scope is dynamic, the program prints 4. If the scope is static, the program prints 3.

    Source: link

        
    answered by 15.04.2014 в 18:45