Friday, January 6, 2012

static scoping(lexical) vs dynamic scoping

  • ChatGPT

Static Scoping vs. Dynamic Scoping

Static Scoping (Lexical Scoping) and Dynamic Scoping are two different methods used to determine the scope and binding of variables in programming languages. Here's a detailed explanation with examples:


1. Static Scoping (Lexical Scoping)

Definition: In static scoping, the scope of a variable is determined by its position in the source code. The variable's binding is fixed at compile-time based on the program's structure.

Characteristics:

  • Variable references are resolved based on the program's text structure.
  • The scope of a variable is determined by the block or function where it is defined.
  • A variable can be accessed only within the block or function where it is declared, and this relationship does not change regardless of the program's execution.

int globalVar = 1;

void foo() {
    int localVar = 2;
    print(globalVar); // prints 1
    print(localVar);  // prints 2
}

void bar() {
    print(globalVar); // prints 1
    // print(localVar); // Error: localVar not defined in this scope
}

int main() {
    foo();
    bar();
}


In this example:

  • globalVar is accessible throughout the program because it is declared in the global scope.
  • localVar is only accessible within foo() because it is declared within foo()'s local scope.

2. Dynamic Scoping

Definition: In dynamic scoping, the scope of a variable is determined by the call stack at runtime. The binding of a variable is based on the calling sequence of functions, not the structure of the code.


Characteristics:

  • Variable references are resolved based on the execution call stack.
  • The scope of a variable is determined dynamically, depending on the function call hierarchy at runtime.
  • Variables are accessible in functions that are called within the context where the variable was defined.
int globalVar = 1;

void foo() {
    int localVar = 2;
    print(globalVar); // prints 1 (globalVar is accessible)
    print(localVar);  // prints 2
}

void bar() {
    print(globalVar); // prints 2 (globalVar is from foo's scope in dynamic scoping)
}

int main() {
    foo();
    bar();
}

In this example:

  • globalVar is set to 1 globally.
  • When bar() is called after foo(), dynamic scoping would cause globalVar to print 2 if bar() could access globalVar set in foo().

Comparison

  • Static Scoping:

    • Variable scope is determined by the position of the variable in the source code.
    • More predictable and easier to understand because the scope does not change dynamically.
    • Example languages: C, Java, Python (mostly).
  • Dynamic Scoping:

    • Variable scope is determined by the runtime call stack.
    • Less predictable because the scope can change depending on function calls.
    • Example languages: Some Lisp dialects (like older versions of Emacs Lisp).
Summary: Static scoping relies on the structure of the code to determine variable scope, making it more predictable. Dynamic scoping relies on the call stack and the sequence of function calls, making it more flexible but potentially less predictable.
  • ChatGPT

To determine the output of the given pseudocode under both static (lexical) scoping and dynamic scoping, we need to understand how variable scopes are managed in each case.

Pseudocode Analysis:

int i
main ()
{
    i = 3
    S ()
    R ()
}

void S ()
{
    print i // prints the value of i on the current line of output
    print " " // prints a blank space on the current line of output
}

void R ()
{
    int i
    i = 2
    S ()
}


Static Scoping (Lexical Scoping)

In static scoping, the scope of a variable is determined by its physical location in the code.

  1. In main: i is set to 3. The function S() is called first.

    • S() prints the value of i from main, which is 3.
    • S() then prints a blank space.
  2. In R: A new local i is created and set to 2.

    • When S() is called within R(), it refers to the i from main due to static scoping.
    • So S() prints the i from main, which is still 3, and then a blank space.

Static Scoping Output:

3 (from main)  // `S()` prints `3` from `main`

(Blank space)  // `S()` prints a space

3 (from main)  // `S()` prints `3` from `main` again in `R()`


Output: 3 3


Dynamic Scoping

In dynamic scoping, the scope of a variable is determined by the call stack at runtime.

  1. In main: i is set to 3. The function S() is called.

    • S() prints the i from main, which is 3.
    • S() then prints a blank space.
  2. In R: A new local i is created and set to 2.

    • When S() is called within R(), it will print the i from R(), which is 2, because dynamic scoping looks up the variable from the most recent context in the call stack.

Dynamic Scoping Output:


3 (from main)  // `S()` prints `3` from `main`

(Blank space)  // `S()` prints a space

2 (from `R`)   // `S()` prints `2` from `R()`


Output: 3 2

Summary:

  • Static Scoping Output: 3 3
  • Dynamic Scoping Output: 3 2

So the answers for the options provided are:

  • Static Scoping: Option D) 3 3 3 2
  • Dynamic Scoping: Option C) 3 3 2 2

  • Gemini

Static vs. Dynamic Scoping: Understanding the Output
Understanding Static and Dynamic Scoping

Before we analyze the output, let's clarify the two scoping methods:

    Static Scoping (Lexical Scoping): The scope of a variable is determined by its position in the code, not by the calling function. This is the most common scoping method in modern programming languages.
    Dynamic Scoping: The scope of a variable is determined by the calling sequence of functions at runtime.

Analyzing the Pseudocode

Given Pseudocode:

int i
main ()
{
i = 3
S ()
R ()
}
void S ()
{
print i // prints the value of i on the current line of output
print " " // prints a blank space on the current line of output
}
void R ()
{
int i
i = 2
S  

 ()
}

Static Scoping:

    The i in function S refers to the global i which is initialized to 3.
    The i in function R is a local variable and hides the global i.
    The output will be: 3 3 2

Dynamic Scoping:

    The i in function S will refer to the most recently defined i.
    When S is called from R, the i in R is the most recent, so it will print 2.
    The output will be: 3 2 3

Answer:

    Static Scoping: (C) 3 3 2 3
    Dynamic Scoping: (B) 3 3 2 2

Explanation:

    The first 3 is printed from the main function.
    The second 3 is printed from function S, referring to the global i in static scoping, and the local i in R in dynamic scoping.
    The 2 is printed from function R.
    The last 3 is printed from function S again, referring to the global i in static scoping.

This example demonstrates the difference between static and dynamic scoping. Static scoping is more predictable as it relies on the code structure, while dynamic scoping depends on the function call stack at runtime, which can lead to unexpected results.

Statically typed languages check types at compile time
The programmer ensures that parameter types are specified and the compiler ensures the programmers wishes will be followed.

In a dynamically typed language (like ruby, javascript, etc), types are not checked until execution
If an expression evaluates, then the type-checking worked. If not, it blows up to your error handling or the user

Static Scoping – Variables can be bound at compile time without regards to calling code.

Dynamic Scoping – Variable binding (context) can only be determined at the moment code is executed.



Reference:
http://hoolihan.net/blog-tim/2009/02/17/static-vs-dynamic-scope/
http://en.wikipedia.org/wiki/Scope_%28programming%29




  • First, Lexical Scope (also called Static 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 xdeclared 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 outer scope is dynamic and depends on the chain call of the functions.
Dynamic scoping is like passing references of all variables to the called function.
stackoverflow

No comments:

Post a Comment