You are on page 1of 24

1

CS09 404 PROGRAMMING PARADIGM


(Module 1 Notes)
 This module discusses in 4 different areas: Evolution of Programming languages, Fundamental Paradigm,
Standard notations for describing a language and Imperative programming features. Keep this in mind
while studying.

A. PROGRAMMING LANGUAGES

Role of Programming Languages:


P. L is a tool for instructing machines. They are notations, used for specifying organizing and
reasoning about computations. The language should:

 Making the computation convenient for people


 Making efficient use of computing machine
 Universal-i.e. accepted all over the world
 Natural-i.e. should have relation with natural languages
 Portable-i.e. machine independent
 Verifiable and understandable

Evolution of Programming Languages:

 Machine lang.: It is the native language of a computer. It is the notation to which the
computer responds directly. It consists of series of 0’s and 1’s to represent an instruction.
So the programs in machine lang. are unintelligible.
 Assembly Lang.: It is written in a low-level programming lang. consist of symbolic
instruction. Each symbolic instruction is called mnemonics, which is corresponding to a
machine instruction in binary.

Advantage: provide more control over handling hard ware units


Generate smaller and compact modules
Faster execution and more readable.
Disadvantage: have to remember machine specific instruction sets
Difficult to write complex programs

 High Level Lang.: It provides readable familiar notations in natural languages. The
advantages of High level lang. include machine independency, availability of program
memories, data types, structures and operations on primitive data.

Language Implementation on a machine: To bridge the gap between the high level
language and machine, we can use two different methods: Compilation and Interpretation.
2

Compiler: is translator that changes the program into a form suitable for execution is called
compiler and this process is called compilation. In compilation the source program is translated
first into an intermediate representation. The time taken for this is called translation time. Then
interpreter translate this into executable binary code. The time require for this is called run time.

Figure 1: Compilation

Interpreter: The interpreting is also a process of translation, but it is directly convert the high
level source program to machine executable form. i.e it retrieve the statement, determine the
action and perform the action. So, there is no distinction of translation and run times.

Figure 2: Interpretation

Comparison between Compiler and Interpreter:

 The compiler is more efficient than interpreter. The compiler first translate into a
intermediate form and run that code for execution. So, the run time translation is only
repeated. But, in case of interpreter, the line by line translation is processod and so it has
to repeat every time.
 Interpreter can be more flexible: Since interpreter provide repeated examination of
source text line by line, it is easy to identify the bugs and can modify the program with
less effort. For compilation this is not possible.

So in most machine combination of both compilation and interpretation is used.


3

B.PROGRAMMING PARADIGM Programming


Paradigm:-A paradigm means an example that sense a pattern or simply it is a model for doing
something. A programming paradigm implies a programming culture or programming styles. A
programming technique is related to an algorithmic idea of solving a particular class of
programs. The fundamental programming paradigms include:
 Imperative Programming: It action oriented. Here the program flow is based on the
actions. The program structure identifies the meaning and flow of the program. Eg:-
FORTRAN, PASCAL, C, ALGOL etc.
 Functional Programming: It is purely mathematical discipline. It uses the theories of
functions and the program flow is based on the calling sequence of the functions. Eg:-
LISP (“LIS”t”P”rocessor)
 Object oriented programming: It is the most popular paradigm used for complex
applications. The technique of OOPs considers the program as a real-world problem,
consider the elements as object. The objects are grouped logically as class.
Encapsulation, inheritance and polymorphism are the basic properties of OOPs. Eg:
Simula, C++, Java
 Logical Programming: This method is quite different from all other paradigm. Here the
programming is based on set of rules and facts. The program consists of queries and the
machine retrieves the result for the query using these rules and facts. Eg: PROLOG

C. LANGUAGE DESCRIPTION

Language Descriptions
Precise specification of a programming language is essential for describing the computational
behavior of the language. In general, formal specifications of a programming lang. provide the
following:

 Helps lang. comprehension


 Support language standardization
 Guides lang. design
 Aids compiler and lang. system writing
 Support program correctness
 Model software specification

Any programming language description can be classified according to its:

 Syntax, which deals with the formation of phrases


 Semantics, which deals with the meaning of phrases
 Pragmatic, which use the practical use of phrases
