Programming Language Design Issues
Programming Language Design Issues
2
Influences on Language Design
• Several factors influence the basic design of
programming languages.
• Most important of these are Computer Architecture
and Programming Design Methodologies.
• Computer Architecture
• Most Programming languages have been designed
around the prevalent computer architecture, called
the von Neumann architecture.
• These languages are called imperative languages.
3
Influences on Language Design… cont’d
• Computer Architecture … cont’d
• von Neumann architecture.
• Both Data and programs are stored in memory
• CPU, which executes instructions, is separate from the
memory
• Therefore, instructions and data must be transmitted, or
pied, from the memory to the CPU.
• Results of operations in the CPU must be moved back
to memory.
4
Influences on Language Design… cont’d
• Computer Architecture … cont’d
• von Neumann architecture.
5
Influences on Language Design… cont’d
• Computer Architecture … cont’d
• von Neumann architecture… cont’d
• Because of the Von Neumann architecture, the
central features of imperative languages are
• Variables, which model the memory cells;
• Assignment statements, which are based on the
pipping operation;
• Iterative form of iterations, which is the most efficient
way to implement iteration on this architecture.
• Why is iteration operation fast on Von Neumann
computers?
6
Influences on Language Design… cont’d
• Computer Architecture … cont’d
• von Neumann architecture… cont’d
• The execution of a machine code program on a von Neumann
architecture computer occurs in a process called the fetch-execute
cycle.
• Each instruction to be executed must be moved from memory to the
processor.
• The address of the next instruction to be executed is maintained in a
register called the program counter.
• Initialize the program counter(pc).
RepeatAlgorithms
forever for fetch-execute cycle
Fetch the instruction
1. Repeat forever pointed to by the pc
1.1 Fetch
Increment the the
pc instruction
to point at pointed to by
the next the pc
instruction
1.2 Increment the pc to point at the next instruction
Decode the instruction
1.3 Decode the instruction
1.4 the
Execute Execute the instruction
instruction
2. End repeat
End repeat
7
Influences on Language Design… cont’d
• Computer Architecture … cont’d
• von Neumann architecture… cont’d
• Algorithms for fetch-execute cycle
Algorithms for fetch-execute cycle
1. Repeat forever
1.1 Fetch the instruction pointed to by the pc
1.2 Increment the pc to point at the next instruction
1.3 Decode the instruction
1.4 Execute the instruction
2. End repeat
10
Language Paradigms
• Major paradigms… cont’d
• Imperative(procedural) programming paradigm
• Expresses computation by fully-specified and fully-controlled
manipulation of a named data in a stepwise fashion.
• A program consists of a sequence of statements, and the execution
of each statement causes the computer to change the value of one
or more locations in its memory, that is, to enter a new state.
• Data or values are initially stored in variables (memory locations),
taken out of ( read from) memory, manipulated in ALU, and then
stored back in the same or different variables (memory locations).
• The syntax of such languages generally has the form
statemetn1;
statement 2;
…….
11
Language Paradigms
• Major paradigms… cont’d
• Imperative(procedural) … cont’d
• Abstracts the von Neumann machine.
• FORTRAN, COBOL, C, Pascal, PL/I are all imperative
languages.
• Because of the Von Neumann architecture, the
central features of imperative languages are
• Variables, which model the memory cells;
• Assignment statements, which are based on the
pipping operation;
• Iterative form of iterations, which is the most efficient
way to implement iteration on this architecture.
12
Language Paradigms
• Major paradigms… cont’d
• Functional(Applicative) programming paradigm
• Expresses computation in terms of mathematical functions.
• It differs from imperative and object-oriented
• No memory location
• Each function will take a number of values as input (parameters) and produce
a single return value ( output of the function)
• The returned value can not be stored for later use.
• It has to be used either as the final output or immediately as parameter value of
another function.
• Functional programming is about defining functions and organizing the return
values of one or more functions as parameters of another function.
• Syntax: function(function-1(…(function2(function1(data)))…))
• ML, Scheme and LISP are examples of functional languages.
13
Language Paradigms
• Major paradigms… cont’d
• Rule-based(declarative) programming paradigm
Expresses computation in terms of logic predicates.
A logic program is a set of facts, rules and questions.
Rule-based languages execute by checking for the presence of a
certain enabling condition and, when present, executing an
appropriate action.
The enabling conditions are usually written in terms of predicate
calculus and take the form:
Enabling condition1 action1
Enabling condition2 action2
. . . .
Enabling conditionn actionn
Address
Value
Type
Lifetime
Scope
Variables( continued)
18
Address:-
the address of a variable is the machine
memory address with which it is associated.
A variable may have different addresses at different times during execution
A variable may have different addresses at different places in a program
It is possible to have multiple variables that have the same address.
If two variable names can be used to access the same memory location, they are
called aliases
Aliases are created via pointers, reference variables, C and C++ unions
Aliasing is a hindrance to readability because it allows a variable to have its value changed by
an assignment to a different variable.
Aliasing also makes program verification more difficult.
Two pointer variables are aliases when they point to the same memory location. The same
is true for reference variables. This kind of aliasing is simply a side effect of the nature of
pointers and references.
Variables( continued)
Type:-The type of a variable determines the range of values19the
variable can store and the set of operations that are defined for
values of the type; in the case of floating point, type also
determines precision.
Value:-The value of a variable is the contents of the memory cell
or cells associated with the variable.
The l-value of a variable is its address
because the address is what is required when the name of a variable
appears in the left side of an assignment.
The r-value of a variable is its value
because it is what is required when the name of the variable
appears in the right side of an assignment statement.
It is convenient to think of computer memory in terms of abstract
cells, rather than physical cells.
Binding Times - Terminology
• A binding is an association between an attribute and an entity, such as
between a variable and its type or value, or between an operation and a
symbol.
• Binding time is the time at which a binding takes place.
• Possible binding times:
– At language design time --e.g., bind operator symbols to operations.
– At language implementation time --e.g., a data type, such as int in C, is
bound to a range of possible values at language implementation time.
– At compile time –e.g., a variable in a Java or C program is bound to a
particular data type.
– At load time –e.g., (a variable in Fortran, and a static variable in C) may
be bound to a storage cell when the program is loaded into memory.
That same binding does not happen until run time in some cases, as
with variables declared in Java methods.
– At Run Time –e.g., bind a nonstatic variable to a memory cell.
– At link time –e.g., a call to a library subprogram is bound to the
subprogram code at link time.
20
Binding Times - Terminology
• Def: A binding is static if it first occurs before run
time and remains unchanged throughout
program execution.
• Def: A binding is dynamic if it first occurs during
execution or can change during execution of
the program.
• Tradeoff: In general,
– Early binding -> greater efficiency, less flexibility
(unchanged).
– Late binding -> more flexibility, less efficiency.
(Discuss flexibility and efficiency)
21
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
A statement in a program listing variable names and
specifies that they are a particular type.
Example: int x,y; float radious;
Implicit declaration
A means of associating variables with types through
default conventions
done by the language processor, either a compiler or
an interpreter.
22
Binding: Type Binding
Implicit declaration
Several different bases for implicit variable type bindings.
1. Naming Conventions:
the compiler or interpreter binds a variable to a type based on
the syntactic form of the variable’s name.
For example, in Fortran:
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.
Thus, with implicit typing, the variable COUNT is REAL whilst the variable
KOUNT is an INTEGER.
2. Type inference (Context)
In context, the 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.
25
Storage Bindings and Lifetime
Storage/Memory layout
Free
31
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
32
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
33
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
34
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
35
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
36
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
37
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
38
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
39
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
40
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
41
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/deallocation overhead
Slower accesses because indirect addressing is
required
Subprograms cannot be history sensitive (no
static variables)
42
Storage Bindings and Lifetime
Explicit Heap-Dynamic Variables
Explicit heap-dynamic variables are memory cells that are
allocated and deallocated by explicit run-time instructions
written by the programmer
Allocation commands such as “new” and deallocation commands
such as “delete” in C++
Memory cells are allocated from and deallocated to a collection
of memory cells often referred to as the heap
These variables can only be referenced through pointers or
reference variables.
In Java, all variables are reference variables and are heap-
dynamic
Explicit heap-dynamic variables are bound to types at compile
time, but to memory at the time they are created/ie run-time
Used to create dynamic structures, such as linked lists and trees,
43 that need to grow and/or shrink during execution
Storage Bindings and Lifetime
Explicit Heap-Dynamic Variables
Deallocating or destroying Explicit Heap-Dynamic
Variables
Explicit: by using operators (Example C++ uses
delete operator)
45
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: