Chapter 2
Language Design Issues
1
Topics Covered
Introduction: Design Goals
Programming environments
Virtual Computers
Binding Times
Language Paradigms
2
Introduction: Design Goals
• There are several design goals considered whenever a new language i
s to be designed.
•Utility - Is a feature often useful? Can it do important things th
at cannot be done using other features of the language?
•Convenience - Does this feature help avoid excessive writing?
Does this feature add or eliminate clutter (code untidiness) in the
code?
•Efficiency - Is it easy or difficult to translate this feature? Is it p
ossible to translate this feature into efficient code? Will its use imp
rove or degrade the performance of programs?
•Portability - Will this feature be implementable on any platfor
m?
•Readability - Does this form of this feature make a program m
ore readable? Will a programmer other than the designer underst
and the intent easily?
3
• There are several design goals considered whenever a new lan
guage is to be designed.
• Modeling ability - Does this feature help make the meani
ng of a program clear? Will this feature help the programm
er model a problem more fully, more precisely, or more easi
ly?
• Simplicity - Is the language design as a whole simple, unifi
ed, and general, or is it full of dozens of special-purpose fea
tures?
• Semantic clarity - Does every legal program and expressio
n have one defined, unambiguous meaning? Is the meaning
constant during the course of program execution?
4
Programming Environment
• Is a collection of tools used in software
development
• Can be separate file system, text editor, linker, compiler
• UNIX is an older programming environment and
provides a variety of powerful tools where all of its tools
were accessed separately.
• Can also be a large collection of integrated tools, each
accessed through a uniform graphical user interface
(Visual Studio, NetBeans)
5
Source Source Source
code code code
Compiler Compiler Compiler
Object files
Linker
Executable files Library files
Loader
Memory
6
Virtual Computers
• A virtual machine (VM) is a software implementation of a
machine (i.e. a computer) that executes programs like a ph
ysical machine
• A virtual machine is less efficient than a real machine beca
use it accesses the hardware indirectly
• Virtual machines are separated into two major categories,
based on their use and degree of correspondence to any r
eal machine
• System virtual machine
– Multiple OS environments can co-exist on the same
computer, in strong isolation from each other
– Example: VMware workstation
7
Virtual Computers
• Process virtual machine
• A process VM, sometimes called an application virtual machine
– runs as a normal application inside a host OS and suppo
rts a single process.
– Example: Java Virtual Machine
• A process VM is created when that process is started and destr
oyed when it exits
• Its purpose is to provide a platform-independent programming
environment
– abstracts away details of the underlying hardware or op
erating system, and allows a program to execute in the s
ame way on any platform.
8
Binding Times
• A binding is an association between two things, s
uch as a name and the thing it names.
• Binding time is the time at which a binding is crea
ted.
• Basically, binding times are of two types, Static an
d Dynamic (Early and Late)
• Static and Dynamic are very general terms to talk
about binding times
• In general, early binding is associated with greate
r efficiency and late binding is associated with gre
ater flexibility
9
Binding Times - Terminology
• Static usually means "before run time".
• Dynamic usually refers to run time.
• Tradeoff: In general,
– Early binding -> greater efficiency, less flexibility.
– Late binding -> more flexibility, less efficiency.
(Discuss flexibility and efficiency)
10
Binding Times
• Language design time
•the control flow constructs - language semantics
•the set of fundamental (primitive) types
•the available constructors for creating complex types
•Example: the type referred to by the name int.
• Language implementation
• the precision (number of bits) of the fundamental types,
• the coupling of I/O to the operating system’s notion of files
• the organization and maximum sizes of stack and heap
• the handling of run-time exceptions such as arithmetic ove
rflow.
11
Binding Times
• Compile time
• Compilers choose the mapping of high-level constructs to mac
hine code, including the layout of statically defined data in me
mory.
• Link time
• Most compilers support separate compilation (compiling differ
ent modules of a program at different times)
• The linker chooses the overall layout of the modules with respe
ct to one another.
• Inter-module references resolved here
• When a name in one module refers to an object in another mo
dule, the binding between the two is performed by the linker.
12
Binding Times
• Load time
• Load time refers to the point at which the operating system loads th
e program into memory.
• A variable may be bound to a storage cell when the program is load
ed into memory
• Translate virtual memory addresses into physical memory addresse
s.
• Run time
• Most modern operating systems distinguish between virtual and ph
ysical addresses.
• Virtual addresses are chosen at link time; physical addresses can act
ually change at run time.
• The processor’s memory management hardware translates virtual a
ddresses into physical addresses during each individual instruction a
t run time.
13
Binding Times
Consider the following Java assignment statement:
count = count + 5;
• Some of the bindings and their binding times for the parts
of this assignment statement are as follows:
– The type of count is bound at compile time.
– The set of possible values of count is bound at compiler desig
n time (Implementation time)
– The meaning of the operator symbol + is bound at compile ti
me, when the types of its operands have been determined.
– The internal representation of the literal 5 is bound at compile
r design time.
– The value of count is bound at execution time with this statem
ent.
14
15
Binding Times
• Meaning of +
• was defined (as numerical addition) when the language was
defined
• The specific addition operation (float, double, int, etc.),
however, cannot be determined until program translation
time.
• Literal 23
• The meaning of literal 23 as the int value representing the
number 23 is fixed at language definition time.
• However, the actual representation (sequence of bits) for the
int value 23 can vary on different platforms, and it is not
bound until the language implementation (compiler design) is
performed.
16
Binding Times
• Computation performed by an external function
• A function in another program file (i.e., an external function)
can come from a library or from another compilation.
• The specific function that is linked to the function call is not
determined until the program modules are combined by the
linkage editor
17
Binding: Type Binding
Before a variable can be referenced in a program, it must be bound to
a data type
The two important aspects of this binding are how the type is specified
and when the binding takes place
Static type binding
Declaration is a static type binding
Explicit declaration
listing variable names and specifies that they are a
particular type
Example: int x,y; float radius;
Implicit declaration
Means of associating variables with types through default
conventions
done by the language processor, either a compiler or an
interpreter
18
Binding: Type Binding
Implicit declaration
Several different bases for implicit variable type bindings.
1. Naming Conventions: FORTRANIf 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.
Big damage to reliability because they prevent the
compilation process from detecting some typographical and
programmer errors
2. Type inference (Context)
type of the value assigned to the variable in a declaration
statement will be the type of the variable.
Example: in C# a var declaration of a variable must include
an initial value, whose type is made the type of the variable
The type of sum, total and name are
int, float and string respectively
19
Binding: Type Binding
Dynamic type binding
the type of a variable is not specified by a declaration statement,
nor can it be determined by the spelling of its name
Instead, the variable is bound to a type when it is assigned a value
in an assignment statement.
When the assignment statement is executed, the variable being
assigned is bound to the type of the value of the expression on the
right side of the assignment
Example:
The primary advantage of dynamic binding of variables to types is
that it provides more programming flexibility.
For example, a program to process numeric data in a language that
uses dynamic type binding can be written as a generic program,
meaning that it is capable of dealing with data of any numeric type.
20
Storage Bindings and Lifetime
The memory cell to which a variable is bound must be taken
from a pool of available memory Allocation
Deallocation is the process of placing a memory cell that has
been unbound from a variable back into the pool of available
memory
The lifetime of a variable is the time during which the variable is
bound to a specific memory location
Four category of scalar variables according to their lifetime:
Static variables
Stack-Dynamic Variables
Explicit Heap-Dynamic Variables
Implicit Heap-Dynamic Variables
21
Storage Bindings and Lifetime
Static variables
bound to memory cells before program execution begins and
remain bound to those same memory cells until program execution
terminates
Applications in programming
Global variables
Local static variables for history sensitive subprograms
Advantage
Efficiency: - Direct memory access
- No run-time overhead
Disadvantage
Reduced flexibility (static binding)
Storage cannot be shared among variables
Example: Consider two subprograms, both of which
require large arrays and suppose that the two subprograms
are never active at the same time. If the arrays are static,
22 they cannot share the same storage for their arrays.
Storage Bindings and Lifetime
Stack-Dynamic variables
Storage bindings are created when their declaration
statements are elaborated (type binding is static)
Elaboration: of such a declaration refers to the storage
allocation and binding process indicated by the
declaration, which takes place when execution reaches the
code to which the declaration is attached (Occurs during
run-time)
Example: the variable declarations that appear at the
beginning of a Java method are elaborated when the
method is called and the variables defined by those
declarations are deallocated when the method completes
its execution.
Stack-dynamic variables are allocated from the run-time
stack.
23
Storage Bindings and Lifetime
Stack-Dynamic variables
Example: C++ and Java—allow variable declarations to
occur anywhere a statement can appear, and the
declaration can be at the beginning or just anywhere in the
middle
Even if variables are
declared at different
positions in the code,
storage binding is done
(elaboration) for all
variables when the
function is called
24
Storage Bindings and Lifetime
Stack-Dynamic variables
Advantage: recursive subprograms require some form of
dynamic local storage so that each active copy of the recursive
subprogram has its own version of the local variables
Stack trace
25
Storage Bindings and Lifetime
Stack-Dynamic variables
Advantage: Subprograms share the same memory space for
their locals (Compare with Static variables)
Disadvantage:
Run-time allocation/de-allocation overhead
Slower accesses because indirect addressing is required
Subprograms cannot be history sensitive (no static
variables)
26
Storage Bindings and Lifetime
Explicit Heap-Dynamic Variables
Memory cells that are allocated and deallocated by explicit
run-time instructions written by the programmer.
Allocated from and deallocated to the heap
Can only be referenced through pointer or reference
variables
Created by either an
operator (as in C++)
The new keyword
call to a system subprogram provided for that purpose (as
in C).
The malloc subprogram
Type binding is static (Compile time)
Used to create dynamic structures, such as linked lists and
trees, that need to grow and/or shrink during execution
27
Storage Bindings and Lifetime
Explicit Heap-Dynamic Variables
Deallocating or destroying Explicit Heap-Dynamic Variables
Explicit: by using operators (Example C++)
Implicit: the programmer is not required to explicitly
include a code to destroy the variables.
Example: C# and Java included a Garbage Collection
facility.
28
Storage Bindings and Lifetime
Implicit Heap-Dynamic Variables
Bound to heap storage only when they are assigned values
All their attributes are bound every time they are assigned (Type,
Memory cell, Value, array subscripts)
Consider the following JavaScript assignment statement:
Regardless of whether the variable named highs was previously
used in the program or what it was used for, it is now an array of
five numeric values.
Advantage of such variables is that they have the highest degree
of flexibility, allowing highly generic code to be written
Disadvantage of such variables is the run-time overhead of
maintaining all the dynamic attributes, which could include array
subscript types and ranges.
29
Scope
The range of statements in which the variable is visible
A variable is visible in a statement if it can be referenced in that
statement.
A variable is local in a program unit or block if it is declared
there.
The nonlocal variables of a program unit or block are those that
are visible within the program unit or block but are not declared
there.
Global variables are a special category of nonlocal variables
Global
Non-local
local
30
Scope
Static scope
the scope of a variable can be statically determined
—that is, prior to execution.
There are two categories of static-scoped languages
those in which subprograms can be nested, which
creates nested static scopes
those in which subprograms cannot be nested
static scopes are also created by subprograms but
nested scopes are created only by nested class
definitions and blocks
Information: Ada, JavaScript, Common LISP, Scheme,
Fortran 2003+, F#, and Python allow nested
subprograms, but the C-based languages do not.
31
Scope
Static scope
Consider languages that allow nested subprograms
The reference to x begins here
but no declaration of x found
The reference to the variable x in sub2 is to the x declared in the
procedure big. This is true because the search for x begins in the
procedure in which the reference occurs, sub2, but no declaration for
x is found there
The search continues in the static parent of sub2, which is big, where
the declaration of x is found. The x declared in sub1 is ignored,
32 because it is not in the static ancestors of sub2.
Scope:- Illustration
big
sub1
var x = 7;
sub2();
sub2
var y = x;
var x = 3;
sub1();
33
Scope
Blocks
Many languages such as Java and C++ allow new static scopes to
be defined in the midst of executable code.
Allows a section of code to have its own local variables whose
scope is minimized
Such variables are typically stack dynamic, so their storage is
allocated when the section is entered and deallocated when the
section is exited
The C-based languages allow any compound statement to have
declarations and thereby define a new scope.
Such compound statements are called blocks. Consider the following
example and assume list was defined to be an array of integers:
The scopes created by blocks,
which could be nested in larger
blocks, are treated exactly like
those created by subprograms
34
Scope
Dynamic Scope
is based on the calling sequence of subprograms, not on their
spatial relationship to each other
Thus, the scope can be determined only at run time.
Consider the following code:
Assume that dynamic-scoping rules apply to
nonlocal references.
The meaning of the identifier x referenced
in sub2 is dynamic—it cannot be
determined at compile time.
It may reference the variable from either
declaration of x, depending on the calling
sequence.
35
Scope: Dynamic scope
Consider the two different call sequences
for sub2 in the example.
1. big calls sub1, which calls sub2. In this
case, the search proceeds from the
local procedure, sub2, to its caller,
sub1, where a declaration for x is
found.
So, the reference to x in sub2 in
this case is to the x declared in
sub1.
2. sub2 is called directly from big. In this
case, the dynamic parent of sub2 is
big, and the reference is to the x
declared in big.
Note that if static scoping were used, in either calling sequence
discussed, the reference to x in sub2 would be to big’s x.
36
Scope and Lifetime
Sometimes related
Consider a variable a declared within a method which have
no method calls.
In this case the lifetime and the scope of the variable
is the same.
Consider variable a: The scope and
lifetime of the variable begins when
the function started and ends when
the function terminated.
Scope:- Spatial
Lifetime:- Temporal
37
Scope and Lifetime
Sometimes not related
Consider a variable declared in a function using the specifier
static in C++
Statically bound to the scope of that function
Statically bound to storage
So, 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
Also unrelated when subprogram calls are involved
38
Scope and Lifetime
Sometimes not related
The scope of the variable sum is completely contained within
the compute function.
It does not extend to the body of the function printheader,
although printheader executes in the midst of the execution of
compute.
However, the lifetime of sum extends over the time during
which printheader executes.
Whatever storage location sum is bound to before the call to
printheader, that binding will continue during and after the
execution of printheader.
compute printheader
…
Variable sum is not visible
int sum;
… … in printheader function
Printheader()
39 ….
Referencing Environment
The referencing environment of a statement is the collection of
all variables that are visible in the statement
The referencing environment of a statement in a static-scoped
language is the variables declared in its local scope plus the
collection of all variables of its static ancestors that are visible.
The referencing environment for the
subprogram sub2 contains x and y
40
Named constants
are variables that are bound to values only once
are useful as aids to readability and program reliability.
Readability can be improved, for example, by using the name pi instead
of the constant 3.14159265.
Another important use of named constants is to parameterize a
program. Compare the following codes.
41
Named constants
Binding to values can also be dynamic:
• The value of result will be calculated when the value of width
is known; and from there on, result is constant.
Java uses the final keyword to declare named constants either
dynamically or statically.
C# has two keywords to create named constants
Using const keyword where the variable should be assigned
with a literal or other const members.
Using readonly keyword where the variables are dynamically
bound to values.
42
Assignment #1: Language Paradigms
Write a brief note with clear examples where necessary on key
concepts of the following programming paradigms (10%).
Only a hand written submission is accepted.
Imperative programming G1
Object-oriented programming G2
Concurrent programming G3
Functional programming G4
Logic programming G5
Generic Programming G6
Scripting languages G7
43