4

Syntax Description:

Syntax refers to the formation of constructs in the lang. and defines the relation between them, it
describe the structure of the lang. with out addressing the meaning of the constructors. Eg: int i;
this statement is the syntax for declaring a variable in C. and int 2i is invalid.

Abstract Syntax of a lang. identifies the meaningful components each constructor of the lang.
This syntax have two part- Lexical Syntax and Phrase-Syntax. The lexical syntax explains
how tokens are arranged into programs and the phrase syntax explain how tokens are arranged in
the program.

Tokens are the basic units of a programming language. E.g: +,-,%,if,else…….\

Keywords are the alphabetic character sequences that are meaning ful in a language. E.g:
if..else, do..while tec

The actual character sequence used to write down the occurance of a token is called spelling.

The tree representation of an abstract syntax is called Abstract Syntax Tree. It shows the
operator –operand relation of an expression. In this an operator is represented by root and
intermediate nodes. The operands should come at the leaf. This is also called parse tree.

Another method of representing the syntax is Formal grammars. Each programming lang. has a
vocabulary of symbols and rules for how these symbols to be put together to form phrases. This
is called grammars. This grammar describes the structure of a lang. with out considering the
semantics. A concrete syntax of a grammar is the written representation including the lexical
details such as placements of keywords and punctuation marks.
A Context Free Grammar (CFG) gives the notation for specifying concrete syntax. The
methods for writing this grammar include BNF. A grammar defines a set of all possible phrases
that constitute programs in the subject lang. together with their syntactic structures.
5

The CFG of a programming lang. have four part

 A set of symbols known as terminal symbols that are non-divisible symbols in the lang.
By conversion, the terminals are represented by lower case letters.
 A set of non terminal symbols known as variable symbols. That are the construct in
language. They represent the intermediate definitions with in the lang.
 A set of rules known as production rules that are used to define the formation of the
constructs.
 A distinguished non-terminal known as the Start symbol

The grammar of the lang. posses an hierarchical structure between the symbols. This tree
representation of grammer is called parse tree. In parse tree, the root is start symbol. The
non-terminals are represented by intermediate nodes and terminals are reoresented by
leaves. The relation is based on th productions of the grammar.

Consider a grammar rule “ A real number have integer part,a point and a fraction. This
real part can have one or more integers or digits. The fraction part may also contain one
or more digits.” Using this grammar, 12.11 is reperesented as follows.

Hear the left to right scan of tokens will retrieve the original expression or phrase. This is
called parsing.
The concept of the CFG can be independent of the notation used to write grammar.
Backus-Naur-Form (BNF) is one such form to represent the grammar. The BNF
notations include:
6

Nonterminals  between < >

Production  has two parts, left and right (head and body). The head and body are seperated by
“::=” symbol, read as can be.

Or |

BNF example:

<RN>::= <INT>.<FRACTION>

<INT>::= <INT><DIGIT.|<DIGIT>

<FRACTION>::=<DIGIT><FRACTION>|<DIGIT>

<DIGIT>::=1|2|3|4|….|9

Ambiguity: A grammar that represents a phrase associated with its language in two or more
distinct trees known as syntactically ambiguous grammar. If ambiguities exist, they are resolved
by establishing conversions that rule out all ambiguities exists.

E.g Consider the grammar, E::=E-E|0|1 The representation of 1-0-1 using this grammar has two
parse tree as follows:

Dangling Else Ambiguity is a well known example of syntactic ambiguity, which arises if the
grammar has the following production.

S::= if E then S| if E then S else S

Consider this conditional: if E1 then if E2 then S1 else S2 the statement becomes ambiguous
because, it is not clear to which if else belongs. The parse trees in this case are:
7

The dangling else ambiguity is typically resolved by matching an else with the nearest inner
matched if. Thus the second option will be selected by the compiler.

Derivation: is a process of reaching the conclusion in language with repeated application of


production. A derivation consists of sequences of strings beginning with the starting symbol.
Each successive string is obtained by replacing non terminal by right side of production. The
derivation can be top-down, bottom-up, left most and right most.

Variants of Grammar

It describes some variation in BNF to represent the grammars. This includes Extended BNF and
Syntax Diagram.

