Lecture 2: Names, Bindings, and Scopes
(Sebesta Chapter 5)




                              TI1220 2012-2013
                      Concepts of Programming Languages

                              Eelco Visser / TU Delft
Outline
  Messages from the lab
  Names
  Variables
  Binding & binding time
  Scope
  Demo: Spoofax name binding language
Messages from the Lab
“There were not a lot of students at the lab. This of
course is ok for the first week, but students should
be told that they stand no chance of passing
the graded assignments without the tutorials, or the
exam without the graded assignments.”
“There are too many
rooms for the number
of students. Could you
mention that they
should start filling the
rooms from the top, one
by one and then move
down as they fill up.
Room 0.010 is quite
unhandy for labs because
of the cubicles.”
“WebLab of course does not work
properly in Internet Explorer, we
should tell students that.”
Email addresses
  e.visser@tudelft.nl: for personal questions about
  grades and such
  ti1220.ewi@gmail.com: for general questions about
  the lab
  ti1220.ewi+lab@gmail.com: for questions about the
  lab (addresses all student assistants)

Policies
    Our first response: did you ask this question at the
    lab?
    We’re closed in the weekend (in principle)
    Please report problems with WebLab immediately
Names (Identifiers)
Name Forms




        [a-zA-Z][a-zA-Z0-9_]* -> ID %% typical

"$"     [a-zA-Z][a-zA-Z0-9_]* -> PhpID

[$@%][a-zA-Z][a-zA-Z0-9_]* -> PerlID

"@"     [a-zA-Z][a-zA-Z0-9_]* -> RubyInstanceVar
"@@"    [a-zA-Z][a-zA-Z0-9_]* -> RubyClassVar
Case Sensitive or Case Insensitive?




 foobar == FooBar == FOOBAR ?




 C-based languages: case sensitive
 C convention: variable names only lower case letters
 Pascal: case insensitive
 Java convention: CamelCase instead of under_scores
Special Words

 keyword: identifier with special           type
   meaning in certain contexts                    Integer Apple
                                                  Integer = 4

                                         name     Integer Real
package example;                                  Real Integer
class User {
    private String name;
    public String get_name {
                                                         Fortran
        return name;
    }
}                              Java

                                 reserved word: special word
                                  that cannot be used as a name
Variables
A program variable is an abstraction of a
computer memory cell or collection of cells




machine language: absolute
 numeric address of data

                             assembly language:
                               names for data
The attributes of a variable:
  Name
  Address
  Value
  Type
  Lifetime
  Scope
the address of a variable is the machine
memory address with which it is associated



     def gcd(x: Long, y: Long): Long =
       if (y == 0) x else gcd(y, x % y)


    each call to gcd creates new instances of x and y




      alias: multiple variables accessing same
       memory location (more next week)
Type & Value




 the type of a variable determines the range of
   values the variable can store and the set of
operations that are defined for values of the type


 the value of a variable is the contents of the
memory cell or cells associated with the variable
Binding & Binding Time
a binding is an association between
     an attribute and an entity



Example bindings
  variable to type
  variable to value
  function call to function definition
Binding Variable Identifiers


                        binding
defining occurrence


        val msg = "Hello, " + "world!"

        println(msg)

                          applied occurrence


                val variables cannot be rebound
Binding Variable Identifiers


                        binding
defining occurrence


    var greeting = "Hello, world!"

    greeting = "Leave me alone, world!"



rebinding
                 var variables can be rebound
Binding Function Identifiers



                                       binding
defining occurrence


     def widthOfLength(s: String) =
       s.length.toString.length

     val maxWidth = widthOfLength(longestLine)


                       applied occurrence
Binding Class Identifiers



                                  binding
defining occurrence


  class ChecksumAccumulator {
    var sum = 0
  }

  var acc = new ChecksumAccumulator
  var csa = new ChecksumAccumulator

  acc.sum = 3
  csa = acc           applied occurrence
Rebinding vs Mutation




class ChecksumAccumulator {
  var sum = 0
}                    binding
var acc = new ChecksumAccumulator
var csa = new ChecksumAccumulator
                     mutation
acc.sum = 3
csa = acc

         rebinding
Namespaces



    object foo {
      val foo : Int = 0
      def foo(x : Int) = x + 1
    }

    object bar {
      def bar() = foo.foo(foo.foo)
    }



