Programming Languages: Names, Bindings, and Scope
Programming Languages: Names, Bindings, and Scope
1
Objectives
2
Introduction
Imperative programming languages are designed in a way that closely follows how a computer actually works.
They tell the computer step by step what to do, just like a set of instructions in a recipe.
These languages follow the von Neumann architecture, which is the basic design of most computers. This
architecture consists of a memory for storing data and instructions, and a processor that executes those
instructions one by one.
imperative programming is about giving the computer a sequence of commands to change its memory and
perform tasks.
3
Introduction
Imperative programming languages are designed to work like how a computer actually processes instructions.
Computers have two main parts that help them run programs:
1.Memory – This stores both the instructions (commands) and the data (information) needed for a program.
2.Processor (CPU) – This performs operations, like calculations and moving data, by modifying what’s in memory.
variables are like labels for specific storage locations in a computer's memory. They act as an abstraction, meaning
they simplify how we interact with memory without dealing with its complexity. Instead of manually managing
memory, we use variables to store and retrieve data easily.
Think of a computer’s memory as a giant grid of tiny storage boxes, where each box can hold a piece of
information. Programming languages create variables as a way to manage these storage boxes easily.
4
Introduction
In programming languages, variables act like placeholders for memory storage. Each variable has certain
properties, with type being the most important.
The type of a variable (like number, text, or list) determines how the computer interprets and uses the data.
5
Introduction
So, they are like the named constants of the imperative languages.
Pure functional languages do not have variables that are like those of
the imperative languages.
Functional programming languages allow you to give names to expressions, similar to how variables work in other
programming languages.
However, there is a key difference: once you assign a value to a name in functional programming, it cannot be
changed. This makes it more like a constant in imperative languages (where constants are values that don’t
change).
In pure functional programming languages, there are no traditional variables that store changing values. But some
functional languages do allow variables that behave more like those in imperative languages.
6
Introduction
FEATURE Imperative Functional
FOCUS How to do something What to do
STATE CHANGES Uses variables that change Avoids changing variables
EXAMPLES C, Java, Python (loops) Haskell, SQL, Prolog
CODE STYLE Expresses logic or
Step-by-step instructions
computations without steps
Imperative programming is like giving a detailed recipe to a computer. You provide a set of step-by-step
instructions that tell the computer exactly how to accomplish a task.
• Uses variables to store values and update them as needed.
• Uses control structures such as loops (for, while) and conditional statements (if-else).
• Focuses on changing the program’s state (i.e., modifying values in memory).
Non-imperative programming is like stating what you want, without specifying how to do it. The computer
figures out the process itself.
• Functional Programming: Uses functions that avoid changing variables (e.g., Haskell, Lisp).
• Logic Programming: Uses rules and facts to infer conclusions (e.g., Prolog).
• Query-Based Programming: Focuses on retrieving data without specifying how (e.g., SQL).
7
Design Issues
When designing a programming language, decisions about case sensitivity and reserved words impact code
readability, ease of use, error prevention, and compatibility.
These are considered issues because they can create challenges for programmers and influence how code is
written and understood.
Reserved Words
•Cannot be used as variable or function names.
Keywords
•Can sometimes be used as variable names if the context allows
8
Name Forms
9
Name Forms
In most programming languages, names (like variable names and function names) usually follow a simple rule:
Start with a letter, followed by letters, numbers, or underscores (_).
Old Style (1970s–1980s): Programmers often used underscores to separate words in names.
Underscores have mostly been replaced by camel case, where every word after the first starts with a capital letter.
10
Name Forms
It is called “camel” because words written in it often have embedded uppercase letters, which look like a camel’s
humps.
In Java and C#, however, the problem cannot be escaped because many of the predefined names include both
uppercase and lowercase letters. For example, the Java method for converting a string to an integer value is
parseInt, and spellings such as ParseInt and parseint are not recognized. This is a problem of writability rather than
readability, because the need to remember specific case usage makes it more difficult to write correct programs. It
is a kind of intolerance on the part of the language designer, which is enforced by the compiler.
11
Name Forms
• In that sense, case sensitivity violates the design principle that language
constructs that look similar should have similar meanings. But in languages
whose variable names are case-sensitive, although Rose and rose look similar,
there is no connection between them.
12
Special Words
Keywords have a special meaning in a programming language but might still be usable as variable names in some
cases.
Reserved words are keywords that can NEVER be used as variable names. They are strictly off-limits in all
contexts.
13
Special Words
In Fortran, the word Integer can mean different things depending on where and how it is used:
14
Special Words (sample)
Integer Apple
Integer = 4
• Fortran compilers and people reading Fortran programs must distinguish between names and special words by
context.
• A reserved word is a special word of a programming language that cannot be used as a name.
• As a language design choice, reserved words are better than keywords because the ability to redefine
keywords can be confusing. For example, in Fortran, one could have the following statements:
15
Variables
Programmers often think of variable names as names for memory locations → Many people see variables as
simple labels for memory spaces.
But there is much more to a variable than just a name → Variables also have properties like type, scope, and
lifetime.
16
Variables
A program variable is like a container in a computer's memory where we store data. It represents a specific spot
(or multiple spots) in memory but in a way that is easier for programmers to use.
Many people think of variables only as names for memory locations, but variables have more than just names.
They have different attributes that define how they work.
The term sextuple comes from the Latin prefix "sex-", meaning six. It simply means a group of six things
Tuple = A fixed set of related things
17
Variables (Address)
It is possible to have multiple variables that have the same address. When more than one variable name can be
used to access the same memory location, the variables are called aliases. Aliasing is a hindrance to readability
because it allows a variable to have its value changed by an assignment to a different variable. For example, if
variables named total and sum are aliases, any change to the value of total also changes the value of sum and vice
versa. A reader of the program must always remember that total and sum are different names for the same
memory cell. Because there can be any number of aliases in a program, this may be very difficult in practice.
Aliasing also makes program verification more difficult.
18
Variables (Type)
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.
19
Variables (Value)
This size is too small for most program variables. An abstract memory cell has the size required by the variable
with which it is associated. For example, although floating-point values may occupy four physical bytes in a
particular implementation of a particular language, a floating-point value is thought of as occupying a single
abstract memory cell. The value of each simple nonstructured type is considered to occupy a single abstract cell.
Henceforth, the term memory cell means abstract memory cell.
20
The Concept of Binding
Example: When you declare a variable like int age = 25;, the variable age is bound to:
•A type (int means it stores integers).
•A value (25 is the current stored data).
21
The Concept of Binding
Language Design Time → When the rules of the language are created (e.g., deciding that int means integer).
Language Implementation Time → When compilers or interpreters are built to follow the language rules.
Compile Time → When the program is translated into machine code (e.g., checking variable types).
Load Time → When the program is loaded into memory before execution.
Link Time → When different parts of a program are combined (e.g., connecting external libraries).
Run Time → When the program is actually running (e.g., assigning a new value to a variable).
22
The Concept of Binding
count = count + 5;
Some of the bindings and their binding times for the parts of this assignment
statement are as follows:
Different bindings (associations) happen at different times when the program is being written, compiled, and
executed.
23
Type Bindings
Static Binding
Dynamic Binding
24
Static Type Binding
Explicit Declaration
This means you clearly specify a variable’s type when declaring it. Like in Java: int age;
Implicit Declaration
This means the compiler automatically assigns a type based on how the variable is used. Like in python: age = 25
Implicit variable type binding is done by the language processor, either a compiler or an interpreter. There are
several different bases for implicit variable type bindings. The simplest of these is naming conventions. In this case,
the compiler or interpreter binds a variable to a type based on the syntactic form of the variable’s name. For
example, in Fortran, an identifier that appears in a program that is not explicitly declared is implicitly declared
according to the following convention: If the identifier begins with one of the letters I, J, K, L, M, or N, or their
lowercase versions, it is implicitly declared to be Integer type; otherwise, it is implicitly declared to be Real type.
25
Static Type Binding
@apple vs %apple
Implicit declarations mean that a variable’s type is not explicitly stated when it is first used.
This can sometimes lead to confusion or errors because programmers might not realize what type a variable is
supposed to have.
To avoid such issues, some programming languages use special characters at the beginning of variable names to
indicate their type.
26
Dynamic Type Binding
In some programming languages, you don’t have to declare a variable’s type before using it.
Instead, the variable gets its type when a value is assigned to it.
This means a variable can change types based on the value it holds.
27
Dynamic Type Binding
Instead, a variable name is connected to a memory location (where the data is stored).
The data itself determines the type of the variable at any given time.
28
Storage Binding and Lifetime
The memory cell to which a variable is bound somehow must be taken from a pool of available memory.
•A computer has a limited amount of memory (RAM), which is shared by all running programs.
•When a variable is created, it needs some space in memory to store its value.
•This memory is taken from a "pool" of available memory (unused space in RAM).
Deallocation is the process of placing a memory cell that has been unbound from a variable back into the pool
of available memory.
•When a variable is no longer needed, its memory should be released so that other parts of the program can use
it.
•This process is called deallocation.
29
Storage Binding and Lifetime
The lifetime of a variable is the time during which the variable is bound to a specific memory location.
•A variable’s lifetime starts when it is given a memory location.
•The lifetime ends when the variable is removed from memory.
So, the lifetime of a variable begins when it is bound to a specific cell and ends when it is unbound from that
cell.
•The start of a variable’s lifetime is when it gets memory.
•The end of a variable’s lifetime is when it loses that memory (deallocation).
30
Static Variables
Static variables are those that are bound to memory cells before
program execution begins and remain bound to those same memory
cells until program execution terminates.
In C or C++:
static int counter = 0;
efore a program starts running, the system allocates memory for static variables.
These variables get a fixed memory location that does not change throughout the program’s execution.
31
Scope
"The scope of a variable is the range of statements in which the variable is visible."
•Scope defines where in the program a variable can be used.
•A variable is only accessible within a certain section of the program.
"Non-local variables of a program unit or block are those that are visible within the program unit or block but
are not declared there."
•Non-local variables are not declared inside a function but can still be accessed there.
•Usually, they are global variables (declared outside functions).
32
Static Scope
"Static scoping is named because the scope of a variable can be statically determined – that is, prior to
execution."
•The scope of a variable is fixed when the program is written, not when it runs.
•This means a compiler can determine which variables are accessible without executing the program.
"This permits a human program reader (and a compiler) to determine the type of every variable in the program
simply by examining its source code."
•Since variables have a fixed scope, a programmer (or compiler) can tell where each variable is used just by
reading the code.
•No need to run the program to figure out which variable belongs where.
33
Static Scope
Nested Subprograms
•Functions (or procedures) can be defined inside other functions.
•Inner functions have access to the variables of their outer functions.
34
NEXT MEETING
35
Blocks
• From ALGOL 60, allows a section of code to have its
own local variables whose scope is minimized.
• Such variables are stack dynamic, so they have their
storage allocated when the section is entered and
deallocated when the section is exited.
• The C-based languages allow any compound statement
(a statement sequence surrounded by matched braces) to
have declarations and thereby defined a new scope.
"From ALGOL 60, allows a section of code to have its own local variables whose scope is minimized."
•In ALGOL 60 (an early programming language), you can declare local variables inside a specific section of code.
•These variables are only accessible within that section (their scope is limited).
"Such variables are stack dynamic, so they have their storage allocated when the section is entered and
deallocated when the section is exited."
•These variables are automatically created when the program enters the section of code.
•They are removed from memory when the program leaves that section.
•This is managed using a stack, which stores temporary data during program execution.
"The C-based languages allow any compound statement (a statement sequence surrounded by matched braces)
to have declarations and thereby defined a new scope."
•In C-based languages (like C, C++, Java), you can declare variables inside any block of code enclosed in { }.
•This creates a new scope, meaning variables inside { } exist only within that block.
36
Blocks
void sub() {
int count; // This "count" belongs to the whole function sub()
while (...) {
int count; // This "count" only exists inside the while loop
count++; // This affects only the inner "count"
}
}
The first count (outside the loop) belongs to the entire function sub().
The second count (inside the loop) is a separate variable that only exists inside the loop.
The inner count disappears when the loop ends, but the outer count remains.
37
Blocks
• Note that this code is legal in C and C++ but illegal in Java
and C#
38
Declaration Order
• C99, C++, Java, and C# allow variable declarations to
appear anywhere a statement can appear
• In C99, C++, and Java, the scope of all local variables
is from the declaration to the end of the block
• In C#, the scope of any variable declared in a block is
the whole block, regardless of the position of the
declaration in the block
• However, a variable still must be declared before it can
be used
"C99, C++, Java, and C# allow variable declarations to appear anywhere a statement can appear."
•In C99, C++, Java, and C#, you can declare a variable anywhere inside a block of code, not just at the beginning.
•This gives programmers more flexibility when writing code.
"In C99, C++, and Java, the scope of all local variables is from the declaration to the end of the block."
•In these languages, a local variable is accessible only from where it is declared until the end of the block ({ }).
•If a variable is declared inside a loop or function, it exists only within that loop or function.
"In C#, the scope of any variable declared in a block is the whole block, regardless of the position of the
declaration in the block."
•In C#, once you declare a variable anywhere inside a block, it is considered to exist for the entire block.
•But you still must declare a variable before using it in your code.
39
Declaration Order
The first x is declared in the outer block, so it exists throughout the entire block.
Trying to declare another x inside the inner block is not allowed in C# because it would create a conflict.
40
Declaration Order
• Because the scope of a declaration is the whole block, the following nested
declaration of x is also illegal:
{
...
{int x; // Illegal
...
}
int x;
}
– Note that C# stall requires that all be declared before they are used
41
Declaration Order
• In C++, Java, and C#, variables can be declared in for
statements
– The scope of such variables is restricted to the for
construct
"In C++, Java, and C#, variables can be declared in for statements."
•In C++, Java, and C#, you can declare a variable inside a for loop.
•This means the variable exists only within the for loop.
42
Declaration Order
void fun() {
...
for (int count = 0; count < 10; count++) {
int count;
...
}
...
}
– The scope of count is from the for statement to the end of for its body (the
right brace)
The first count is declared in the for loop header (int count = 0).
The second count inside the { } block is not allowed because the loop already has a count.
"The scope of count is from the for statement to the end of for its body (the right brace)."
•The count variable inside the for loop only exists from the start of the loop until the closing } of the loop body.
•Once the loop ends, count disappears and cannot be used outside.
43
Global Scope
• C, C++, PHP, and Python support a program structure that consists of a
sequence of function definitions in a file
– These languages allow variable declarations to appear outside
function definitions
1."C, C++, PHP, and Python support a program structure that consists of a sequence of function definitions in a
file."
1. These languages organize code into functions, which are written inside a file.
2. The file contains multiple function definitions, and these functions can be used in the program.
2."These languages allow variable declarations to appear outside function definitions."
1. You can declare variables outside of functions.
2. These are called global variables because they can be accessed by multiple functions in the file.
44
Dynamic Scope
Dynamic scoping is a way of figuring out which variables a function can use, based on the order in which functions
are called during the program's execution, rather than where the variables are created in the code.
In simpler terms, when a function runs, dynamic scoping looks at the most recent functions that were called and
allows the current function to use variables from those functions, even if the variables were declared outside the
current function.
For example, in languages with dynamic scoping (like early versions of LISP, APL, and SNOBOL4), a function can
access variables from other functions that were called before it, not just the variables declared inside it.
Some modern languages, like Perl and Common Lisp, have dynamic scoping as an option, but by default, they use
static scoping, where functions can only access variables that are in their scope or passed directly to them.
45
Dynamic Scope
"References to variables are connected to declarations by searching back through the chain of subprogram calls
that forced execution to this point."
• When a variable is used in dynamic scoping, the program searches backward through all active function calls to
find where it was last declared.
• This means that a function can use variables from functions that called it, even if those variables were never
passed as parameters.
• The program does not check the written structure but instead looks at which functions are currently running.
46
Dynamic Scope
• Ex: Consider again the function big, which the two
functions sub1 and sub2 are nested:
function big() {
function sub1() {
var x = 7;
...
}
function sub2() {
var y = x; . . .
}
var x = 3;
...
}
47
Dynamic Scope
• Consider the two different call sequences for sub2:
– big calls sub2 and sub2 use x
• The dynamic parent of sub2 is big. The reference is to the x in
big.
– big calls sub1, sub1 calls sub2, and sub2 use x
• The search proceeds from the local procedure, sub2, to its
caller, sub1, where a declaration of x is found.
– Note that if static scoping was used, in either calling sequence the
reference to x in sub2 is to big’s x.
48
Scope and Lifetime
Scope and lifetime are sometimes closely related, but are
different concepts
"The scope of such a variable is from its declaration to the end of the method."
•A local variable in Java can only be accessed within the method where it is declared.
•Once the method ends, the variable is no longer accessible.
"The lifetime of that variable is the period of time beginning when the method is entered and ending when
execution of the method terminates."
•The variable comes into existence when the method starts.
•It disappears from memory when the method finishes execution.
49
Scope and Lifetime
• Consider a static variable in a C or C++ function
– Statically bound to the scope of that function and is
also statically bound to storage
– Its scope is static and local to the function but its
lifetime extends over the entire execution of the
program of which it is a part
"Statically bound to the scope of that function and is also statically bound to storage."
•The scope of a static variable is limited to the function where it is declared.
•However, it is stored permanently (not created and destroyed with function calls).
"Its scope is static and local to the function but its lifetime extends over the entire execution of the program of
which it is a part."
•A static variable can only be accessed within its function (local scope).
•However, it stays in memory for the entire runtime of the program.
•This means even if the function is called multiple times, the variable retains its value from previous calls.
50
Referencing Environments
"The referencing environment of a statement is the collection of all names that are visible in the statement."
•This means that when a statement (line of code) is executed, it has access to certain variables.
•These variables are part of its referencing environment (which includes local and visible variables).
"The referencing environment of a statement is needed while that statement is being compiled, so code and
data structures can be created to allow references to variables from other scopes during run time."
•The compiler needs to know which variables a statement can access.
•This helps the compiler set up data structures that allow variables from outer scopes to be used at runtime.
51
Referencing Environments
• A subprogram is active if its execution has begun but
has not yet terminated.
“A subprogram is active if its execution has begun but has not yet terminated."
•A subprogram (function/method) is active when it has been called but has not yet finished execution.
•While it is active, it can still use and modify variables.
“In a dynamic-scoped language, the referencing environment is the local variables plus all visible variables in all
active subprograms."
•Dynamic scoping means that a variable's scope is determined at runtime, based on which functions are currently
active.
•The referencing environment includes:
• Local variables (declared in the function).
• Variables from any active function that called this function (instead of just outer scopes in the code).
52
Referencing Environments
• Ex.
x = 10 # Global variable
def outer():
y = 20 # Enclosing scope variable
def inner():
z = 30 # Local variable
print(x) # Can access global x
print(y) # Can access enclosing y
print(z) # Can access local z
inner()
outer()
53
Referencing Environments
• The referencing environments of the indicated program points are as
follows:
•Referencing Environment for print(x) in inner()
•The statement print(x) is inside inner(), but x is a global variable.
•The referencing environment includes:
•Local Scope (inner()): No x found.
•Enclosing Scope (outer()): No x found.
•Global Scope: Finds x = 10.
•Built-in Scope: Not needed in this case.
•Referencing Environment for print(y) in inner()
•The statement print(y) is in inner(), but y is declared in outer().
•The referencing environment includes:
•Local Scope (inner()): No y found.
•Enclosing Scope (outer()): Finds y = 20.
•Global Scope: Not needed.
•Built-in Scope: Not needed.
•Referencing Environment for print(z) in inner()
•The statement print(z) is inside inner(), and z is defined inside inner().
•The referencing environment includes:
•Local Scope (inner()): Finds z = 30.
•No need to check Enclosing, Global, or Built-in.
A referencing environment in programming refers to the set of variables that are visible and accessible at a
particular point in a program. It defines where and how a variable can be accessed within a program's structure.
54
Referencing Environments
55
Named Constants
• It is a variable that is bound to a value only at the time it is bound to
storage; its value cannot be change by assignment or by an input statement.
• Ex, Java
A named constant is like a regular variable, but once you give it a value, you cannot change it. It stays the same
throughout the program.
56
Named Constants
Variable Initialization
• The binding of a variable to a value at the time it is bound to storage
is called initialization.
• Initialization is often done on the declaration statement.
• Ex, C++
int sum = 0;
int* ptrSum = ∑
char name[] = “George Washington Carver”;
Variable initialization means giving a variable a starting value at the moment it is created (when it is given storage
in memory).
57
Thank you
58