EBNF contain some extra notations that are not in BNF. The extra notations in EBNF are

 Braces { } to represent a sequence of zero or more instance of an element.


 Brackets [ ] to represent an optional element.
 Parenthesis ( ) to represent a group of elements.

E::= E+T|E-T |T in BNF is represented as E::= E {[+|-]}T

Syntax diagrams are pictorial representations of a grammar. In this the syntactic description and
equivalent BNF are represented graphically. The terminals are represented by circles and non
terminals are represented by square boxes. Eg: The syntax diagram of a grammar for real
number.
8

Semantic Description of a language


The semantic of a language mean what the words in the lang. means. The semantic of a
programming lang. support correct description and implementation of programming lang.,
systematic development and verification of the lang. and design of new lang. that are simpler.
There are 3 methods for representing the semantics of a lang. They are:

 Attributed Grammar
 Natural Semantics
 Denotational Semantics

An attributed grammar is a formal way to define attributes for the production of the formal
grammar associating attribute value. The attribute can be two types: Synthesized and inherited.

The Synthesized attributes get the values from the attributes attached to the children of its non
terminal. i.e these are the results of the attribute evaluation by rule. For example consider the
grammar for expression evaluator:

Then the expression 7*5 is evaluated as follows. Let val is the


synthesized attribute. Then E.val is the synth. Attribute for E and so on.
In synthesid attributes it is evaluated in bottom up manner. i.e attributes
values are computed by working from the leaves towards the root.
9

In this tree representation the nodes get the value or attribute from
the children nodes. That is why it is called synthesized attributes. The use of synthesized
attributes for the representation of the semantics is also called Syntax Directed approach of
defining semantics. The representations in which the production and semantic rules are written
together are called Syntax directed definition.

Inherited Attributes are passed down from parent nodes or sibling nodes. i.e. Inherited
attributes are attributes that are passed to a rule, as opposed to synthesized attributes, which are
returned from a rule. When a non-terminal A appears in the right side of the production, then it
is replaced by the inherited attribute of A (say A.in).

Natural semantics associates logical rule with the syntax of a language. The logical rules can be
used to deduce the meaning of a construct. This is used with PROLOG environment.

is written in logical semantics as

It is read as follows: “If E1 has value v1 and E2 has value v2, then plus E1 E2 has value, v1 +
v2.” In the expression plus a b the result depends on the value of a & b. So, to handle these value
we introduce an environment env.

means the value v1 binds to E1 in the environment env.

Denotationl Semantics is the approach to formalizing the meaning of the programming


language by construction mathematical objects called denotations. It is also called mathematical
semantics. The denotation will be function from input to output. A characteristic feature of
denotation is that, it not only assign a meaning to a complete program, but also a to every phrase
10

in the programming language. The denotations are enclosed in a double bracket [[ ]]. The double
bracket contain the syntactic phrase of a programming lang. It have two parts- Domain (identify
the types and syntax relevant to the lang.) and Semantic rules (synthesize the meaning of a
construct in terms of the component). So 2*4, 5+3, 008 in denotational semantics represent the
same abstract syntax 8. I.e. meaning [[2*4]] =meaning [[5+3]] .

Expression Notation

The programming languages use a combination of notations called Infix, postfix, prefix and mix
fix to represent expressions.

An expression is prefix notation is written as follows:

 Prefix of a constant or variable is constant or variable itself.


 The application of an operator OP to sub expressions E1 and E2 is written in prefix as
OP E1 E2