variables, functions, objects are in separate name spaces
the time at which a binding takes
 places is called binding time



Example binding times
  language design time
  language implementation time
  compile time
  load time
  link time
  run time
Type int in C
        bound to range of possible values
        (e.g. 32 bit words)
        at language implementation time


Variable in Java
  bound to data type
  at compile time
                           Variable in JavaScript
                             bound to data type
                             at run time
Symbolic Constants (C)
                                                                0   -17.8
                                                               20    -6.7
                                                               40     4.4
                                                               60    15.6
#include <stdio.h>                                             80    26.7
#define LOWER 0 /* lower limit of table */                    100    37.8
                                                              120    48.9
#define UPPER 300 /* upper limit */                           140    60.0
#define STEP 20 /* step size */                               160    71.1
                                                              180    82.2
                                                              200    93.3
/* print Fahrenheit-Celsius table */                          220   104.4
                                                              240   115.6
main() {                                                      260   126.7
	 int fahr;                                                   280   137.8
                                                              300   148.9
	 for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
	 	 printf("%3d %6.1fn", fahr, (5.0 / 9.0) * (fahr - 32));
}




compile-time binding of values
Typedefs (C)

typedef int Length;

Length len, maxlen;
                       compile-time binding of type name
Length *lengths[];

typedef struct tnode *Treeptr;
typedef struct tnode { /* the tree node: */
	 char *word; /* points to the text */
	 int count; /* number of occurrences */
	 struct tnode *left; /* left child */
	 struct tnode *right; /* right child */
} Treenode;

Treeptr talloc(void) {
	 return (Treeptr) malloc(sizeof(Treenode));
}
Function Definitions and Calls (Scala)



 def max(x: Int, y: Int): Int = {
   if (x > y) x else y
 }




                                    max(3, 5)




  function statically bound, argument values
   dynamically bound to formal parameters
Recursion (Scala)


def gcd(x: Long, y: Long): Long =
  if (y == 0) x else gcd(y, x % y)




                         def fib(x: Long): Long =
                           if (x <= 0) 1
                           else if (x == 1) 1
                           else fib(x - 1) + fib(x - 2)




    recursion requires dynamic binding of variables
a binding is static when it occurs
   before run time and remains
 unchanged throughout execution



                a binding is dynamic if it first
            occurs during run time or can change
             in the course of program execution
Function Expressions (JS)
// This function expression defines a function that squares its argument.
// Note that we assign it to a variable
var square = function(x) {
	 return x * x;
}
var q = square(10);
function square(x) { return x * x; }

// Function expressions can include names, which is useful for recursion.
var f = function fact(x) {
	 if (x <= 1)
	 	 return 1;
	 else
	 	 return x * fact(x - 1);
};

// Function expressions can also be used as arguments to other functions:
data.sort(function(a, b) { return a - b; });

// Function expressions are sometimes defined and immediately invoked:
var tensquared = (function(x) { return x * x; }(10));
var square = function foo(x) {
! return x * x;
};

var z = square;

var r = z(10);

console.log(r);

function squareF(x) { return x * x; }

var q = squareF(10);

console.log(q);

var sq = squareF;

console.log("sq: " + sq);

console.log("sq(12): " + sq(12));

console.log(foo(3));
Type binding of variable

  How specified? explicit vs implicit

  When bound? static vs dynamic
an explicit declaration is a
statement in a program that lists
variable names and specifies that
    they are a particular type


            an implicit declaration is a means
              of associating variables with types
             through default conventions, rather
                 than declaration statements
Fortran: static types, implicitly declared

In implicit typing, all constants, variables
and arrays beginning with the letters I, J,
K, L, M, or N are automatically taken to
be of type INTEGER.

Constants, variables and arrays beginning
with all other letters are assumed to be
REAL.

Thus, with implicit typing, the variable
COUNT is REAL whilst the variable
KOUNT is an INTEGER.

Implicit typing can be overridden with
explicit type declaration.


                             source: http://www.obliquity.com/computer/fortran/datatype.html
Perl: implicitly declared with
                        different name spaces




$a : scalar (string or numeric value)
#a : array
%a : hash structure
Variables and Expressions (C)

#include <stdio.h>
                                      static types, explicitly declared

