3. Names and Bindings¶
3.1. Names in a program¶
We need names (or identifiers ) in order to denote various entities in a program.
Syntax of names differs depending on the language. In most languages, a name is a sequence of alphabets, numbers and some symbols.
In some languages, there is a limit on the length of names.
There are case-sensitive languages and case-insensitive languages.
A Keyword is a name which plays some designated role in syntax. A reserved word is a keyword which cannot be used with other meaning.
Fortran has no reserved word
The following Fortran program is syntactically correct.
INTEGER REAL
REAL INTEGER
REAL = 3
INTEGER = 1.2
Most languages provide standard libraries. Names defined in those libraries are neither keywords nor reserved words.
Names defined in libraries
In Javascript, alert
function is provided by browsers. We can use the name alert
for other purpose.
var alert;
alert = 1;
3.2. Namespace¶
When we use a lot of names, it is necessary to use long names in order to avoid conflicts. However, long names are not convenient to read and write. A namespace is a name given to a set of names, which allows us to make the hierarchy of names. In other words, it enables us to use concatenated short names instead of a single long name.
Namespace in C++
::
is the operator to concatenate names.
#include <iostream>
main() {
std::cout << "Hello, world!\n";
}
We can set the default namespace by using namespace
.
#include <iostream>
using namespace std;
main() {
cout << "Hello, world!\n";
}
Importing a module in Python
If you import a module, names defined in the module are available in the form module.function.
import foo
x = foo.bar()
If you import a function, the function name is available without the module name.
from foo import bar
x = bar()
3.3. Bindings¶
3.3.1. Definition of bindings¶
Because a name is a syntactic object, we must make a connection between a name and a semantic entity (e.g. variable, function, etc.).
A binding is a link between a name (more precisely, an occurence of a name) and a certain semantic entity.
We call a binding static when it can be determined before execution (usually compile-time).
We call a binding dynamic when it is determined during execution.
An environment is a set of bindings currently used during execution.
Note
A static binding does not necessarily mean a certain name always bound to the same entity. Different occurences of a certain name may have different bindings.
Variables in TinyBASIC
TinyBASIC (very small BASIC interpreter) has only 26 variables: A
to Z
. In this case, we always use the same environment.
Variables in Java
In Java, a variable declaration int i;
means we will bind a name i
to a newly created integer variable.
Exercise 5
There are two types of languages as to varibale declarations. Languages such as C and Java require declarations before variables are used, while languages such as Perl and Ruby do not. What are merits and demerits of these two types of languages?
3.3.2. Anonymous and alias¶
Bindings are not necessarily one-to-one association.
We call an entity anonymous if it is not bound to any name.
One entity can be bound to more than one names. In such case, names that bound to the same entity are called alias of each other.
Anonymous function in JavaScript
function(x) { return x+1; }
Anonymous function in Lisp
(lambda (x) (+ x 1))
Reference in PHP
Alias in Ruby
alias $b $a
$a = 2
puts $b
3.4. Scope¶
A scope is a part of program where a certain binding is used (in other words, we can see an entity through its name).
3.4.1. Static Scoping¶
In Algol-based languages, the scope of a name is a block in which the name is declared. If the same name is declared more than once, the most inner one takes precedence over outer ones. This type of scoping is also called lexical scoping because it is determined by the lexical stuructres.
Static scoping
Both procedure main
and procedure sub2
have variable
definitions of x
. Occurences of x
in procedure sub1
use the variable defined in procedure main
.
procedure main;
var x : integer; { declaration 1 }
procedure sub1;
begin
... x ... { refers declaration 1 }
end;
procedure sub2;
var x : integer; { declaration 2 }
begin
... x ... { refers declaration 2 }
end;
{ body of main }
begin
... x ... { refers declaration 1 }
end;
3.4.2. Dynamic scoping¶
In the original Lisp and some of its successor, if a name is declared in a function, its scope extends to other functions called from it. If the same name is declared more than once, the most recent one takes precedence over older one.
Dynamic scoping
Occurrences of x
in procedure sub1
have different bindings depending on which procedure calls sub1
.
procedure main;
var x : integer; { declaration 1 }
procedure sub1;
begin
... x ... { refers declaration 1 when called from B
refers declaration 2 when called from A }
end;
procedure sub2;
var x : integer; { declaration 2 }
begin
sub1 { call A }
end;
{ body of main }
begin
sub1; { call B }
sub2
end;
Exercise 6
In the following pseudo code, what is the output when using staic scoping and dynamic scoping, respectively?
procedure main;
var x : integer;
procedure sub1;
begin
writeln(x) { output the value of x }
end;
procedure sub2;
var x : integer;
begin
x := 10;
sub1
end;
begin
x := 5;
sub2
end.
[Answer]