(Try the Definitions of Infix (E1 op E2) and Post fix (E1 E2 op).

Eg: A+B-23 is written in prefix as - + A B 23 and post fix as A B + 23 -.

Associativity and Precedence: To handle the ambiguity in expression we use precedence. An


operator at higher precedence is evaluated before the operator at lower precedence. The
precedence order is

* / have higher precedence than+ - .

The associativity is used to deal with the multiple occurrences of operator of same precedence
level. It can be left associative (the multiple occurrences of the operator are grouped from left to
right. +,-, *, /) or right associative (the multiple occurrences of the operator are grouped from
right to left eg: ex2).

D. IMPERATIVE PROGRAMMING

 In natural languages the imperative means commands. In computational languages the


imperative programming is paradigm in which computation will be interms of program
statements. The basic units of imperative programming are actions. Action modify the values
of a variables. These actions can be
 Computational (arithmetic)
 Control Flow( if, while)
 Input/output (File r/w)

The program flow is based on the actions, placement of statements. The reader can understand
the program from its structure itself.
11

 Design Principles:
The important considerations for the design of imperative paradigm are:
 Structured Programming: The structure of the program should be understandable. i.e.
from the structure and function & variable names we can identify the meaning of the
program.
 Efficiency: A language must allow an underlying machine assignment oriented machine
to be used directly and efficiently.
 Syntax Directed Control Flow:
 Structured control Flow: A program is structured if the flow of control through the
program is evident from the syntactic structure of the program text. i.e the program
should help us to understand what the program does. In imperative, it is single entry/
single exist control flow.
 Composition of Actions: Sequence of statements can be grouped into a compound
statement by inclosing it between keywords begin and end. In C, we use { } for the same
purpose. This is useful for block oriented control flow.
 Selection Statements: It select one of two alternaive substatements for execution. E.g.:
If<exp> then S1 else S2. If conditions are nested then avoid nesting at then part..ie use
nested if as:
if ….then…
else if …then….
else if…..then….
else…….
 Looping Constructs: The repeated execution of a block of codes can be done with help
of looping constructs. This can be two types:
Indefinite Iteration : The no. of execution cannot be pre-determined. Eg:
While <exp>do <statement> repeat the statement (body) as long as expression is true.
It check the expression before entering to the loop.
Repeat S until (exp) will repeat the statement until the condition is true. It checks the
exp after the first execution.

  Definite Iteration: The no. of iteration can be predefined.

Eg: for<name>: <exp> to <exp> do <Statement>

For i: 1 to 10 do A[i]=10;

For i: 10 down to 3 do A[i]=0;

 Case Construct : A case statement uses the value of an expression to select one of the
several alternatives (sub expression) for execution.
Case exp of
<constant 1>: <statement1>
12

<constant 2>: <statement2>


….\
end;
case constant can appear in any order, need not be consecutive. Several constant can use
same sub expression but case constant must be distinct. Lang. like C, modula2 allows
default case.
 Handling Special Cases:
 Break statement send control out of the enclosing loop to the statement following
the loop.
 Continue statement repeat the enclosing loop by sending control to the beginning
of the loop.
 Return statement sends the control back to the caller procedure.
 Goto L interrupts the normal flow from one statement to next in sequence control
flow to the statement labeled L.
Implementation of Case Construct:
The implementation of the statements in machine is as follows:

Translation for E

If E fails goto

Translation of S

Goto

But, case statements are difficult to implement if the case constants are not consecutive. So,
we have three methods for implementing case statements:
 If the cases are less than 7, implement using conditionals i.e nested if…else
 If constants are large then a special data structure called Jump Table is used. The
ith entry to the jump table is the codes for constant i.
 If cases are large and many of jump table entries are vacant, then compiler
implements the cases using Hash Table.
13

 Syntactic Concern for Design


It deals with the details such as he placements of operators, keywords and semi column that have
nothing to do with the meaning of the program. The do affect the usability of the lang.

Two important syntactic concern are placement of semicolon and Dangling else ambiguity.

 The delimiter like ; are used to terminate a sequence or separate. In pascal notation if it
appears between elements, it is consider as a separator and if it is at the end of the
statement it is considered as the terminator. To avoid this ambiguity modula2 uses a key
word end to terminate the statement.
 The dangling else ambiguity arises when if nested at then part. This will result in
problem like which if does else belongs. Most lang. resolve it by matching the else with
nearest if. Modula2 avoid this by ending the statement with end keyword. So, if exp then
if exp then S1 else S2 is written in any one of the form:

if exp then if exp then S1 end else S2 end

if exp then if exp then S1 else S2 end end

 Role of Types:
A data object means something meaningful to an application. The data representation means the
organization of values in a program. Thus object have corresponding representation in program.
This data representation are built up from values that can be manipulated directly by underlying
machine. How these data representations are built up is described by types. So, role of types can
be:

 Represent data objects


 Layout values in underlying machine
 Check that operators applied correctly

Basic Types:
atomic or primitive types.

Enumeration: finite sequences of names are listed between two parenthesis ( ).

Eg: type day:=(mon,tue, wed,thu,fri,sat,sun); The mon,…sun are called elements of type day.
The operations in enumeration are

 Ordinal: maps the numerical position of the element. Ord(sun)=7;


 Successor: succs(x) give name after x. [note: succ(sun)=null.]
14

 Predecessor: pred(x) gives the previous element x; note: [pred(mon)=null]

Integers and Reals: The values with integer and real are determined by underlying machine.
Commonly they ranges from –maxint to maxint. The operations with iintegers and real are

<, <=, >,>=,<>,= +,-,*,/,div,mod,and,or

Short circuit Evaluation: In this the second operand evaluated iff necessary. This is a technique
for compiler optimization.

Eg: if (i>10 && a==b) in this if i<10, the whole expression is false, so a==b is not evaluated.

Subrange: They are special case of basic type. They restrict the range of values of an existing
type.eg: 0..99. or type year:=1900 .. 1999.

Layout of basic Types: The basic types are laid out by using machine representation values. On
most machines char fit in a byte, integers in a word, and real numbers in two contiguous words.

Coercion: Automatic Type Conversion: In C characters are automatically coerced to integers.


For example, EOF is a character but it is evaluated using an integer constant associated with that.
When floating points are added with integers the integer is coerced to float. These are implicit
type conversions.

Compound Types:
They are built up from basic types. Eg. Array, Record, union, set and Pointers

Arrays:

An array specify the index of the first and last elements in the array and the type of all elements
in the array. The array is collection of homogenous type elements. An array is declared by
following syntax: array[<simple>]of <type>. Here simple represents the range of array and type
is the type of elements in the array.

Array Layout: The array is stored as memery cells inconsecutive location, cell width depends
on the type. var A: array[low..high] of T will create an array of cells from high to low. The
high and low are indices of array A.

A[low] A[low+1] A[low+2] ….. … …. …. A[high]


Let location of base= A[low], w =width of each cell then location of A[i] is calculated by
follwing formula: i*w+ (base-low*w)

In this i*w is calculated at runtime The portion bae-low*w can be pre-computed as constant c at
compile time. Then the address of A[i] will be i*w+c;

Layout of Array of Array: ie. 2D array.


15

It is declared as Var M: array[1..3]of array[1..2] of Integers. It is laid in memory as follows:

This type of layout is called row major layout (In M[i][j]


the second index varies frequently than first index i).
Formula for finding the location of M[i][j] is given by
i*w1 +j*w2 + base-low1*w1-low2*w2. Here, low1 and
low2 are lower limit of first and second indices. W2 is
cell width of type and w1=n2*w2, where n2=high2-
low2+1,no. of elements in the row.

If the first index of M[i][j] varies faster than second index, it


is called column major layout. M[1][1], M[2][1], M[3][1], M[1][2], M[2][2], M[3][2]

In algol60, the array can be declaring using conditionals. Var A: array[if c<0 then2 else 3]..20] if
integers. Here, if c is known at compile time then the layout can be done at compile time.