/* print Fahrenheit-Celsius table for fahr = 0, 20, ..., 300 */
int main() {
	 int fahr, celsius;
	 int lower, upper, step;
	 lower = 0; /* lower limit of temperature scale */
	 upper = 300; /* upper limit */
	 step = 20; /* step size */
	 fahr = lower;
	 while (fahr <= upper) {
	 	 celsius = 5 * (fahr - 32) / 9;
	 	 printf("%dt%dn", fahr, celsius);
	 	 fahr = fahr + step;
	 }
  return 0;
}
type inference: implicit type
  declaration using context


                   Languages with type inference
                     ML
                     Haskell
                     OCaml
                     F#
                     Scala
                     Visual BASIC 9.0+
                     Go
Scala: static types, inferred from context




def widthOfLength(s: String) = s.length.toString.length

val lines = Source.fromFile(args(0)).getLines.toList

val longestLine = lines.reduceLeft(
  (a, b) => if (a.length > b.length) a else b
)

val maxWidth = widthOfLength(longestLine)
dynamic type binding: variable is
        bound to type when it is assigned a value



Languages with dynamic type binding
  Ruby
  JavaScript
  Lisp
  Scheme
  Python
  PHP
Variable Declaration (JS)


var i;
var sum;

var i, sum;

var message = "hello";
var i = 0, j = 0, k = 0;

for(var i = 0; i < 10; i++) console.log(i);
for(var i = 0, j=10; i < 10; i++,j--)
console.log(i*j);
for(var p in o) console.log(p);

var i = 10;
i = "ten";
JavaScript: dynamic type binding


list = [10.2, 3.5];
list = 47;



      Ruby

        all variables are references

        all data are objects (there is only one type)

        any variable can reference an object
Disadvantages of dynamic typing

  programs are less reliable: types
  not checked by compiler

  cost of checking types at run time
next week: storage bindings and lifetime
Scope
the scope of a variable is the range of
statements in which the variable is visible




 a variable is local in a program unit or
        block if it is declared there

the non-local variables are those that
are visible but not declared in a program
                    unit
class ChecksumAccumulator {
  private var sum = 0
  def add(b: Byte): Unit = {
    sum += b
  }
  def checksum(): Int = {
    return ~(sum & 0xFF) + 1
  }
}




                            Scala: variable sum is non-local
                           for methods add and checksum
static scoping: scope of variable can
be statically determined

  nested scopes: Ada, JavaScript, Scheme,
  Scala, F#, Python

  non-nested scopes: C-based languages
function big() {
  function sub1() {
	 var x = 7;
	 sub2();
  }
  function sub2() {
    var y = x;
  }
  var x = 3;
  sub1();
}



             static scoping in JavaScript
Variable Scope (JS)


var scope = "global";
// Declare a global variable
function checkscope() {
	 var scope = "local";
   // Declare a local variable with the same name
	 return scope;
   // Return the local value, not the global one
}
checkscope()
// => "local"
Variable Scope (JS)



scope = "global";            //   Declare a global variable, even without var.
function checkscope2() {
	 scope = "local";           //   Oops! We just changed the global variable.
	 myscope = "local";         //   This implicitly declares a new global variable.
	 return [ scope, myscope ]; //   Return two values.
}
checkscope2()                //   => ["local", "local"]: has side effects!

scope                        // => "local": global variable has changed.
myscope                      // => "local": global namespace cluttered up.
Nested Functions (JS)

              function hypotenuse(a, b) {
              	 function square(x) {
              	 	 return x * x;
              	 }
              	 return Math.sqrt(square(a) + square(b));
              }



var scope = "global scope";       // A global variable
function checkscope() {
	 var scope = "local scope";      // A local variable
	 function nested() {
	 	 var scope = "nested scope";   // A nested scope of local variables
	 	 return scope;                 // Return the value in scope here
	 }
	 return nested();
}
checkscope()                      // => "nested scope"
block: sections in which allocation of storage
            for variables is allocated


if (list[i] < list[j]) {
  int temp;                       void sub() {
  temp = list[i];                   int count;
  list[i] = list[j];                ...
  list[j] = temp;                   while (...) {
}                                     int count;
                                      count++;
                                      ...
                                    }
                                    ...
 Java and C# do not allow         }
   shadowing of variables
def printMultiTable() {
  var i = 1
  // only i in scope here                      block scope in Scala:
  while (i <= 10) {
    var j = 1                                  order of declaration
    // both i and j in scope here
    while (j <= 10) {
                                                     matters
      val prod = (i * j).toString
      // i, j, and prod in scope here
      var k = prod.length
      // i, j, prod, and k in scope here
      while (k < 4) {
        print(" ")
        k += 1
      }
      print(prod)
      j += 1
    }
    // i and j still in scope; prod and k out of scope
    println()
    i += 1
  }
  // i still in scope; j, prod, and k out of scope
}
Function Scope and Hoisting (JS)



function test(o) {
	 var i = 0;                        // i is defined throughout function
	 if (typeof o == "object") {
	 	 var j = 0;                      // j is defined everywhere, not just block
	 	 for ( var k = 0; k < 10; k++) { // k is defined everywhere, not just loop
	 	 	 console.log(k);               // print numbers 0 through 9
	 	 }
	 	 console.log(k);                 // k is still defined: prints 10
	 }
	 console.log(j);                   // j is defined, but may not be initialized
}




  JavaScript does not
    have block scope!
Use Before Declaration

var scope = "global";
function f() {
	 console.log(scope); // Prints "undefined", not "global"
	 var scope = "local"; // Variable initialized here, but defined everywhere
	 console.log(scope); // Prints "local"
}




function f() {
	 var scope; // Local variable is declared at the top of the function
	 console.log(scope); // It exists here, but still has "undefined" value
	 scope = "local";    // Now we initialize it and give it a value
	 console.log(scope); // And here it has the value we expect
}
let
   val name1 = expression1
   ...
   val namen = expressionn
in
   expression
end;




                             let
                                val top = a + b
                                val bottom = c - d
                             in
                                top / bottom
                             end;
let binding in ML
Describing Static Name
    Binding Rules
module names

imports
	
                                  NaBL: Spoofax Name Binding Language
	   include/Delft
	
namespaces
	                                                   module blog
	   Module
	   Entity                                          imports user
	   Property
	                                                   entity BlogPosting {
rules                                                 name   : String
                                                      poster : User
	   Module(x, _) :
                                                      body   : String
	   	   defines Module x
	   	   scopes Entity                                 blog   : Blog
	   	                                                 title : String
	   Entity(x, _) :                                  }
	   	   defines Entity x   of type Type(x)
	   	   scopes Property                             entity Blog {
	   	                                                 title : String
	   Property(x, t) :
                                                      author : Blog
	   	   defines Property   x of type t
	   	                                               }
	   Type(x) :
	   	   refers to Entity   x                        entity User {
	   	   refers to Entity   "String"                   name : String
	   	   refers to Entity   "Int"                    }
Reading & Programming in Week 2

Reading: Sebesta

   Chapter 5: Names, Bindings, Scopes


WebLab:
  C tutorial
   JavaScript tutorial
   More Scala tutorial
   Grammars and regular expressions



                    Week 3: Dynamic Binding & Storage

Ti1220 Lecture 2: Names, Bindings, and Scopes

  • 1.
    Lecture 2: Names,Bindings, and Scopes (Sebesta Chapter 5) TI1220 2012-2013 Concepts of Programming Languages Eelco Visser / TU Delft
  • 2.
    Outline Messagesfrom the lab Names Variables Binding & binding time Scope Demo: Spoofax name binding language
  • 3.
  • 4.
    “There were not alot of students at the lab. This of course is ok for the first week, but students should be told that they stand no chance of passing the graded assignments without the tutorials, or the exam without the graded assignments.”
  • 5.
    “There are toomany rooms for the number of students. Could you mention that they should start filling the rooms from the top, one by one and then move down as they fill up. Room 0.010 is quite unhandy for labs because of the cubicles.”
  • 6.
    “WebLab of coursedoes not work properly in Internet Explorer, we should tell students that.”
  • 7.
    Email addresses e.visser@tudelft.nl: for personal questions about grades and such ti1220.ewi@gmail.com: for general questions about the lab ti1220.ewi+lab@gmail.com: for questions about the lab (addresses all student assistants) Policies Our first response: did you ask this question at the lab? We’re closed in the weekend (in principle) Please report problems with WebLab immediately
  • 8.
  • 9.
    Name Forms [a-zA-Z][a-zA-Z0-9_]* -> ID %% typical "$" [a-zA-Z][a-zA-Z0-9_]* -> PhpID [$@%][a-zA-Z][a-zA-Z0-9_]* -> PerlID "@" [a-zA-Z][a-zA-Z0-9_]* -> RubyInstanceVar "@@" [a-zA-Z][a-zA-Z0-9_]* -> RubyClassVar
  • 10.
    Case Sensitive orCase Insensitive? foobar == FooBar == FOOBAR ? C-based languages: case sensitive C convention: variable names only lower case letters Pascal: case insensitive Java convention: CamelCase instead of under_scores
  • 11.
    Special Words keyword:identifier with special type meaning in certain contexts Integer Apple Integer = 4 name Integer Real package example; Real Integer class User { private String name; public String get_name { Fortran return name; } } Java reserved word: special word that cannot be used as a name
  • 12.
  • 13.
    A program variableis an abstraction of a computer memory cell or collection of cells machine language: absolute numeric address of data assembly language: names for data
  • 14.
    The attributes ofa variable: Name Address Value Type Lifetime Scope
  • 15.
    the address ofa variable is the machine memory address with which it is associated def gcd(x: Long, y: Long): Long = if (y == 0) x else gcd(y, x % y) each call to gcd creates new instances of x and y alias: multiple variables accessing same memory location (more next week)
  • 16.
    Type & Value the type of a variable determines the range of values the variable can store and the set of operations that are defined for values of the type the value of a variable is the contents of the memory cell or cells associated with the variable
  • 17.
  • 18.
    a binding isan association between an attribute and an entity Example bindings variable to type variable to value function call to function definition
  • 19.
    Binding Variable Identifiers binding defining occurrence val msg = "Hello, " + "world!" println(msg) applied occurrence val variables cannot be rebound
  • 20.
    Binding Variable Identifiers binding defining occurrence var greeting = "Hello, world!" greeting = "Leave me alone, world!" rebinding var variables can be rebound
  • 21.
    Binding Function Identifiers binding defining occurrence def widthOfLength(s: String) = s.length.toString.length val maxWidth = widthOfLength(longestLine) applied occurrence
  • 22.
    Binding Class Identifiers binding defining occurrence class ChecksumAccumulator { var sum = 0 } var acc = new ChecksumAccumulator var csa = new ChecksumAccumulator acc.sum = 3 csa = acc applied occurrence
  • 23.
    Rebinding vs Mutation classChecksumAccumulator { var sum = 0 } binding var acc = new ChecksumAccumulator var csa = new ChecksumAccumulator mutation acc.sum = 3 csa = acc rebinding
  • 24.
    Namespaces object foo { val foo : Int = 0 def foo(x : Int) = x + 1 } object bar { def bar() = foo.foo(foo.foo) } variables, functions, objects are in separate name spaces
  • 25.
    the time atwhich a binding takes places is called binding time Example binding times language design time language implementation time compile time load time link time run time
  • 26.
    Type int inC bound to range of possible values (e.g. 32 bit words) at language implementation time Variable in Java bound to data type at compile time Variable in JavaScript bound to data type at run time
  • 27.
    Symbolic Constants (C) 0 -17.8 20 -6.7 40 4.4 60 15.6 #include <stdio.h> 80 26.7 #define LOWER 0 /* lower limit of table */ 100 37.8 120 48.9 #define UPPER 300 /* upper limit */ 140 60.0 #define STEP 20 /* step size */ 160 71.1 180 82.2 200 93.3 /* print Fahrenheit-Celsius table */ 220 104.4 240 115.6 main() { 260 126.7 int fahr; 280 137.8 300 148.9 for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP) printf("%3d %6.1fn", fahr, (5.0 / 9.0) * (fahr - 32)); } compile-time binding of values
  • 28.
    Typedefs (C) typedef intLength; Length len, maxlen; compile-time binding of type name Length *lengths[]; typedef struct tnode *Treeptr; typedef struct tnode { /* the tree node: */ char *word; /* points to the text */ int count; /* number of occurrences */ struct tnode *left; /* left child */ struct tnode *right; /* right child */ } Treenode; Treeptr talloc(void) { return (Treeptr) malloc(sizeof(Treenode)); }
  • 29.
    Function Definitions andCalls (Scala) def max(x: Int, y: Int): Int = { if (x > y) x else y } max(3, 5) function statically bound, argument values dynamically bound to formal parameters
  • 30.
    Recursion (Scala) def gcd(x:Long, y: Long): Long = if (y == 0) x else gcd(y, x % y) def fib(x: Long): Long = if (x <= 0) 1 else if (x == 1) 1 else fib(x - 1) + fib(x - 2) recursion requires dynamic binding of variables
  • 31.
    a binding isstatic when it occurs before run time and remains unchanged throughout execution a binding is dynamic if it first occurs during run time or can change in the course of program execution
  • 32.
    Function Expressions (JS) //This function expression defines a function that squares its argument. // Note that we assign it to a variable var square = function(x) { return x * x; } var q = square(10); function square(x) { return x * x; } // Function expressions can include names, which is useful for recursion. var f = function fact(x) { if (x <= 1) return 1; else return x * fact(x - 1); }; // Function expressions can also be used as arguments to other functions: data.sort(function(a, b) { return a - b; }); // Function expressions are sometimes defined and immediately invoked: var tensquared = (function(x) { return x * x; }(10));
  • 33.
    var square =function foo(x) { ! return x * x; }; var z = square; var r = z(10); console.log(r); function squareF(x) { return x * x; } var q = squareF(10); console.log(q); var sq = squareF; console.log("sq: " + sq); console.log("sq(12): " + sq(12)); console.log(foo(3));
  • 34.
    Type binding ofvariable How specified? explicit vs implicit When bound? static vs dynamic
  • 35.
    an explicit declarationis a statement in a program that lists variable names and specifies that they are a particular type an implicit declaration is a means of associating variables with types through default conventions, rather than declaration statements
  • 36.
    Fortran: static types,implicitly declared In implicit typing, all constants, variables and arrays beginning with the letters I, J, K, L, M, or N are automatically taken to be of type INTEGER. Constants, variables and arrays beginning with all other letters are assumed to be REAL. Thus, with implicit typing, the variable COUNT is REAL whilst the variable KOUNT is an INTEGER. Implicit typing can be overridden with explicit type declaration. source: http://www.obliquity.com/computer/fortran/datatype.html
  • 37.
    Perl: implicitly declaredwith different name spaces $a : scalar (string or numeric value) #a : array %a : hash structure
  • 38.
    Variables and Expressions(C) #include <stdio.h> static types, explicitly declared /* print Fahrenheit-Celsius table for fahr = 0, 20, ..., 300 */ int main() { int fahr, celsius; int lower, upper, step; lower = 0; /* lower limit of temperature scale */ upper = 300; /* upper limit */ step = 20; /* step size */ fahr = lower; while (fahr <= upper) { celsius = 5 * (fahr - 32) / 9; printf("%dt%dn", fahr, celsius); fahr = fahr + step; } return 0; }
  • 39.
    type inference: implicittype declaration using context Languages with type inference ML Haskell OCaml F# Scala Visual BASIC 9.0+ Go
  • 40.
    Scala: static types,inferred from context def widthOfLength(s: String) = s.length.toString.length val lines = Source.fromFile(args(0)).getLines.toList val longestLine = lines.reduceLeft( (a, b) => if (a.length > b.length) a else b ) val maxWidth = widthOfLength(longestLine)
  • 41.
    dynamic type binding:variable is bound to type when it is assigned a value Languages with dynamic type binding Ruby JavaScript Lisp Scheme Python PHP
  • 42.
    Variable Declaration (JS) vari; var sum; var i, sum; var message = "hello"; var i = 0, j = 0, k = 0; for(var i = 0; i < 10; i++) console.log(i); for(var i = 0, j=10; i < 10; i++,j--) console.log(i*j); for(var p in o) console.log(p); var i = 10; i = "ten";
  • 43.
    JavaScript: dynamic typebinding list = [10.2, 3.5]; list = 47; Ruby all variables are references all data are objects (there is only one type) any variable can reference an object
  • 44.
    Disadvantages of dynamictyping programs are less reliable: types not checked by compiler cost of checking types at run time
  • 45.
    next week: storagebindings and lifetime
  • 46.
  • 47.
    the scope ofa variable is the range of statements in which the variable is visible a variable is local in a program unit or block if it is declared there the non-local variables are those that are visible but not declared in a program unit
  • 48.
    class ChecksumAccumulator { private var sum = 0 def add(b: Byte): Unit = { sum += b } def checksum(): Int = { return ~(sum & 0xFF) + 1 } } Scala: variable sum is non-local for methods add and checksum
  • 49.
    static scoping: scopeof variable can be statically determined nested scopes: Ada, JavaScript, Scheme, Scala, F#, Python non-nested scopes: C-based languages
  • 50.
    function big() { function sub1() { var x = 7; sub2(); } function sub2() { var y = x; } var x = 3; sub1(); } static scoping in JavaScript
  • 51.
    Variable Scope (JS) varscope = "global"; // Declare a global variable function checkscope() { var scope = "local"; // Declare a local variable with the same name return scope; // Return the local value, not the global one } checkscope() // => "local"
  • 52.
    Variable Scope (JS) scope= "global"; // Declare a global variable, even without var. function checkscope2() { scope = "local"; // Oops! We just changed the global variable. myscope = "local"; // This implicitly declares a new global variable. return [ scope, myscope ]; // Return two values. } checkscope2() // => ["local", "local"]: has side effects! scope // => "local": global variable has changed. myscope // => "local": global namespace cluttered up.
  • 53.
    Nested Functions (JS) function hypotenuse(a, b) { function square(x) { return x * x; } return Math.sqrt(square(a) + square(b)); } var scope = "global scope"; // A global variable function checkscope() { var scope = "local scope"; // A local variable function nested() { var scope = "nested scope"; // A nested scope of local variables return scope; // Return the value in scope here } return nested(); } checkscope() // => "nested scope"
  • 54.
    block: sections inwhich allocation of storage for variables is allocated if (list[i] < list[j]) { int temp; void sub() { temp = list[i]; int count; list[i] = list[j]; ... list[j] = temp; while (...) { } int count; count++; ... } ... Java and C# do not allow } shadowing of variables
  • 55.
    def printMultiTable() { var i = 1 // only i in scope here block scope in Scala: while (i <= 10) { var j = 1 order of declaration // both i and j in scope here while (j <= 10) { matters val prod = (i * j).toString // i, j, and prod in scope here var k = prod.length // i, j, prod, and k in scope here while (k < 4) { print(" ") k += 1 } print(prod) j += 1 } // i and j still in scope; prod and k out of scope println() i += 1 } // i still in scope; j, prod, and k out of scope }
  • 56.
    Function Scope andHoisting (JS) function test(o) { var i = 0; // i is defined throughout function if (typeof o == "object") { var j = 0; // j is defined everywhere, not just block for ( var k = 0; k < 10; k++) { // k is defined everywhere, not just loop console.log(k); // print numbers 0 through 9 } console.log(k); // k is still defined: prints 10 } console.log(j); // j is defined, but may not be initialized } JavaScript does not have block scope!
  • 57.
    Use Before Declaration varscope = "global"; function f() { console.log(scope); // Prints "undefined", not "global" var scope = "local"; // Variable initialized here, but defined everywhere console.log(scope); // Prints "local" } function f() { var scope; // Local variable is declared at the top of the function console.log(scope); // It exists here, but still has "undefined" value scope = "local"; // Now we initialize it and give it a value console.log(scope); // And here it has the value we expect }
  • 58.
    let val name1 = expression1 ... val namen = expressionn in expression end; let val top = a + b val bottom = c - d in top / bottom end; let binding in ML
  • 59.
  • 60.
    module names imports NaBL: Spoofax Name Binding Language include/Delft namespaces module blog Module Entity imports user Property entity BlogPosting { rules name : String poster : User Module(x, _) : body : String defines Module x scopes Entity blog : Blog title : String Entity(x, _) : } defines Entity x of type Type(x) scopes Property entity Blog { title : String Property(x, t) : author : Blog defines Property x of type t } Type(x) : refers to Entity x entity User { refers to Entity "String" name : String refers to Entity "Int" }
  • 62.
    Reading & Programmingin Week 2 Reading: Sebesta Chapter 5: Names, Bindings, Scopes WebLab: C tutorial JavaScript tutorial More Scala tutorial Grammars and regular expressions Week 3: Dynamic Binding & Storage