What is Lexical scope and lexical closures in Dart?

Lexical scoped variable/closure etc can only be accessed within the block of code in which it is defined.

Understanding lexical scoping

In a programming language, an item’s lexical scope is the place in which it was created. The scope of the variable is determined by the program’s textual (lexical) structure. Variables can be declared within a specific scope and are only accessible within that region.

In other words, lexical scope refers to the ability of a function scope to access variables from the parent scope. When there is lexical scope, the innermost, inner and outermost functions may access all variables from their parent scopes all the way up to the global scope. However, no scope may access the variables from the functions defined inside it. Thus, the child function is lexically bound to the parent function.

Dart is a lexically scoped language. With lexical scoping, descendant scopes will access the most recently declared variable of the same name. The innermost scope is searched first, followed by a search outward through other enclosing scopes.

String topLevel = 'Hello';

void firstFunction() {
  String secondLevel = 'Hi';
  print(topLevel);
  nestedFunction() {
    String thirdLevel = 'Howdy';
    print(topLevel);
    print(secondLevel);
    innerNestedFunction() {
      print(topLevel);
      print(secondLevel);
      print(thirdLevel);
    }
  }
  print(thirdLeve);
}

void main() => firstFunction();

This is a valid function, until the last print statement. The third-level variable is defined outside the scope of the nested function, because scope is limited to its own block or the blocks above it. (Again, a block is defined by curly braces.)

Example 2:

Let us consider one more example, a bit more complicated one to understand the lexical scoping in a better way.

Consider the example shown below −

void main() {
   String language = "Dart";
   void outerFunction() {
      String level = 'one';
      String ex = "scope";
      void innerFunction() {
         Map level = {'count': "Two"};
         print('ex: $ex, level: $level');
         print('Language: $language');
      }
      innerFunction();
      print('ex: $ex, level: $level');
   }
   outerFunction();
}

There are multiple scopes in the above example, for instance, we have a scope as soon as we start the main function, after that, another inner scope opens as soon as we enter the outerFunction() and an even more scope as we move inside the innerFunction().

Output

ex: scope, level: {count: Two}
Language: Dart
ex: scope, level: one

Lexical Closures:

In programming languages, a lexical closure, also called closure or function closure, is a way of implementing lexical scope name binding in a function. It is a function object that has access to variables in its lexical scope, even when the function is used outside the scope.

Function flutterfever(num add) {
return (num i) => add + i;
}

void main() {
// Create a function that adds 2.
var flutter1= flutterfever(2);

// Create a function that adds 4.
var flutter2= flutterfever(4);

print(flutter1(3));
print(flutter2(3));
}
output://
5
7
Note:
Functions can close over variables defined in surrounding scopes. In the following example,
flutterfever() captures the variable addBy. Wherever the returned function goes, it remembers
"add" variable.
lexical scope in dart

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More