In C, the layout is known at compile time and storage allocation is down at run time. If keyword
static is used, then both storage and layout are done at compile time. So the calculation of array
bound can be;

 Static evaluation
 Evaluation upon procedure entry
 Dynamic Evaluation

Records:

Records allow variables to an object to be grouped together and treated as a unit. The different
elements are called field of record. Declaration Syntax is: 
record
<name1>:<type1>;
    <name2>:<type2>;
               …..
    <name k>:<type n>;
end;
Eg: type complex=record
re, im:=real;
end;
16

Variables for record type can be declared as follows:


var x, y, z: complex;
The operation in record type is performed by . (dot) operator. Eg: z.re:=x.re+y.re;
Comparison Between Array and Records:
Array Record
It is a collection of elements of homogeneous It is the collection of heterogeneous type.
type.
The elements of array are selected at run time. The elements selected at compile time.
The indices are used to access the array .(dot)operator is used to access the record
elements fields.

Unions and Variants of Records:

A record is used to represent the objects with same property. A variant record represent the
object with some but not all properties in common. i.e it have fixed part and variant part. Union
is special case of variant record, in which no common field exist.

Generally variant record can be represented as:


case <tagname> : <type name> of
<const1>:(<fields1>);
<const2>:(<fields2>);
….
<const n>:(<fields n>);
The sate depends on the special field called tag field with tag name and type name. Const1 to
const n are distinct state of the variant record.

Example: Consider a binary tree. In tree the node can be with no child, one child or left and right
child. So,
Type kind= (leaf, unary, binary);
Node = record
C1 T1;
C2 T2;
Case k: kind of
leaf: ();
unary: (chil2:T3);
binary: (lchild, rchild: T4); end;
17

Here C1 and C2 are common fields for T1 and T2. The third part depends on the tag kind.

The space reserved for a variant part is just enough to hold the fields in the largest variant.

Set:

Set is a collection of elements. It can efficiently implemented using bits. A set can be represented
using [ ] brackets. It can be empty [ ], subrange [1..3] or list [+.-.*./]

A type set is represented as var A: set of [1..3].

This set can be [ ],[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]

The set can be implemented using bits. In this the presence of an element is represented by 1 and
absent by 0. So, [1,3] is represented as 101. So, a set of n elements can be represented by a n bit
vector.

The set operations include: A+B  Insertion {a: a in A or a in B}

A*B Intersection { a: a in A and a in B}

A-B Set difference { a: a in A and a not in B}

A/B Symmetric difference (A-B) U (B-A)

Pointers:

A pointer type is value that provides indirect access to the element of a known type. It is used
for:

 Efficiency: Instead of moving or copying a large data structure move or copy pointers
 Dynamic Data: Data structures that grow and shrink during the execution

Pointer Type: ↑<type name>

Eg: type link = ↑cell; or type ptr = ↑integer

Operations On Pointers:
18

 Dereferencing: ↑ have double duty as prefix and post fix. type ↑T implies the pointer
points to the type T. p↑ imply the object pointed to by p; The later is called dereferencing.
 Dynamic Allocation on heap: The new( ) is used to allocate a new pointer. The new( )
leave a pointer p pointing to a newly allocated data structure of type T on heap.
 Assignment: The pointer assignment can be performed between same type of pointers.
 Equity Testing: If two pointers points to same data structure then they are equal. If not,
they are pointing to different locations.
 Deallocaion: The deallocaion of pointers is done by dispose() command.

Linked Lists: The data structure that Grow and shrink can be constructed using records and
pointers. By static layout principle, the size and layout of the storage used for each types are
known statically before the program runs. So, we can define the fixed size cells as:

Type link = ↑cell;

\cell = record

Info : integer;

Next= link;

End;

Dangling Pointers: It is a pointer to storage that is being used for another purpose, typically the
storage has been deallocated. The storage that is allocated but inaccessible is called garbage. A
program containing garbage are called memory leaks. The memory leaks leads to dangling
pointer.

Example: p:=q, leave p & q points to the same cell, pointed by q. The cell pointed by p is now
inaccessible and so memory leak.

 Types and Error Checking: The types can be used for the binding of values to an
expression and error checking of expressions. So, here the types extend from values to
expression.
19

Variable Binding: In most of the imperative languages, a fixed type is assigned (bound)
with a variable. If a variable is declared as integer, it must denote the integer value. This
value can be changed during the execution. So, a variable binding associate a property to
a variable. A binding is static, if it is done at compile time (early binding) and if it is at
runtime it is called dynamic binding (late binding).

Types Systems: The widely followed principle is that every expression should have a
type that is known at compile time. The type system for a language is a set of rules for
associating a type with the expression. A type system rejects an expression if it does not
associate a type with the expression. Example for a type system: If expression E and F
have same type, then expressions E+F, E-F, E*F and E/F have that same type.

Basic Rule for Type Checking:
When a function from a set A to a set B is applied to an element of set A, the result is an
element of set B.
Arithmetic Operators are functions. Associated with each operator op is rule that
specifies the type of an expression E op F of the type E and F. Eg: If E and F are integers
then E + F have the type integer.
Overloading: The operators + and * can be different meaning depending on the context.
This is called overloading.
Coercion: The implicit type conversion by the compiler is called coercion. In 2*3.14 the
2 is coerced in to real.
Polymorphism: A polymorphic function has a parameterized type or generic type. For
example data structure like stack, queue can be defined on any type. So stack of integers
and stack of characters are possible. A polymorphic type allows a data structure to be
defined once and then applied later to any desired type.

Type Equivalence:
var x, y: array[0..9] of integers
var z: array[0..9] of integers
In Pascal context x, y are equal but not z. In C context x, y, Z are equal.
This leads to the definition of structural equivalence.

Two type expressions are structurally equivalent under following rules:


SE1: A type name is equivalent to it self.
SE2: Two types are structurally equivalent if they are formed by applying the same type
constructor to structurally equivalent types.
SE3: After a type declaration, type n=T, the type name n is structurally equivalent to T.

So, by these rules, char and char are structurally equivalent and so S and E:
Type S= array [0..99] of char;
20

Type T= array [0..99] of char;

Name Equivalence: The type name equivalence can be of following type, by applying
SE1-SE3:
 Pure Name Equivalence: A type name is equivalent to itself, but no constructed
type is equivalent to other constructed type.
 Transitive Name Equivalence: A type name can be equivalent to itself and be
declared equivalent to other types names. In the following example, T, S, U are
equivalent to each other and equivalent to integer, because integer is a type name
also.
type S=integer;
type T=S;
type U=integer;
 Type Expression Equivalence: A type name is equivalent only to itself. Two type
expressions are equivalent only if they are formed by applying same constructor to
equivalent expressions. i.e the expression have to be identical.

Circular Types: Linked data structure give rise to recursive or circular type.

type link = ↑ cell;


type cell = record
Info: integer;
Next: link;
end;
In this, the link depends on cell, and cell is defined in terms of link. This lead to the circular type.

Static and Dynamic Type Checking: Type checking ensures that the operations in the program
are applied properly. It is the mechanism to prevent errors. A type error occurs if a function f
expects an argument of type S, but f is applied some a, that does not have type S. A program that
run without type error is called type safe.

In Static checking, the programs are examined for type errors during translation. Using the rules
of a type system, a compiler can infer from the source text that a function f will applied to an
operand a of the right type, each time the expression f(a0 is called.

The dynamic checking is done at running time, by inserting extra code into the program to
detect the impending errors. Extra code for dynamic checking use space and time, so it is
expensive and seldom used. i.e the static checking sufficient for the program and dynamic values
of types are rarely checked.
21

The effectiveness of the type system can be referred by Strong and Weak type system. A type
system is Strong if it accepts only safe expressions. i.e. the expressions accepted by strong
systems are guaranteed to be executed with out errors. A type system is Weak if it is not strong.
A weak system allows some unsafe program to slip through.

 Introduction to Procedures
Procedures are a construct for giving a name to apiece of coding, called body. When the name is
called the body is executed. Each execution of the body is called activation of the procedure.
Variable names in an imperative lang. are a sequence of mapping from a source text to its value
at run time. This mapping includes scope, activation and state.

The procedures take two forms:


A function procedure is a procedure which returns a value and a proper procedure is which
does not return a value.
Procedure Call: The use of the procedure is referred as procedure call. Functions are called as
in expression eg: r=sin(x); and proper procedures are called as atomic statements: eg: read(x);
Prefix notation is the rule for procedure call. The syntax: <procedure-name> (<parameters>)
The parameters in the call are referred as actual parameters and the parameters in procedure are
called formals.
The elements of the procedure include:
 A name for the declared procedure
 A body consisting local variables and statements
 List of formal parameters
 An optional result type

Example:

int function area(int x, int y) { int a=x*y; return a;}

Procedure name area


Body statements a=x*y;
Formals x,y
Result type int

Recursive procedure is a special case, where the procedure can activate from wiyhin its own
procedure body, either directly call by itself or indirectly call by other procedure. A recursive
procedure have multiple activation in progress at same time. Example:

function f(n: integer):integer begin if n=0 then f:=1 else f:=n*f(n-1); end;
22

Benefits of Procedures:

 Procedures are one way of organizing the programs.


 The procedures separate what from how, which leads to the better understandability of
program
 Procedure abstraction: the procedure abstract the implementation details away and think
in terms of operation that are relevant to the problem
 Implementation Hiding: Algorithms isolated within the procedure can be modified by
changing the procedure with out affecting the rest of the program.
 Modular Programs: The program can be partitioned in to meaning ful modules which can
be understood easily.
 Libraries: Standard operations of useful procedures are a way of extending the lang.

Parameter Passing Methods:

Parameter passing refers to the matching of actual with formals when a procedure call occurs.
Differing interpretation of what a parameter leads to different parameter passing methods. Theay
are: Call by value, call by reference and call by value reference.

Call by value: Under call by value the formal parameter corresponds to the value of an actual
parameter. Let x be a formal of procedure P(x) and we call P (E), then x takes value of E. In this
case the formal x has no effect on actual E.

E.g.: Swap(x, y) procedure swap(x, y: T);


var z: T;
begin z: =x; x: =y; y: =z; end
The call swap (a, b) does nothing to a and b, because only the value of a and B are assigned to x
and y.
Call by Reference: Here, a formal parameter becomes a synonym for the location of an actual
variable. Instead of passing the value of the parameter, the location is passed to the procedure.
The changes in formals thus affect he actual. For ex; consider the function swap(x, y).
procedure swap (var x: integer; var y: integer);
var z: integer;
begin z=x; x=y; y=z; end
The key word var represents the reference variable, in Pascal. Both x and y are reference
variables. Then call of swap (a, b) do the following: copy address of a to x and b to y. Then
exchange the values at the address stored in x and y. So this change affect the values of a and b.
In C, the address is passed by swap(&a, &b) and pointer variables are represented using *.
23

Call by value Result: This is also called copy-in/copy-out because the actual are initially copied
into the formals and formals are eventually copied back out to the actual. Actuals with locations
are treated as follows:

 Copy in Phase: Both the values and locations of the actual parameters are computed. The
values are assigned to the corresponding formals, as in call by value, and the locations are
saved for the copy out phase.
 Copy out phase: After the procedure body is executed, the final values of the formals are
copied back to the location computed in the copy in phase.
Scope rule for Names

Nested Scope

Activation Records

Associated with each activation of a procedure is storage for the variables declared in the
procedure. The storage associated with the procedure is called activation record. In a sequential
language, control can be in most one procedure at a time. When P calls Q, execution of P hold
when control flows to Q and execution of Q resumes when control return from Q. So, control
flows between procedure are a last in first out (LIFO) manner.

The flow of control between activations can be depicted by tree called activation tree. The nodes
in the tree represent activations. When activation P calls activation Q, the node for P has the
node for Q as a child. If P calls Q before it calls R, then the node for Q appears to the left of the
node for R:

An activation record consists of following elements:

Control Link
Access Link
Saved state
Parameters
Function result
Local variable
24

Data needed for the activation of a procedure is collected in a record called activation record or
frame. The record contains storage for local variables, formal parameters and any additional
information needed for the procedure activation. E.g.:

function readentry (u:Link):boolean;

var i: integer;

C: char;

begin…end;

In this code, activation record includes, storage for the actual parameter u, the Boolean result, the
variables I and c, any temporary storage needed for evaluating expressions within the function
body and storage needed to manage activations.

 In a language with recursive procedures, each activation has its own activation record.
 Control link also called dynamic link points to the activation record of the run time caller.
 Access link also called static link is used to implement lexically scoped languages.

Stack allocation & Deallocation:

The stack discipline allows storage to be reused efficiently. Storage for local variables is
allocated when activation begins and it is released when activation ends. The records are
allocated in LIFO manner.

Drawback: A stack can be use dif storage for locals is not needed once an activation ends. The
storage can then be deallocated.

Heap allocation & Deallocation:

A general technique for managing activation record is to allocate storage for them in an area
called heap. The records stay on the heap as long as they needed. A technique called garbage
collection is used to automatically reclaim storage that no longer needed.

The life time of an activation record begins when the activation record is allocated and ends
when the location in the activation record can no longer be accessed from the program. That is,
the allocation and life time is not tied with LIFO manner.

The static variables with in a procedure retain their values between activations: they are shared
by all activations of the procedures. Local variables are bound to distinct storage in each
activation, except if they are declared to be static. The life time of a static variable is the entire
computation. It retains its value from activation to activation.

ALL THE BEST!!!

You might also like