Вы находитесь на странице: 1из 126

PRINCIPLES OF PROGRAMMING LANGUAGES

(For M.Sc Computer Science, Semester - I)

Prepared By

C.SATHYA CHARANYA MCA. M.PHIL., (P.HD)

DEPARTMENT OF COMPUTER SCIENCE


1. UNIT-I........................................................................................................................................ 1

1.1 Language Design Issues .................................................................................................... 1

1.2 History-Role of Programming Languages................................................................. 1

1.3 Role of programming languages ...................................................................................... 3

1.4 Programming environments............................................................................................. 7

1.5 Impact of machine Architectures ..................................................................................... 7

1.6 Language Translation Issues .......................................................................................... 12

1.7 Stages in Translation ........................................................................................................ 14

1.8 Formal Translation Models ............................................................................................. 17

1.9 Recursive Descent Parsing .............................................................................................. 26

2. UNIT-II .................................................................................................................................... 30

2.1 Modeling Language Properties ...................................................................................... 30

2.2 Formal Properties of Languages .................................................................................... 30

2.3 Language Semantics ........................................................................................................ 30

2.4 Elementary data Types Properties of Types and Object ............................................. 33

2.5 Properties of Types and Object ...................................................................................... 33

2.6 Scalar Data Types ............................................................................................................. 40

2.7 Composite Data Types..................................................................................................... 42

3. UNIT - III ................................................................................................................................. 47

3.1 Encapsulation .................................................................................................................... 47

3.2 Structured Data Types ..................................................................................................... 47


3.3 Abstract Data Types ......................................................................................................... 51

3.4 Encapsulation by subprograms ...................................................................................... 52

3.5 Type Definitions ............................................................................................................... 55

3.6 Inheritance ......................................................................................................................... 57

3.7 Polymorphism .................................................................................................................. 61

4. UNIT- IV .................................................................................................................................. 62

4.1 Functional Programming ................................................................................................ 62

4.2 Programs as Functions..................................................................................................... 62

4.3 Functional Programming in an Imperative Language ............................................... 70

4.4 LISP..................................................................................................................................... 71

4.5 Functional Programming with static typing ................................................................ 73

4.6 Delayed Evaluation .......................................................................................................... 77

4.7 Mathematical Functional Programming ....................................................................... 81

4.8 Recursive Functions and Lambda Calculus ................................................................. 82

4.9 Logic Programming ......................................................................................................... 91

4.8 Logic and Logic Programs .............................................................................................. 91

4.9 Problems with logic programming ................................................................................ 97

5. UNIT -V ................................................................................................................................... 98

5.1 Formal Semantics ............................................................................................................. 98

5.2 Sample small language .................................................................................................... 98

5.3 Operational Semantics ..................................................................................................... 99

5.4 Denotation Semantics .................................................................................................... 101

5.5 Axiomatic Semantics ...................................................................................................... 103

5.6 Program correctness....................................................................................................... 103


5.7 Parallel Programming .................................................................................................... 105

5.8 Parallel Processing and programming languages ..................................................... 105

5.9 Threads ............................................................................................................................ 107

5.10 Semaphore ..................................................................................................................... 107

5.10 Monitors......................................................................................................................... 109

5.11 Message Passing ........................................................................................................... 111

5.12 Parallelism Non Imperative Languages.................................................................... 115


Core Course-IV-17PCS04 - PRINCIPLES OF PROGRAMMING LANGUAGES

UNIT - I
Language Design Issues: History-Role of Programming languages - environments -
Impact of machine Architectures - Language Translation Issues: Programming language
Syntax- Stages in Translation - formal Translation models - recursive descent Parsing
UNIT - II
Modeling Language Properties: Formal Properties of Languages- Language Semantics-
Elementary data Types: Properties of Types and Object- Scalar Data Types - Composite
Data Types
UNIT - III
Encapsulation: Structure data types - Abstract data types - Encapsulation by sub
programs Type Definitions Inheritance: - Polymorphisms
UNIT -IV
Functional Programming: Programs as Functions- Functional Programming in an
Imperative Language - LISP - Functional Programming with static typing - delayed
evaluation- Mathematical functional programming- recursive functions and lambda
calculus - Logic programming : Logic and Logic Programs - Horn Clauses - Prolog -
Problems with logic programming
UNIT V
Formal Semantics: Sample small language - operational Semantics - Denotation
Semantics - Axiomatic Semantics - Program correctness - Parallel Programming: Parallel
Processing and programming languages - threads - Semaphore - monitors-message
passing - parallelism Non Imperative Languages
TEXT BOOKS :
1. Terrence W Pratt, Marvin V Zelkowitz, “Programming Languages - Design and
Implementation,” PHI Publications, 4th edition, 2008
2. Kenneth C. Louden , “Programming Languages-Principles and Practices,” Cengage
Learning Publications , 2nd Edition, 2008
1. UNIT-I
1.1 Language Design Issues

 To improve your ability to develop effective algorithms


 To improve your use of existing programming languages
 To increase your vocabulary of useful programming constructs
 To allow a better choice of programming language
 To make it easier to learn a new language
 To make it easier to design a new language

1.2 History-Role of Programming Languages

a) Numerically based languages - computing mathematical expressions


FORTRAN, ALGOL, Pascal, PL/1, BASIC, C, C++
b) Business languages
COBOL (Common Business Oriented Language) English-like notation
c) Artificial intelligence languages - state space search
LISP (LISP Processing)
PROLOG (Programming in Logic)
d) System languages
C, C++, Script languages AWK, Perl, TCL/TK
e) Web programming: HTML, XML, Java, Microsoft *.NET family

1
Software Architectures
a) Mainframe era

Types of computing Effects on language design

 Batch processing (batches  File I/O in batch processing


of files)  Error handling in batch
 Interactive processing processing: error handling
(time sharing) facilities required
 Time constraints: no constraints
in batch processing; time
constraints in interactive
processing

b) Personal computers

Types of computing Effects on language design

 Interactive processing  No need for time sharing


 Embedded system  Good interactive graphics
environments: required
 The computer system is an  Non-standard I/O devices for
integral part of a larger embedded systems
system - e.g. plant control,
operates without an
underlying OS in real
time.

2
c) Networking era

Types of computing Effects on language design

 Client-server model of  Interaction between the client and


computing server programs
 Server: a program that  Active web pages
provides information  Security issues
Client - a program that  Performance
requests information

1.3 Role of programming languages


a) Design goals
 During 1950s--1960s - Run-time considerations
 There is a direct connection between language features and hardware -
integers, real’s, go to statements
 Programmers are cheap, machines expensive; Keep the machine busy
 Today - program development time considerations
 CPU power and memory are very cheap
 Direct connection between language features and design concepts -
encapsulation, records, inheritance, functionality, assertions
b) Attributes of a good language
 Conceptual integrity: Clarity, simplicity, and unity - provides both a framework
for thinking about algorithms and a means of expressing those algorithms
 Orthogonality -every combination of features is meaningful. Some negative
aspects

3
 Naturalness for the application - program structure reflects the logical structure
of algorithm
 Support for abstraction - program data reflects problem being solved
 Ease of program verification - verifying that program correctly performs its
required function
 Programming environment - external support for the language: editors, testing
programs.
 Portability of programs - transportability of the resulting programs from the
computer on which they are developed to other computer systems
 Cost of use - program execution, program translation, program creation, and
program maintenance
c) Imperative languages
 Statement oriented languages that change machine state (C, Pascal, FORTRAN,
COBOL)
 Computation: a sequence of machine states (contents of memory)
 Syntax: S1, S2, S3.
d) Applicative (functional) languages
 Function composition is major operation (ML, LISP)
 Syntax: P1(P2(P3(X)))
 Programming consists of building the function that computes the answer
e) Rule-based languages
 Actions are specified by rules that check for the presence of certain enabling
conditions. (Prolog)
 The order of execution is determined by the enabling conditions, not by the order
of the statements.
 Syntax: Answer ® specification rule

4
f) Object-oriented languages
 Imperative languages that merge applicative design with imperative statements
(Java, C++, Smalltalk)
 Syntax: Set of objects (classes) containing data (imperative concepts) and
methods (applicative concepts)
 Usually, a language is designed to support a given programming paradigm.
However a language can be used to implement paradigms other than the
intended one.
Language standardization
The need for standards - to increase portability of programs. Language standard
defined by national standards bodies:
 ISO - International Standards organization
 IEEE - Institute of Electrical and Electronics Engineers
 ANSI - American National Standards Institute
 Working group of volunteers set up to define standard
 Agree on features for new standard
 Vote on standard
 If approved by working group, submitted to parent organization for
approval.
Problem: When to standardize a language?
 If too late - many incompatible versions - FORTRAN in 1960s was already a
de facto standard, but no two were the same
 If too early - no experience with language - Ada in 1983 had no running
compilers
Problem: What happens with the software developed before the standardization?
Ideally, new standards have to be compatible with older standards.

5
Internationalization
Some of the internationalization issues:
 What character codes to use?
 Collating sequences? - How do you alphabetize various languages?
 Dates? - What date is 10/12/01? Is it a date in October or December?
 Time? - How do you handle time zones, summer time in Europe, daylight
savings time in US, Southern hemisphere is 6 months out of phase with
northern hemisphere, Date to change from summer to standard time is not
consistent.
 Currency? - How to handle dollars, pounds, marks, francs, etc.

Different types of programming languages and its design issues


Imperative
 Central features are variables, assignment statements, and iteration
 Examples: C, Pascal
Functional
 Main means of making computations is by applying functions to given
Parameters
 Examples: LISP, Scheme
Logic (declarative)
 Rule-based (rules are specified in no particular order)
 Example: Prolog
Object-oriented
 Data abstraction, inheritance, late binding
 Examples: Java, C++

6
Markup
 Not a programming per se, but used to specify the layout of information in Web
Documents

1.4 Programming environments


The environment in which programs are created and tested.
a) Effect on language design
 Separate Compilation
 Separate Execution
 Testing
 Debugging
b) Necessary language features:
 Modular Organization
 Local/Global Variables
 Libraries

c) Job Control and Process languages


Scripting languages: usually interpreted, able to process both programs and data
files specify a sequence of operations on program and data files.
Simple example: DOS *.bat files

1.5 Impact of machine Architectures


The Operation of a computer an integrated set of algorithms and data structures
capable of storing and executing programs.

Components:
1. Data - types of elementary data items and data structures to be manipulated
2. Primitive Operations - operations to manipulate data
3. Sequence Control - mechanisms for controlling the sequence of operations
7
4. Data Access - mechanisms to supply data to the operations
5. Storage Management - mechanisms for memory allocation
6. Operating Environment - mechanisms for I/O (i.e. communication)

Implementation of the components


A. Hardware
 CPU (Central processing Unit)Inboard memory
 I/O devices - keyboard, mouse, disk drives, etc
 Outboard storage - disks, CDs
B.CPU
 ALU (arithmetic-logic unit)Control Unit Registers (fast memory)
 PC - program counter, location counter, program address register,
instruction counter
 IR - instruction register
C. Inboard memory
 Registers (listed above)Cache memory Main memory
D. Hardware-level operations
 Fetch-execute cycle:
 Processor fetches an instruction from memory.
 Processor executes the fetched instruction (performs the instruction cycle)
Steps in fetch-execute cycle:
1. Program counter- contains the address of the next instruction to be fetched.
2. The fetched instruction is loaded into Instruction Register
3. Program counter is incremented after fetching.
4. Processor interprets the bits stored in the IR and performs the required action.
Instruction cycle - processing that is required for a single instruction. The instructions

8
executed by CPU are machine language instructions. Some of them are
implemented in hardware - e.g. increment a register by 1.Some are implemented
in Firmware - e.g. add the contents of two registers.
E. Firmware
 A set of machine-language instructions implemented by programs,
 called micro programs, stored in programmable read-only memory in the
 Computer (PROM).
 Example: The language in problem #4, p.42 consists of very low-level
instructions. It would be implemented in hardware (hardwired). The instruction
a = a + b cloud be implemented in firmware.
Advantages:
 Flexibility - by replacing the PROM component we can increase the set of
machine instructions, e.g. we can implement vector multiplication as a machine
operation.
 Less cost of the hardware - the simpler the instructions, the easier to hardwire
them.
F. Software
a) Translators and virtual architectures
Input: high-level language program Output: machine language code
Types of translators (high to low level):
1. Preprocessor:
Input: extended form of high-level language Output: standard form of high-level
Language
2. Compiler:
Input: high-level language program Output (object language): assembler code
3. Assembler:
Input: assembly language Output: one-to-one correspondence to a machine language
9
Code
4. Loader/Link editor:
Input: assembler/machine language reloadable program
Output: executable program (absolute addresses are assigned)
G. Software simulation - Interpreters
The program is not translated to machine language code. Instead, it is executed
by another program.
Example: Prolog interpreter written in C++
Advantages of interpreted languages:
 very easy to be implemented
 easy to debug
 flexibility of language - easy to modify the interpreter
 Portability - as long as the interpreter is portable, the language is also
portable.
Disadvantages of interpreted languages: slow execution.

H. Virtual machines
 Program: data + operations on these data Computer: implementation of data
 structures + implementation of operations
 Hardware computer: elementary data items, very simple operations
 Firmware computer: elementary data items, machine language instructions
 Software computer: each programming environment defines specific
software computer.
 E.G - the operating systems is one specific virtual computer
 A programming language also defines a virtual computer.

10
Basic Hierarchy:
1. Software
2. Firmware
3. Hardware
Software sub-hierarchy - depends on how a given programming environment is
implemented
Example of virtual machines hierarchy:
 Java applets
 Java virtual machine - used to implement the Java applets
 C virtual machine - used to implement Java
 Operating system - used to implement C
 Firmware - used to implement machine language
 Hardware - used to implement firmware micro programs
I) Binding and binding times
Binding - fixing a feature to have a specific value among a set of possible values.
E.G. - your program may be named in different ways and when you choose a
Particular name you have done a binding.
Different programming features have different binding times, depending on:
 The nature of the feature, e.g. you choose the names of the variables
in the source code; the operating system chooses the physical address of the
variables.
 The implementation of the feature - in certain cases the programmer has a
choice to specify the binding time for a given feature.
Binding occurs at:
At language definition - concerns available data types and language structures,
e.g. in C++ the assignment statement is =, while in Pascal it is :=

11
At language implementation - concerns representation of data structures and
operations, e.g. representation of numbers and arithmetic operations
At translation -Chosen by the programmer - variable types and assignments
Chosen by the compiler - relative locations of variables and arrays
Chosen by the loader - absolute locations
At execution -Memory contents on entry to a subprogram (copying arguments to
parameter locations) At arbitrary points (when executing assignment statements)
Recursive programs Dynamic libraries
Example: X = X+10 (see p. 62) Discuss what happens at each stage listed above.
Importance of binding times
1. If done at translation time - more efficiency is gained
2. If done at execution time - more flexibility is gained.

1.6 Language Translation Issues


Programming Language Syntax
The syntax of a programming language describes the structure of programs
without any consideration of their meaning.
Examples of syntax features:
 Statements end with ';' (C, C++, Pascal), with'.' (Prolog), or do not have an
ending symbol (FORTRAN)
 Variables must start with any letter (C, C++, Java), or only with a capital letter
(Prolog).
 The symbol for assignment statement is '=', or ':=' , or something else.
Key criteria concerning syntax
1. Readability – a program is considered readable if the algorithm and data are
apparent by inspection.
2. Write ability – ease of writing the program.

12
3. Verifiability – ability to prove program correctness (very difficult issue)
4. Translatability – ease of translating the program into executable form.
5. Lack of ambiguity – the syntax should provide for ease of avoiding
ambiguous structures..
Basic syntactic concepts in a programming language
1. Character set – the alphabet of the language.
Several different character sets are used: ASCII, EBCIDIC, and Unicode.
2. Identifiers – strings of letters of digits usually beginning with a letter
3. Operator Symbols – +-*/
4. Keywords or Reserved Words – used as a fixed part of the syntax of a
statement.
5. Noise words – optional words inserted into statements to improve readability.
6. Comments – used to improve readability and for documentation purposes.
Comments are usually enclosed by special markers.
7. Blanks – rules vary from language to language. Usually only significant in
literal strings.
8. Delimiters – used to denote the beginning and the end of syntactic constructs.
9. Expressions – functions that access data objects in a program and return a
value
10. Statements – these are the sentences of the language, describe a task to be
performed.

Overall Program-Subprogram Structure


1. Separate subprogram definitions: separate compilation, linked at load time.
Advantages: easy modification.
2. Separate data definitions: Group together all definitions that manipulate a data
object. General approach in OOP.
13
3. Nested subprogram definitions: Subprogram definitions appear as declarations
within the main program or other subprograms. Not used in many
contemporary languages. Provides for static type checking in non-local
referencing environments.
4. Separate interface definitions: Subprogram interface - the way programs and
subprograms interact by means of arguments and returned results. A program
specification component may be used to describe the type of information
transferred between separate components of the program. E.G. C/C++ use
header files as specification components.
5. Data descriptions separated from executable statements. A centralized data
division contains all data declarations. E.G. COBOL. Advantage - logical data
format independent on algorithms.
6. Unseparated subprogram definitions: No syntactic distinction between main
program statements and subprogram statements. Allows for run-time translation
and execution.

1.7 Stages in Translation


a) Lexical analysis (scanning) – identifying the tokens of the programming language:
the keywords, identifiers, constants and other symbols appearing in the language.
In the program
Void main ()
{
Printf ("Hello World\n");
}
The tokens are
Void, main, (,), {, printf, (, "Hello World\n", ), ;, }

14
b) Syntactic analysis (parsing) – determines the structure of the program,
as defined by the language grammar.
c) Semantic analysis - assigns meaning to the syntactic structures
Example:
int variable1;
The meaning is that the program needs 4 bytes in the memory to serve
as a location for variable1. Further on, a specific set of operations only can be
used with variable1, namely integer operations.
The semantic analysis builds the bridge between analysis and synthesis.
d) Basic semantic tasks:
1. Symbol–table maintenance
2. Insertion of implicit information
3. Error detection
4. Macro processing and compile-time operations
The result of the semantic analysis is an internal representation, suitable to be
used for code optimization and code generation
Synthesis of the object program
The final result is the executable code of the program. It is obtained in three main steps:
Optimization - Code optimization involves the application of rules and algorithms
applied to the intermediate and/ or assembler code with the purpose to make it more
efficient, i.e. faster and smaller.
Code generation - generating assembler commands with relative memory addresses for
the separate program modules - obtaining the object code of the program.
Linking and loading - resolving the addresses - obtaining the executable code of the
program.

15
Bootstrapping
1. The compiler for a given language can be written in the same language.
The process is based on the notion of a virtual machine.
2. A virtual machine is characterized by the set of operations, assumed to be
executable by the machine. For example, the set of operations in Homework 1
can be the set of operations for a virtual machine.
3. A real machine (at the lowest level with machine code operations implemented
in hardware)
4. A firmware machine (next level - its set is the assembler language operations and
the program that translates them into machine operations is stored in a special
read-only memory)
5. A virtual machine for some internal representation (this is the third level, and
there is a program that translates each operation into assembler code)
6. A compiler for the language L (some language) written in L (the same language)
a. The translation of the compiler into the internal representation is done
manually - the programmer manually re-writes the compiler into the
internal representation. This is done once and though tedious, it is not
difficult - the programmer uses the algorithm that is encoded into the
compiler.
b. From there on the internal representation is translated into assembler and
then into machine language.
7. Syntax is concerned with the structure of programs. The formal description of
the syntax of a language is called grammar
 Grammars consist of rewriting rules and may be used for both recognition
and generation of sentences.

16
1.8 Formal Translation Models
1. Syntax is concerned with the structure of programs. The formal description of the
syntax of a language is called grammar
2. Grammars consist of rewriting rules and may be used for both recognition and
generation of sentences.
3. Grammars are independent of the syntactic analysis.

More about grammars

a. Word categories, constituents


Language consists of sentences. Each sentence consists of words.
The rules that tell us how to combine words that form correct sentences are
called grammar rules.
Example from English:
"The boy reads" is a valid sentence "Boy the reads" is an invalid sentence.
The corresponding rule here says that the article must precede the noun.
Here you see the words "article" and "noun". These words correspond to
certain categories of words in the language. For example, the words boy, book, room,
class, is all nouns, while read, speak, write, are verbs.
Why do we need word categories?

There are infinitely many sentences and we cannot write a rule for each
individual sentence. We need these categories in order to describe the structural
patterns of the sentences. For example, the basic sentence pattern in English is a noun
phrase followed by a verb phrase.

17
A sequence of words that constitutes a given category is called a constituent. For
example, the boldface parts in each of the sentences below correspond to a constituent
called verb phrase.

The boy is reading a book. The boy is reading an interesting book.


The boy is reading a book by Mark Twain

b. Terminal and non-terminal symbols, grammar rules


Grammars use two types of symbols:
Terminal - to represent the words.
Non-terminal - to represent categories of words and constituents.
These symbols are used in grammar rules. Here are some examples:

Rule Meaning

N ® boy N is the non-terminal symbol for


"noun", "boy" is a terminal "symbol"

D ® the | a | an D is the non-terminal symbol for


definite or indefinite articles.

NP ® D N this rule says that a noun


phrase NP may consist of an article
followed by a noun

There is one special non-terminal symbol S to represent "sentence".


It is called also the starting symbol of the grammar.

Grammars for programming languages - no major differences

18
BNF notation

1. Grammars for programming languages use a special notation called BNF (Backus-
Naur form):
2. The non-terminal symbols are enclosed in < > Instead of ®, the symbol ::= is used The
vertical bar is used in the same way meaning choice are used to represent optional
constituents.
3. BNF notation is equivalent to the first notation in the examples above.

Example: The rule


<assignment statement> ::= <variable> = <arithmetic expression>
says that an assignment statement has a variable name on its left-hand side
followed by the symbol "=", followed by an arithmetic expression.

Example: Expression syntax

BNF notation:

E®T <expression> ::= <term> | <expression> + <term>

E®E+T

T®P <term> ::= <primary> | <term> * <primary>

T®T*P

P®I <primary> ::=<integer> | (<expression>)

P ® (E)

19
Derivations, Parse trees, Ambiguity

Using a grammar, we can generate sentences. The process is called derivation

Example: The simple grammar on p. 91: S à SS | (S) | ( ) generates all sequences of


paired parentheses.

The rules of the grammar can be written separately:

Rule1: S ® SS

Rule2: S ® (S)

Rule3: S ® ( )

One possible derivation is:

SÞ(S) by Rule1

Þ(SS) by Rule2

Þ(()S) by Rule3

Þ(()()) by Rule3

The strings obtained at each step are called sentential forms. They may contain both
terminal and non-terminal symbols. The last string obtained in the derivation contains
only terminal symbols. It is called a sentence in the language.

This derivation is performed in a leftmost manner. That is, at each step the leftmost
variable in the sentential form is replaced.

20
Parsing is the process of syntactic analysis of a string to determine whether
the string is a correct sentence or not. It can be displayed in the form of a parse tree:

Each non-terminal symbol is expanded by applying a grammar rule that contains the
symbol in its left-hand side. Its children are the symbols in the right-hand side of the
rule.

Note: The order of applying the rules depends on the symbols to be expanded.
At each tree level we may apply several different rules corresponding to the nodes to be
expanded.

Ambiguity: The case when the grammar rules can generate two possible parse trees for
one and the same sequence of terminal symbols.

21
Example:

Let S denote a statement, Exp - an expression. Consider the following rules


for if statements (the words if, then, else are terminal symbols):

Rule1: If statement ® if Exp then S else S

Rule2: If statement ® if Exp then S

Consider now the statement

if a < b then if c < y then write (yes) else write (no);

Following the grammar rules above, there are two possible interpretations:

If a < b then

if c < y then write (yes)


else write (no);
If a < b then if c < y then write (yes)

else write (no);


Here is the parse tree for the first interpretation:

22
Here is the parse tree for the second interpretation:

23
A grammar that contains such rules is called ambiguous.
It is very important that grammars for programming languages are not ambiguous.
Types of grammars
There are 4 types of grammars depending on the rule format.
1. Regular grammars: (Type 3)
1. A ® a
2. A ® aB
2. Context-free grammars (Type 2)
A ® any string consisting of terminals and non-terminals
3. Context-sensitive grammars (Type 2)
1. String1 ® String2
2. String1 and String2 are any strings consisting of terminals and non-
terminals, provided that the length of String1 is not greater than the length of
String.

24
4. General grammars (Type 0)
 String1 ® String2, no restrictions.
 Regular grammars and regular expressions
 Strings of symbols may be composed of other strings by means of
 Concatenation - appending two strings, and Kleene star operation – any
 Repetition of the string. E.g. a* can be a, or aa, or aaaaaaa, etc
 Given an alphabet ∑, regular expressions consist of string concatenations
combined with the symbols U and *, possibly using '(' and ')'.
There is one special symbol used to denote an empty expression: Ø
Formal definition:
1. Ø and each member of ∑ is a regular expression.
2. If α and β are regular expressions, then (α β) is a regular expression.
3. If α and β are regular expressions, then α U β is a regular expression.
4. If α is a regular expression, then α* is a regular expression.
5. Nothing else is a regular expression.

Example:

Let ∑ = {0, 1}. Examples of regular expressions are:

0, 1, 010101, any combination of 0s and 1s

0 U 1, (0 U 1)1*

(0 U 1)*01

Regular languages are languages whose sentences are regular expressions.


Regular grammars are used to describe identifiers in programming languages and
arithmetic expressions.
25
Context-free grammars generate context-free languages. They are used to describe
programming languages.

1.9 Recursive Descent Parsing


• A parser that uses collection of recursive procedures for parsing the given input
string is called Recursive Descent parser
• The CFG is used to build the recursive routines
• The RHS of the production rule is directly converted to a program.
• For each NT a separate procedure is written and body of the procedure is RHS of
the corresponding NT.
Basic steps of construction of RD Parser
1. The RHS of the rule is directly converted into program code symbol by symbol
2. If the input symbol is NT then a call to the procedure corresponding the non-
terminal is made.
3. If the input is terminal then it is matched with the look ahead from input. The
look ahead pointer has to be advanced on matching of the input symbol
4. If the production rule has many alternates then all these alternates has to be
combined into a single body of procedure.
5. The parser should be activated by a procedure corresponding to the start symbol.
a. Example
b. A  aBe | cBd | C
c. B  bB | 
d. C  f
Predictive Parsing - LL(1) Parser
 This top-down parsing algorithm is of non-recursive type.
 In this type parsing table is built

26
 For LL(1)

Uses only one input symbol tp predict the parsing


process

Left most derivation

Input scanned from left to right

 The data structures used by LL(1) are

o Input buffer (store the input tokens)

o Stack (hold left sentential form)

o Parsing table (row of NT, column of T)

27
L (1) Parser

Input buffer
– Our string to be parsed. We will assume that its end is marked with a
special symbol $.

Output
– A production rule representing a step of the derivation sequence (left-
most derivation) of the string in the input buffer.
Stack
o contains the grammar symbols
o at the bottom of the stack, there is a special end marker symbol $.
o Initially the stack contains only the symbol $ and the starting symbol S.
$S  initial stack
o When the stack is emptied (ie. only $ left in the stack), the parsing is
completed.
Parsing table
o a two-dimensional array M[A,a]
o each row is a non-terminal symbol
o each column is a terminal symbol or the special symbol $
o Each entry holds a production rule.

Parser Actions

 The symbol at the top of the stack (say X) and the current symbol in the input
string (say a) determine the parser action.
There are four possible parser actions.
1. If X and a are $ → parser halts (successful completion)
28
2. If X and a are the same terminal symbol (different from $)
→ Parser pops X from the stack, and moves the next symbol in the input buffer.
3. If X is a non-terminal
→ Parser looks at the parsing table entry M[X, a]. If M[X, a] holds a production
rule XY1Y2...Yk, it pops X from the stack and pushes Yk, Yk-1... Y1 into the
stack. The Parser also outputs the production rule XY1Y2...Yk to represent a
step of the Derivation.
4. none of the above → error
– All empty entries in the parsing table are errors.
– If X is a terminal symbol different from a, this is also an error case.
5. The construction of predictive L L (1) parser is based on two very important
functions and those are FIRST and FOLLOW.
6. For the construction
7. Computation of FIRST and FOLLOW function
8. Construction the predictive parsing table using FIRST and FOLLOW functions
9. Parse the input string with the help of predictive parsing table

--------------------------------------------UNIT-1 COMPLETED----------------------------------------

29
2. UNIT-II

2.1 Modeling Language Properties


a) Recognizers
1. A recognition device reads input strings of the language and decides whether the
input strings belong to the language
2. Example: syntax analysis part of a compiler
b) Generators
A device that generates sentences of a language one can determine if the syntax
of a particular sentence is correct by comparing it to the structure of the
Generator

2.2 Formal Properties of Languages

1. Backus-Naur Form and Context-Free Grammars

2. Most widely known method for describing programming language syntax

3. Extended BNF

4. Improves readability and writ ability of BNF

2.3 Language Semantics

Introduction

1. For the programmer - to know how to use language constructs


2. For the implementer - to know how to implement the language

 Informal descriptions of language semantics - provided in verbal form in the


language manuals. May be ambiguous.
 Formal description of language semantics - studied theoretically,
no satisfactory models have been produced so far.
30
a) Semantic models

Grammatical models: grammar rules are paired with semantic rules.

Resulting grammars are called attribute grammars

Rule Attribute

E®E+T value(E1) = value(E2) + value(T)

E®T value(E) = value(T)

T®TxP value(T1) = value(T2) x value(P)

T®P value(T) = value(P)

P®I value(P) = value of number I

P ® (E) value(P) = value(E)

b) Operational models

Describe the meaning of the language constructs in terms of machine states,


i.e. memory and register contents

c) Applicative models

Treat programs as functions. Two methods to build applicative models: denotation


semantics and functional semantics.

31
d) Denotation semantics

A technique for describing the meaning of programs in terms of mathematical


functions on programs and program components. Programs are translated into
functions about which properties can be proved using the standard mathematical
theory of functions. Based on Lambda calculus.

e) Lambda calculus

Lambda calculus is a formal mathematical system devised by Alonzo Church to


investigate functions, function application and recursion. It has provided the basis for
developing functional programming languages. Lambda calculus also provides the
meta-language for formal definitions in denotation semantics.

An example illustrating lambda calculus:

A function accepts input and produces an output. Suppose we have a "chocolate-


covering" function that produces the following outputs for the corresponding inputs:
peanuts -> chocolate-covered peanuts
rasins -> chocolate-covered rasins
ants -> chocolate-covered ants

f) Axiomatic models

Describe the meaning as pre-conditions and post-conditions. Used in program


verifications.

g) Specification models

32
Describe the relationship among various functions that implement a program.
Example of a specification model:

Algebraic data types - describe the meaning in terms of algebraic operations, e.g. pop
(push(S, x)) = S

2.4 Elementary data Types Properties of Types and Object

Basic differences among programming languages:

 Types of data allowed


 Types of operations available
 Mechanisms for controlling the sequence of operations

Elementary data types: built upon the available hardware features


structured data types: software simulated

2.5 Properties of Types and Object


A. Data object:

1. A run-time grouping of one or more pieces of data in a virtual computer.


2. A location in memory with an assigned name in the actual computer.

(I) Types of data objects:

 Programmer defined data objects - variables, arrays, constants, files, etc.


 System defined data objects - set up for housekeeping during program execution,
not directly accessible by the program. E.g. run-time storage stacks.
Data value: a bit pattern that is recognized by the computer
Elementary data object: contains a data value that is manipulated as a unit.
Data structure: a combination of data objects.
33
Attributes: determine how the location may be used. Most important attribute - the
data type.
(ii) Attributes and Bindings

1. Type: determines the set of data values that the object may take and the
applicable operations.
2. Name: the binding of a name to a data object.
3. Component: the binding of a data object to one or more data objects.
4. Location: the storage location in memory assigned by the system.
5. Value: the assignment of a bit pattern to a name.

Type, name and component are bound at translation, location is bound at


loading, and value is bound at execution

(iii) Data objects in programs


In programs, data objects are represented as variables and constants
Variables: Data objects defined and named by the programmer explicitly.
Constants: a data object with a name that is permanently bound to a value for its
lifetime.
1. Literals: constants whose name is the written representation of their value.
2. A programmer-defined constant: the name is chosen by the programmer in a
definition of the data object.
(iv) Persistence

Data objects are created and exist during the execution of the program. Some
data objects exist only while the program is running. They are called transient data
objects. Other data objects continue to exist after the program terminates, e.g. data files.
They are called persistent data objects. In certain applications, e.g. transaction-based

34
systems the data and the programs coexist practically indefinitely and they need a
mechanism to indicate that an object is persistent. Languages that provide such
mechanisms are called persistent languages.
B. Data types

A data type is a class of data objects with a set of operations for creating and
manipulating them.

Examples of elementary data types: integer, real, character, Boolean, enumeration,


pointer.

(i) Specification of elementary data types


Attributes that distinguish data objects of that type
Data type, name - invariant during the lifetime of the object
 stored in a descriptor and used during the program execution
 used only to determine the storage representation, not used explicitly during
execution

Values that data object of that type may have determined by the type of the object
usually an ordered set, i.e. it has a least and a greatest value. Operations that define the
possible manipulations of data objects of that type.
Primitive - specified as part of the language definition
Programmer-defined (as subprograms, or class methods)
An operation is defined by:
1. Domain - set of possible input arguments
2. Range - set of possible results
3. Action - how the result is produced

35
The domain and the range are specified by the operation signature

 the number, order, and data types of the arguments in the domain,
 the number, order, and data type of the resulting range mathematical notation
for the specification:
op name: arg type x arg type x … x arg type ® result type
The action is specified in the operation implementation
Sources of ambiguity in the definition of programming language operations

 Operations that is undefined for certain inputs.


 Implicit arguments, e.g. use of global variables
 Implicit results - the operation may modify its arguments
 (HW 01 - the value of a changed in x = a + b)
 Self-modification - usually through change of local data between calls,
i.e. random number generators change the seed.

Subtypes: a data type that is part of a larger class. Examples: in C, C++ int, short,
long and char are variations of integers.

The operations available to the larger class are available to the subtype.
This can be implemented using inheritance.

(ii) Implementation of a data type


Storage representation
Influenced by the hardware described in terms of: Size of the memory blocks
required layout of attributes and data values within the block
Two methods to treat attributes:
1. determined by the compiler and not stored in descriptors during execution - C
2. stored in a descriptor as part of the data object at run time - LISP Prolog
36
(iii) Implementation of operations
1. Directly as a hardware operation. E.g. integer addition
2. Subprogram/function, e.g. square root operation
3. In-line code. Instead of using a subprogram, the code is copied into the program
at the point where the subprogram would have been invoked.
C. Declarations

Declarations provide information about the name and type of data objects
needed during program execution.
 Explicit – programmer defined
 Implicit – system defined
e.g. in FORTRAN - the first letter in the name of the variable determines the type
Perl - the variable is declared by assigning a value $abc = 'a string' $abc is a string
variable $abc = 7 $abc is an integer variable
Operation declarations: prototypes of the functions or subroutines that is programmer-
defined.
Examples: declaration: float Sub (int, float) signature: Sub: int x float --> float
Purpose of declaration
 Choice of storage representation
 Storage management
 Declaration determines the lifetime of a variable, and allows for more efficient
memory usage.
 Specifying polymorphic operations.
 Depending on the data types operations having same name may have different
meaning, e.g. integer addition and float addition
 In most language +, -. *, / are overloaded Ada - allows the programmer to
overload subprograms ML - full polymorphism

37
 Declarations provide for static type checking
D. Type checking and type conversion
Type checking: checking that each operation executed by a program receives
the proper number of arguments of the proper data types.
Static type checking is done at compilation
Dynamic type checking is done at run-time.
Dynamic type checking – Perl and Prolog Implemented by storing a type tag in each
data object
Advantages: Flexibility
Disadvantages:
 Difficult to debug
 Type information must be kept during execution
 Software implementation required as most hardware does not provide support
 Concern for static type checking affects language aspects:
 Declarations, data-control structures, provisions for separate compilation of
subprograms
Strong typing: all type errors can be statically checked
Type inference: implicit data types, used if the interpretation is unambiguous.
Used in ML
E. Type Conversion
Explicit type conversion: routines to change from one data type to another.
Pascal: the function round - converts a real type into integer C - cast, e.g. (int) X for float
X converts the value of X to type integer
Coercion: implicit type conversion, performed by the system. Pascal: + integer and real,
integer is converted to real Java - permits implicit coercions if the operation is widening
C++ - and explicit cast must be given.
Two opposite approaches to type coercions:
38
1. No coercions, any type mismatch is considered an error : Pascal, Ada
2. Coercions are the rule. Only if no conversion is possible, error is reported.
Advantages of coercions: free the programmer from some low level concerns,
as adding real numbers and integers.
Disadvantages: may hide serious programming errors.
F. Assignment and Initialization
Assignment - the basic operation for changing the binding of a value to a data object.

Two different ways to define the assignment operation:


 Does not return a value
 Returns the assigned value
 The assignment operation can be defined using the concepts L-value and R-
value
 Location for an object is its L-value. Contents of that location are its R-value.
 Consider executing: A = A + B;
 Pick up contents of location A: R-value of A
 Add contents of location B: R-value of B
 Store result into address A: L-value of A.

For each named object, its position on the right-hand-side of the assignment operator
(=) is a content-of access, and its position on the left-hand-side of the assignment
operator is an address-of access.

 address-of is an L-value
 contents-of is an R-value
 Value, by itself, generally means R-value

39
G. Initialization

Uninitialized data object - a data object has been created, but no value is assigned,
i.e. only allocation of a block storage has been performed.

2.6 Scalar Data Types

Scalar data types represent a single object, i.e. only one value can be derived.
In general, scalar objects follow the hardware architecture of a computer.
1. Numeric data types
Maximal and minimal values - depending on the hardware. In some languages these
values represented as defined constants.

 Operations
 Arithmetic
 Relational
 Assignment
 Bit operations

Implementation: Most often using the hardware-defined integer storage representation


and a set of hardware arithmetic and relational primitive operations on integers.

Sub ranges and Specification: A subtype of integer consists of a sequence of integer


values within some restricted range. e.g. a Pascal declaration A: 1...10 means that the
variable A may be assigned integer values from 1 through 10.

Implementation: smaller storage requirements, better type checking

40
2. Floating-point real numbers

Specification

1. Ordered sequence of some hardware-determined minimum negative value to a


maximum value.
2. Similar arithmetic, relational and assignment operations as with integers. Round
off issues - the check for equality may fail due to round off.

Implementation: Mantissa - exponent model. The storage is divided into a mantissa -


the significant bits of the number, and an exponent.
Example: 10.5 = 0.105 x 102,

Mantissa: 105 Exponents: 2

3. Fixed-point real numbers

Specification: Used to represent real numbers with predefined decimal places,


such as dollars and cents.

Implementation: May be directly supported by hardware or simulated by software.

4. Other data types

Complex numbers: software simulated with two storage locations -


one for the real portion and one for the imaginary portion.

Rational numbers: the quotient of two integers.

Enumerations: ordered list of different values.

41
Example: enum Student Class {Fresh, Soph, Junior, Senior} the variable Student
Class may accept only one of the four listed values.

Implementation: represented during run time as integers, corresponding to the listed


values.

5. Booleans

Specification: Two values: true and false. Can be given explicitly as enumeration,
as in Pascal and Ada. Basic operations: and, or, not.

Implementation: A single addressable unit such as byte or word. Two approaches:

1. Use a particular bit for the value, e.g. the last bit; 1 - true, 0 -false.
2. Use the entire storage; a zero value would then be false, otherwise - true.

Characters

Specification: Single character as a value of a data object. Collating sequence - the


ordering of the characters, used for lexicographic sorting. Testing the type of the
character - e.g. digit, letter, special symbol.

Implementation: usually directly supported by the underlying hardware.

2.7 Composite Data Types


Characterized by a complex data structure organization, processed by the Compiler.

a) Character strings:
Data objects that are composed of a sequence of characters

Specification and syntax. Three basic methods of treatment:

42
Fixed declared length - storage allocation at translation time
The data object is always a character string of a
declared length.
Strings longer than the declared length are truncated.
Variable length to a declared bound - storage allocation at translation time.
An upper bound for length is set and any string over
that length is truncated
Unbounded length - storage allocation at run time. Strings can be of any
length. Strings are arrays of characters No string type
declaration. Null character determines the end of a string.

Operations
1. Concatenation – appending two strings one after another
2. Relational operation on strings – equal, less than, greater than
3. Substring selection using positioning subscripts
4. Substring selection using pattern matching
5. Input/output formatting
6. Dynamic strings - the string is evaluated at run time.
7. Perl: "$ABC" will be evaluated as a name of a variable, and the contents of the
variable will be used.
Implementation
Fixed declared length: a packed vector of characters
Variable length to a declared bound: a descriptor that contains the maximum
length and the current length
Unbounded length: either a linked storage of fixed-length data objects or a
contiguous array of characters with dynamic run time storage allocation.
b) Pointers and programmer-constructed objects

43
1. Pointers are variables that contain the location of other data objects
2. Allow to construct complex data objects.
3. Used to link together the components of the complex data objects.

Specification:

 Pointers may reference data objects only of a single type – C, Pascal, and Ada.
 Pointer may reference data objects of any type. – Smalltalk
 C, C++: pointers are data objects and can be manipulated by the program
Java: pointers are hidden data structures, managed by the language
implementation

Operations:

Creation operation:
 Allocates a block of storage for the new data object, and returns its address to be
stored in the pointer variable. No name of the location is necessary as the
reference would be by the pointer.
 Selection operation: the contents of the pointer are used as an address in the
memory.
Implementation
Methods:
 Absolute addresses stored in the pointer. Allows for storing the new object
anywhere in the memory
 Relative addresses: offset with respect to some base address. Requires initial
allocation of a block of storage to be used by the data objects. The address of each
object is relative to the address of the block.
Advantages: the entire block can be moved to another location without

44
invalidating the addresses in the pointers, as they are relative, not absolute.

Implementation problems:

1. Creating objects of different size during execution time requires the


management of a general heap storage area.
2. Garbage - occurs when the contents of pointer are destroyed, and the object
still exists however it is no more accessible.
3. Dangling references: the object is destroyed however the pointer still contains
the address of the used location, and can be wrongly used by the program.
c) Files
Characteristics:
Usually reside on secondary storage devices as disks, tapes. Lifetime is greater than the
lifetime of the program that has created the files.

 Types of files depending on the method of access


 Sequential file: a data structure composed of a linear sequence of components of
the same type.
File operations:
1. Open
2. Read
3. Write
4. End-of-file
5. Close
Implementation: usually handled by the operating system.
Interactive Input-Output: sequential files used in interactive mode.

45
Direct Access Files: any single component can be accessed at random just as in an
array.
 Key: the subscript to access a component.
 Implementation: a key table is kept in main memory
 Indexed Sequential Files: similar to direct access files using a key combined
with capability to process the file sequentially. The file must be ordered by the
key

-------------------------------------------------UNIT-II COMPLETED-------------------------------------

46
3. UNIT - III

3.1 Encapsulation
If a data member is private it means it can only be accessed within the same
class. No outside class can access private data member (variable) of other class.

3.2 Structured Data Types


A data structure is a data object that contains other data objects as its elements or
Components.
A. Specifications

1. Number of components
2. Fixed size – Arrays Variable size – stacks, lists. Pointer is used to link
components.
Type of each component
1. Homogeneous – all components are the same type
2. Heterogeneous – components are of different types

Selection mechanism to identify components – index, pointer two-step process:


referencing the structure selection of a particular component

1. Maximum number of components


2. Organization of the components: simple linear sequence
3. simple linear sequence
4. multidimensional structures:
5. separate types (Fortran)
6. vector of vectors (C++)

Operations on data structures


1. Component selection operations

47
2. Sequential
Random
3. Insertion/deletion of components
4. Whole-data structure operations Creation/destruction of data structures
B. Implementation of data structure types

Storage representation
Includes:
1. storage for the components
2. optional descriptor - to contain some or all of the attributes
Sequential representation:
The data structure is stored in a single contiguous block of storage that includes
both descriptor and components. Used for fixed-size structures, homogeneous
structures (arrays, character strings)
Linked representation:
The data structure is stored in several noncontiguous blocks of storage, linked
together through pointers. Used for variable-size structured (trees, lists) Stacks, queues,
lists can be represented in either way. Linked representation is more flexible and
ensures true variable size; however it has to be software simulated.
Implementation of operations on data structures
Component selection in sequential representation:
Base address plus offset calculation. Add component size to current location to
move to next component.
Component selection in linked representation:
Move from address location to address location following the chain of pointers.
Storage management
Access paths to a structured data object - to endure access to the object for its
processing. Created using a name or a pointer.
48
Two central problems:
Garbage – the data object is bound but access path is destroyed. Memory cannot be
unbound.

Dangling references – the data object is destroyed, but the access path still exists.
C. Declarations and type checking for data structures

A. Existence of a selected component


B. Type of a selected component
D. Vectors and arrays

A vector - one dimensional array


A matrix - two dimensional arrays
Multidimensional arrays
A slice - a substructure in an array that is also an array, e.g. a column in a matrix.

Implementation of array operations:

Access - can be implemented efficiently if the length of the components of the array
is known at compilation time. The address of each selected element can be
computed using an arithmetic expression.
Whole array operations, e.g. copying an array - may require much memory.

Associative arrays

Instead of using an integer index, elements are selected by a key value, that is a
part of the element. Usually the elements are sorted by the key and binary search is
performed to find an element in the array.

49
E. Records

A record is a data structure composed of a fixed number of components of


different types. The components may be heterogeneous, and they are named with
symbolic names.
Specification of attributes of a record:

1. Number of components
2. Data type of each component
3. Selector used to name each component.

Implementation:

Storage: single sequential block of memory where the components are stored
sequentially.

Selection: provided the type of each component is known, the location can be
computed at translation time.
F. Other structured data objects

Records and arrays with structured components:


A record may have a component that is an array; an array may be built out of
components that are records.
Lists and sets: lists are usually considered to represent an ordered sequence of
Elements, sets - to represent unordered collection of elements.
Executable data objects
Other languages however do not distinguish between programs and data - e.g.
PROLOG. Data structures are considered to be a special type of program
statements and all are treated in the same way.

50
3.3 Abstract Data Types

a. An abstract data type is:


b. A set of data objects,
c. A set of abstract operations on those data objects,
d. Encapsulation of the whole in such a way that the user of the data object cannot
manipulate data objects of the type except by the use of operation defined.
e. Encapsulation is primarily a question of language design; effective encapsulation
is possible only when the language prohibits access to the information hidden
within the abstraction.
f. Some languages that provide for abstract data types: Ada: packages; C++, Java,
Visual Basic: classes.

Information hiding

Information hiding is the term used for the central principal in the design of
programmer-defined abstract data types.

A programming language provides support for abstraction in two ways

1. By providing a virtual computer that is simpler to use and more powerful than
the actual underlying hardware computer.
2. The language provides facilities that aid the programmer to construct
abstractions.

When information is encapsulated in an abstraction, it means that the user of the


abstraction does not need to know the hidden information in order to use the
abstraction, is not permitted to directly use or manipulate the hidden information even
if desiring to do so.

51
3.4 Encapsulation by subprograms
A. Subprograms as abstract operations

Subprograms can be viewed as abstract operations on a predefined data set.


A subprogram represents a mathematical function that maps each particular set of
arguments into a particular set of results.

Specification of a subprogram (same as that for a primitive operation):

 The name of the subprogram


 The signature of the subprogram - gives the number of arguments, their
order, and the data type of each, as well as the number of results, their
order, and the data type of each
 The action performed by the subprogram

Some problems in attempting to describe precisely the function computed by a


subprogram:

1. Implicit arguments in the form of nonlocal variables.


2. Implicit results (side effects) returned as changes to nonlocal variables or as
changes in the subprogram's arguments.
3. Using exception handlers in case the arguments are not of the required type.
4. History sensitiveness - the results may depend on previous executions.

Implementation of a subprogram:

 Uses the data structures and operations provided by the language


 Defined by the subprogram body
 Local data declarations Statements defining the actions over the data.

52
The body is encapsulated; its components cannot be accessed separately by the user of
the subprogram. The interface with the user (the calling program) is accomplished by
means of arguments and returned results.

Type checking: similar to type checking for primitive operations.


Difference: types of operands and results are explicitly stated in the program
B. Subprogram definition and invocation

a) Subprogram definitions and subprogram activations


Subprogram definition:
The set of statements constituting the body of the subprogram. It is a static property of
the program, and it is the only information available during translation.

Subprogram activation
A data structure (record) created upon invoking the subprogram. It exists while
the subprogram is being executed. After execution the activation record is destroyed.
C. Implementation of subprogram definition and invocation

A simple (but not efficient) approach:

Each time the subprogram is invoked, a copy of its executable


statements, constants and local variables is created.

A better approach:

 The executable statements and constants are invariant part of the subprogram
they do not need to be copied for each execution of the subprogram. A single
copy is used for all activations of the subprogram. This copy is called code
segment. This is the static part.
53
 The activation record contains only the parameters, results and local data.
 This is the dynamic part. It has same structure, but different values for the
variables.

On the left is the subprogram definition. On the right is the activation record created
during execution. It contains the types and number of variables used by the
subprogram and the assigned memory locations at each execution of the subprogram.

The definition serves as a template to create the activation record (the use of the word
template is different from the keyword template in class definitions in C++, though its
generic meaning is the same - a pattern, a frame to be filled in with particular values. In
class definitions the binding refers to the data types and it is performed at compilation
time, while here the binding refers to memory locations and data values, and it is
performed at execution time.)

54
Generic subprograms: have a single name but several different definitions –
overloaded.

Subprogram definitions as data objects

In compiled languages subprogram definition is separate from subprogram execution.


– C, C++, Java

In interpreted languages there is no difference - definitions are treated as run-time


data objects – Prolog, LISP, and Perl. Interpreted languages use an operation to
invoke translation at run-time – consult in Prolog, define in LISP.

3.5 Type Definitions

a) Basics

Type definitions are used to define new data types. Note, that they do not define a
complete abstract data type, because the definitions of the operations are not included.

Format: typedef definition name

Actually we have a substitution of name for the definition.

Examples:
Typedef int key type;
Key type key1, key2;

These statements will be processed at translation time and the type of key1 and key2
will be set to integer.

Struct rational_number
55
{Int numerator, denominator ;};

Typedef rational_number rational;


Rational r1, r2;

Here r1 and r2 will be of type rational_number

b) Type equivalence and equality of data objects

Two questions to be answered:

 When two are types the same?


 When do two objects have the same value?

Name equivalence: two data types are considered equivalent only if they have the
same name.
Issues
every object must have an assigned type, there can be no anonymous types.
A singe type definition must serve all or large parts of a program.

Structural equivalence: two data types are considered equivalent if they define data
objects that have the same internal components.
Issues
Do components need to be exact duplicates? Canfield order is different in
records? Can field sizes vary?
Data object equality

56
We can consider two objects to be equal if each member in one object is
identical to the corresponding member of the other object. However there still may be a
problem. Consider for example the rational numbers 1/2 and 3/6.
Are they equal according to the above definition?

c) Type definition with parameters


Parameters allow the user to prescribe the size of data types needed – array sizes.
Implementation: The type definition with parameters is used as a template
as any other type definition during compilation.
3.6 Inheritance
Implicit passing of information between program components.

The concept is generally used in the context of complex data objects.

1. Abstract Data Types


 Data components
 Operations to manipulate the data components

Basic idea: The data components and the programs that implement the operations are
hidden from the external world. The object is encapsulated.

Implementation of ADT: classes (C++), packages (ADA), objects (Smalltalk)

E.G. private section: accessible only to the class functions (class functions are called
also methods) public section: contains the methods - to be used by other programs
Generic abstract data types - use templates
This is the case when the data components may be of different type, however the
operations stay the same, e.g. a list of integers, a list of characters.
Instantiation occurs at compiling time

57
1. Derived classes

Object hierarchy: an object may be a special case of a more general object.


Some of the properties are the same - these properties can be inherited

Generalization and specialization: Down the hierarchy the objects become more
specialized, up the hierarchy - more generalized.

Instantiation: The process of creating instances of a class.

Derived classes inherit data components and/or methods further on; they can specify
their own data components and their own specific methods. The specific parts may
have same names as in the parent - they override the definition in the parent class.

Implementation

Copy-based approach (Direct encapsulation) - each instance of a class object has its
own data storage containing all data components - specific plus inherited.

Delegation-based approach (Indirect encapsulation) – the object uses the data storage
of the base class.
58
2. Multiple inheritance

4. Inheritance of methods

Virtual functions - bound at run time

Class Figure
{
Public:
Figure ();
Virtual void draw ();
Virtual void erase ();
Void center ();
Void set color (T Color);
Void position center ();
};
Void Figure:: center()
{
Erase ();
Position center ();
59
Draw ();
}
Class Box: public Figure
{
Public:
Box ();
Void draw ();
Void erase ();
};

Int MAIN:

Box a_box;
a_box. Draw (); // overrides base class
a_box.set_color(C); // inherits the method
a_box. Center (); // makes use of virtual
// functions

Implementation of virtual methods:


A slot in the record defining the class. The constructor fills in the location of the
new virtual procedure if there is one. If not, it fills in the location of the virtual
Procedure from the base class.

Abstract Classes - can serve only as templates, no data objects can be declared
with the name of the class. Specified by NULL virtual functions

Virtual void Type Name () = 0;


Mixin inheritance - specify only the differences (not present in C++)
60
3.7 Polymorphism

The ability of a single operator or subprogram name to refer to any number of


function definitions depending on the data types of the arguments and results.

Example:

When printing a person's name, we may want to print the full name, or to print only the
first and the last name. We may use two functions that have the same name but
different number of arguments:

Void print_name (string, string, string);

Void print_name (string, string);

--------------------------------------UNIT-III COMPLETED--------------------------------------

61
4. UNIT- IV

4.1 Functional Programming


 The design of the imperative languages is based directly on the von
Neumann architecture
 Efficiency is the primary concern, rather than the suitability of the language
for software development
 The design of the functional languages is based on mathematical functions
 A solid theoretical basis that is also closer to the user, but relatively
unconcerned with the architecture of the machines on which programs will
run Mathematical.

4.2 Programs as Functions


 A program is a description of specific computation

 If we ignore the “how” and focus on the result, or the “what” of the
computation, the program becomes a virtual black box that transforms input
into output

 A program is thus essentially equivalent to a mathematical function

 Function: a rule that associates to each x from set of X of values a unique y


from a set Y of values

 In mathematical terminology, the function can be written as y=f(x) or f:XY

 Domain of f: the set X

 Range of f: the set Y

 Independent variable: the x in f(x), representing any value from the set X

62
 Dependent variable: the y from the set Y, defined by y=f(x)

 Partial function: occurs when f is not defined for all x in X

 Total function: a function that is defined for all x in the set X

 Programs, procedures, and functions can all be represented by the


mathematical concept of a function

o At the program level, x represents the input, and y represents the


output

o At the procedure or function level, x represents the parameters, and y


represents the returned values

 Functional definition: describes how a value is to be computed using formal


parameters

 Functional application: a call to a defined function using actual parameters,


or the values that the formal parameters assume for a particular computation

 In math, there is not always a clear distinction between a parameter and a


variable

o The term independent variable is often used for parameters

 A major difference between imperative programming and functional


programming is the concept of a variable

o In math, variables always stand for actual values

o In imperative programming languages, variables refer to memory


locations that store values

63
 Assignment statements allow memory locations to be reset with new values

o In math, there are no concepts of memory location and assignment

 Functional programming takes a mathematical approach to the concept of a


variable

o Variables are bound to values, not memory locations

o A variable’s value cannot change, which eliminates assignment as an


available operation

 Most functional programming languages retain some notion of assignment

o It is possible to create a pure functional program that takes a strictly


mathematical approach to variables

 Lack of assignment makes loops impossible

o A loop requires a control variable whose value changes as the loop


executes

o Recursion is used instead of loops

 There is no notion of the internal state of a function

o Its value depends only on the values of its arguments (and possibly
nonlocal variables)

 A function’s value cannot depend on the order of evaluation of its arguments

o An advantage for concurrent applications

64
 Referential transparency: the property whereby a function’s value depends
only on the values of its variables (and nonlocal variables)

 Examples:

o gcd function is referentially transparent

o rand function is not because it depends on the state of the machine and
previous calls to itself

 A referentially transparent function with no parameters must always return


the same value

o Thus it is no different than a constant

 Referential transparency and the lack of assignment make the semantics


straightforward

 Value semantics: semantics in which h names are associated only to values, not
memory locations

 Lack of local state in functional programming makes it opposite of OO


programming, wherein computation proceeds by changing the local state of
objects

 In functional programming, functions must be general language objects, viewed


as values themselves

 In functional programming, functions are first-class data values

o Functions can be computed by other functions

o Functions can be parameters to other functions

65
 Composition: essential operation on functions

o A function takes two functions as parameters and produces another


function as its returned value

 In math, the composition operator o is defined:

o If f:XY and g:YZ, then g o f:XZ is given by

o (g o f)(x) = g(f(x))

 Qualities of functional program languages and functional programs:

o All procedures are functions that distinguish incoming values


(parameters) from outgoing values (results)

o In pure functional programming, there are no assignments

o In pure functional programming, there are no loops

o Value of a function depends only on its parameters, not on order of


evaluation or execution path

o Functions are first-class data values

 Functional programming is not tied to the von Neumann machine.


 It is not necessary to know anything about the underlying hardware when
writing a functional program, the way you do when writing an imperative
program.
 Functional programs are more declarative than procedural ones; i.e. they
describe what is to be computed rather than how it should be computed.

66
Common characteristics of functional programming languages:

1. Simple and concise syntax and semantics.


2. Repetition is expressed as recursion rather than iteration.
3. Functions are first class objects. I.e. functions can be manipulated just as easily as
integers, floats, etc. in other languages.
4. Data as functions. I.e. we can build a function on the fly and then execute it.
(Some languages).
5. Higher-order functions. I.e. functions can take functions as arguments and return
functions as results.
6. Lazy evaluation. Expressions are evaluated only when needed. This allows us to
build infinite data structures, where only the parts we need are actually
constructed.
7. Garbage Collection. Dynamic memory that is no longer needed is automatically
reclaimed by the system. GC is also available in some imperative languages
(Modula-3, Eiffel) but not in others (C, C++, Pascal).
8. Polymorphic types. Functions can work on data of different types. (Some
languages).
9. Functional programs can be more easily manipulated mathematically than
procedural programs.

Pure vs. Impure FPL

 Some functional languages are pure, i.e. they contain no imperative features at
all. Examples: Haskell, Miranda, Gofer.
 Impure languages may have assignment-statements, goto:s, while-loops, etc.
Examples: LISP, ML, Scheme.

67
Applications of Functional Languages

 APL is used for throw-away programs


 LISP is used for artificial intelligence
 Knowledge representation
 Machine learning
 Natural language processing
 Modeling of speech and vision
 Haskell
A. What is Haskell?

 Haskell is statically typed (the signature of all functions and the types of all
variables are known prior to execution);
 Haskell uses lazy rather than eager evaluation (expressions are only evaluated
when needed);
 Haskell uses type inference to assign types to expressions, freeing the
programmer from having to give explicit types;
 Haskell is pure (it has no side-effects).

B. Haskell -- Lazy evaluation

 No expression is evaluated until its value is needed.


 No shared expression is evaluated more than once; if the expression is ever
evaluated then the result is shared between all those places in which it is used.
 No shared expression should be evaluated more than once.

C. Haskell -- Infinite data structures

 Lazy evaluation makes it possible for functions in Haskell to manipulate `infinite'


data structures.

68
 The advantage of lazy evaluation is that it allows us to construct infinite objects
piece by piece as necessary

 Consider the following function which can be used to produce infinite lists of
integer values:

D. Haskell – Currying

 Haskell only supports one-argument functions. Multi-argument functions are


constructed by successive application of arguments, one at a time.
 Currying is the preferred way of constructing multi-argument functions.
 The main advantage of currying is that it allows us to define specialized versions
of an existing function.
 A function is specialized by supplying values for one or more (but not all) of its
arguments.
 The Functional Programming Paradigm is one of the major programming
paradigms.
 FP is a type of declarative programming paradigm Also known as applicative
programming and value-oriented programming
 Idea: everything is a function
 Based on sound theoretical frameworks (e.g., the lambda calculus)
 Examples of FP languages
 First (and most popular) FP language: Lisp Other important FPs: ML, Haskell,
Miranda, Scheme, Logo

69
4.3 Functional Programming in an Imperative Language
Comparing Functional and Imperative Languages
Imperative Languages:
 Efficient execution
 Complex semantics
 Complex syntax
 Concurrency is programmer designed
Functional Languages:
 Simple semantics
 Simple syntax

Imperative (procedural) programs consists of actions to effect state change,


principally through assignment operations or side effects
 Fortran, Algol, Cobol, PL/I, Pascal, Modula-2, Ada, C

 Why does imperative programming dominate in practice?

OO programming is not always imperative, but most OO languages have been


imperative

 Simula, Smalltalk, C++, Modula-3, Java

Comparing Functional and Imperative Languages


Imperative Languages:
 Efficient execution
 Complex semantics
 Complex syntax
 Concurrency is programmer designed

70
Functional Languages:
 Simple semantics
 Simple syntax
 Inefficient execution
 Programs can automatically be made concurrent

Features of Imperative Programs

 Sequence of instructions
 Modification of variables (memory cells)
 Test of variables (memory cells)
 Transformation of states (automata)
Construction of programs
 Describe what has to be computed
 Organize the sequence of computations into steps
 Organize the variables
Correctness
 Specifications by pre/post-conditions
 Loop invariants
Symbolic execution
 Expressions f(z) + x / 2 can be different from x / 2 + f(z)namely when f modifies
the value of x (by side effect)Variables
 The assignment x: = x + 1 modifies a memory cell as a side effect

4.4 LISP
 LISP is the first functional programming language, it contains two forms those
are:
o Data object types: originally only atoms and lists

71
o List form: parenthesized collections of sub lists and/or atoms e.g.,(A B (C
D) E)
 Fundamentals of Functional Programming Languages:
 The objective of the design of a FPL is to mimic mathematical functions to the
greatest extent possible. The basic process of computation is fundamentally
different in a FPL than in an imperative language
 In an imperative language, operations are done and the results are stored in
variables for later use

 Management of variables is a constant concern and source of complexity for


imperative programming

 In an FPL, variables are not necessary, as is the case in mathematics

 In an FPL, the evaluation of a function always produces the same result given the
same parameters

 This is called referential transparency


A Bit of LISP:
 Originally, LISP was a type less language. There were only two data types, atom
and list
 LISP lists are stored internally as single-linked lists
 Lambda notation is used to specify functions and function definitions, function
applications, and data all have the same form.
 E.g. :, If the list (A B C) is interpreted as data it is a simple list of three atoms, A,
B, and C If it is interpreted as a function application, it means that the function
named A is applied to the two parameters, B and C
 The first LISP interpreter appeared only as a demonstration of the universality of
the computational capabilities of the notation

72
Scheme:
 A mid-1970s dialect of LISP, designed to be cleaner, more modern, and simpler
version than the contemporary dialects of LISP, Uses only static scoping
 Functions are first-class entities, They can be the values of expressions and
elements of lists,
 They can be assigned to variables and passed as parameters

4.5 Functional Programming with static typing

 In a statically typed language, every variable name is bound both to a type


(at compile time, by means of a data declaration)to an object.
 Once a variable name has been bound to a type (that is, declared) it can be
bound (via an assignment statement) only to objects of that type; it cannot
ever be bound to an object of a different type. An attempt to bind the name to
an object of the wrong type will raise a type exception.
 In a dynamically typed language, every variable name is (unless it is null)
bound only to an object.
 Names are bound to objects at execution time by means of assignment
statements, and it is possible to bind a name to objects of different types
during the execution of the program.

73
 Functional programming languages are based on the lambda-calculus. The
lambda-calculus grew out of an attempt by Alonzo Church and Stephen Kleene
in the early 1930s to formalize the notion of computability (also known
as constructability and effective calculability).
 It is a formalization of the notion of functions as rules (as opposed to functions as
tuples). As with mathematical expressions, it is characterized by the principle
that the value of an expression depends only on the values of its sub
expressions.
 The lambda-calculus is a simple language with few constructs and a simple
semantics. But, it is expressive; it is sufficiently powerful to express all
computable functions.
 As an informal example of the lambda-calculus, consider the function defined by
the polynomial expression

x2 + 3x - 5.
 The variable x is a parameter. In the lambda-calculus, the notation λx.M is used
to denote a function with parameter x and body M. That is, x is mapped to M.
We rewrite our function in this format

λx.(x2+ 3x - 5)
74
and read it as ``the function of x whose value is defined by x2 + 3x - 5''. The lambda-
calculus uses prefix form and so we rewrite the body in prefix form,

λx. (- (+ (* x x) (* 3 x)) 5).


The lambda-calculus curries its functions of more than one variable i.e. (+ x y) are
written as ((+ x) y), the function (+ x) is the function which adds something to x.
Rewriting our example in this form we get:

λx.((- ((+ ((* x) x)) ((* 3) x))) 5)


To denote the application of a function f to an argument a we write f a

To apply our example to the value 1 we write


λx.((- ((+ ((* x) x)) ((* 3) x))) 5) 1.
To evaluate the function application, we remove the λx. And replace each remaining
occurrence of x with 1 to get

((- ((+ ((* 1) 1)) ((* 3) 1))) 5)


Then evaluate the two multiplication expressions

((- ((+ 1) 3)) 5)


Then the addition

((- 4) 5)
And finally the subtraction

-1.

We say that the variable x is bound in the lambda-expression λx. A variable occurring in
the lambda-expression which is not bound is said to be free. The variable x is free in the
lambda-expression λy.((+ x) y). The scope of the variable introduced (or bound) by
lambda is the entire body of the lambda-abstraction.

75
The lambda-notation extends readily to functions of several arguments. Functions of
more than one argument can be curried to produce functions of single arguments. For
example, the polynomial expression xy can be written as

λx. λy. xy
When the lambda-abstraction λx. λy. xy is applied to a single argument as in (λx. λy. xy
5) the result is λy. 5y, a function which multiplies its argument by 5. A function of more
than one argument is regarded as a functional of one variable whose value is a function
of the remaining variables, in this case, ``multiply by a constant function.''

The special character of the lambda-calculus is illustrated when it is recognized that


functions may be applied to other functions and even permit self application. For
example let C = λf. λx . (f(fx))

The pure lambda-calculus does not have any built-in functions or constants. Therefore,
it is appropriate to speak of the lambda-calculi as a family of languages for computation
with functions. Different languages are obtained for different choices of functions and
constants.

We will extend the lambda-calculus with common mathematical operations and


constants so that λx.((+ 3) x) defines a function that maps x to x+3. We will drop some of
the parentheses to improve the readability of the lambda expressions.

A lambda-expression is executed by evaluating it. Evaluation proceeds by repeatedly


selecting a reducible expression (or redex) and reducing it. For example, the expression
(+ (* 5 6) (* 8 3)) reduces to 54 in the following sequence of reductions.

(+ (* 5 6) (* 8 3)) → (+ 30 (* 8 3))
→ (+ 30 24)
→ 54

76
When the expression is the application of a lambda-abstraction to a term, the term is
substituted for the bound variable. This substitution is called β-reduction. In the
following sequence of reductions, the first step an example of β-reduction. The second
step is the reduction required by the addition operator.
(λx.((+ 3) x))

((+ 3) 4)

The pure lambda-calculus has just three constructs: primitive symbols, function
application, and function creation. Figure N.1gives the syntax of the lambda-calculus.

4.6 Delayed Evaluation


 In a language with an applicative order evaluation rule, all parameters to user-
defined functions are evaluated at the time of a call

 Examples that do not use applicative order evaluation:

o Boolean special forms and and or if special form

 Short-circuit evaluation of Boolean expressions allows a result without


evaluating the second parameter

 Delayed evaluation is necessary for if special form

 Example: (if a b c)

o Evaluation of b and c must be delayed until the result of a is known; then


either b or c is evaluated, but not both

 Must distinguish between forms that use standard evaluation (function


applications) and those that do not (special forms)

77
 Using applicative order evaluation for functions makes semantics and
implementation easier

 Nonstrict: a property of a function in which delayed evaluation leads to a well-


defined result, even though sub expressions or parameters may be undefined

 Languages with the property that functions are strict are easier to implement,
although no strictness can be a desirable property

 Algol60 included delayed execution in its pass by name parameter passing


convention

o A parameter is evaluated only when it is actually used in the code of a


called procedure

 Example: Algol60 delayed execution

 When called as p(true, 1 div 0), it returns 1 since y is never reached in the code of
p

o The undefined expression 1 div 0 is never computed

 In a language with function values, it is possible to delay evaluation of a


parameter by enclosing it in a function “shell” (a function with no parameters)

 Example: C pass by name equivalent

78
 Such “shell” procedures are sometimes referred to as pass by name thunks, or
just thunks

 In Scheme and ML, the lambda and fn function value constructors can be used to
surround parameters with function shells

 Example:

Which can be called as follows?

 Delayed evaluation can introduce inefficiency when the same delayed expression
is repeatedly evaluated

 Scheme uses a memorization process to store the value of the delayed object the
first time it is forced and then return this value for each subsequent call to force

o This is sometimes referred to as pass by need

 Lazy evaluation: only evaluate an expression once it is actually needed

 This can be achieved in a functional language without explicit calls to delay and
force

79
 Required runtime rules for lazy evaluation:

o All arguments to user-defined functions are delayed

o All bindings of local names in let and letrec expressions are delayed

o All arguments to constructor functions are delayed

 Required runtime rules for lazy evaluation (cont’d.):

o All arguments to other predefined functions are forced

o All function-valued arguments are forced

o All conditions in selection forms are forced

 Lists that obey lazy evaluation may be called streams

 Primary example of a functional language with lazy evaluation is Haskell

 Generator-filter programming: a style of functional programming in which


computation is separated into procedures that generate streams and other
procedures that take streams as arguments

 Generators: procedures that generate streams

 Filters: procedures that modify streams

 Same-fringe problem for lists: two lists have the same fringe if they contain the
same non-null atoms in the same order

 To determine if two lists have the same fringe, must flatten them to just lists of
their atoms

 flatten function: can be viewed as a filter; reduces a list to a list of its atoms

80
 Lazy evaluation will compute only enough of the flattened lists as necessary
before their elements disagree

 Delayed evaluation complicates the semantics and increases complexity in the


runtime environment

o Delayed evaluation has been described as a form of parallelism, with


delay as a form of process suspension and force as a kind of process
continuation

 Side effects, in particular assignment, do not mix well with lazy evaluation

4.7 Mathematical Functional Programming

Definition: A mathematical function is a mapping of members of one set, called the


domain set, to another set, called the range set
Functional Forms
Def: A higher-order function, or functional form, is one that either takes
functions as parameters or yields a function as its result, or both.
1. Function Composition
A functional form that takes two functions as parameters and yields a function
whose result is a function whose value is the first actual parameter function applied to
the result of the application of the second Form: h ≡ f ° g which means h (x) ≡ f ( g ( x))E
2. Construction
A functional form that takes a list of functions as parameters and yields a list of
the results of applying each of its parameter functions to a given parameter Form: [f, g]
For f (x) ≡ x * x * x and g (x) ≡ x + 3, [f, g] (4) yields (64, 7).

81
3. Apply-to-all
A functional form that takes a single function as a parameter and yields a list of
values obtained by applying the given function to each element of a list of parameters
Form: α For h (x) ≡ x * x * x α ( h, (3, 2, 4)) yields (27, 8, 64) This looks like map( ).

4.8 Recursive Functions and Lambda Calculus


 Abstractly, a function f is a rule that associates to each x in some set X (the
domain), a y in another set Y (the range): f: X  Y.

 Alternatively, a function can be viewed as a subset S of the Cartesian product


X  Y with the property that (x,y), (x,y')  S implies y = y'.

 Functions can be given as sets simply by listing their elements (definition by


extension).

 More usually, functions are given by a formula (definition by compression),


which may or may not be recursive.

 One way to think abstractly about a recursive definition is to consider it to


imply a (countably infinite) union of sets that are built, one element at a time,
out of the base case or cases.

 Factorial example: fact n = if n = 0 then 1 else n * fact (n-1)

 The "base" point is (0,1): fact0 = { (0,1) }

 Now consider the formula as a set equation: fact = fact0 U fact', where fact' is
the function formed for each n by the formula n * fact (n-1).

 Unfortunately, we don't yet know either fact or fact'.

82
 But consider what would happen if we used fact0 as an approximation for fact
in the formula for fact':

 fact1 = fact0 U fact0' , where fact0' = { (n,m) | (n-1,p)  fact0 , m = n*p }


= { (1,1) } [since (1-1,1) = (0,1)  fact0]

 Then fact1 = { (0,1) } U { (1,1) }. We have a new point!

 So apply the equation again, this time using fact1 as an approximation for fact
in fact'. We get yet another point! Call this function fact2 . Continue.

 Now let fact = Un = 1.. factn . What function is this?

 If we try the process once again, we find that we get no new points: fact  =
fact0 U fact '.

 The function fact is said to be a fixed point of the recursive equation for fact.

 Indeed, fact is the smallest such set with this property and is essentially
unique.

 So it makes sense to define the fact function to be fact : we say that the
recursive definition has least-fixed-point semantics.

 Not all sets allow least fixed point solutions to recursive equations. Sets that
do are called domains.

 Domain theory tells us when recursive definitions will work (and when they
won't).

We extend the syntax of the lambda-calculus to include named expressions as


follows:
Lambda Expressions L ::= ...| x : L | ...
83
Where x is the name of the lambda-expression L. With the introduction of named
expressions we have the potential for recursive definitions since the extended syntax
permits us to name lambda-abstractions and then refer to them within a lambda-
expression. Consider the following recursive definition of the factorial function.
FAC: λn.(if (= n 0) 1 (* n (FAC (- n 1))))
This with syntactic sugaring is

FAC: λn.if (n = 0) then 1 else (n * FAC (n - 1))


We can treat the recursive call as a free variable and replace the previous definition with
the following.

FAC: (λfac.(λn.(if (= n 0) (* n (fac (- n 1))))) FAC)


Let

H : λfac.(λn.(if (= n 0) 1 (* n (fac (- n 1)))))


Note that H is not recursively defined. Now we can redefine FAC as
FAC : (H FAC)
This definition is like a mathematical equation. It states that when the function H is
applied to FAC, the result is FAC. We say that FAC is a fixed point or fixpoint of H. In
general functions may have more than one fixed point. In this case the desired fixed
point is the mathematical function factorial. In general, the `right' fixed point turns out
to be the unique least fixed point.

It is desirable that there be a function which applied to lambda-abstraction returns the


least fixed point of that abstraction. Suppose there is such a function Y where,

FAC: Y H
Y is called a fixed point combinatory.

84
With the function Y, this definition of FAC does not use of recursion. From the previous
two definitions, the function Y has the property that

Y H = H (Y H)
As an example, here is the computation of FAC 1 using the Y combinatory.

FAC 1 = (Y H) 1
= H (Y H) 1
= λfac.(λn.(if (= n 0) 1 (* n (fac (- n 1))))) (Y H) 1
= λn.(if (= n 0) 1 (* n((Y H)(- n 1)))) 1
= if (= 1 0) 1 (* 1 ((Y H)(-11)))
= (* 1 ((Y H)(-11)))
= (* 1 ((Y H)0))
= (* 1 (H (Y H) 0))
...
= (* 1 1)
= 1
The function Y can be defined in the lambda-calculus.
Y : λh.(λx.(h (x x)) λx.(h (x x)))
It is especially interesting because it is defined as a lambda-abstraction without using
recursion. To show that this lambda-expression properly defines the Y combinatory,
here it is applied to H.

(Y H) = (λh.(λx.(h (x x)) λx.(h (x x))) H)


= (λx.(H (x x)) λx.(H (x x)))
= H ( λx.(H (x x))λx.(H (x x)))
= H (Y H)

 parameters are written together so we may write

85
λxy.x + y instead of λx.λy.x + y

 The lambda calculus is an abstraction and simplification of a functional


programming language, much as a Turing machine is an abstraction and
simplification of a computer.

 Lambda calculus is Turing-complete, so it it can be used as a model for


computation instead of TMs.

 Issues such as delayed evaluation, recursion, and scope can be studied with
mathematical precision in the lambda calculus.

 Lambda calculus: invented by Alonzo Church in the 1930s

o A mathematical formalism for expressing computation by functions

o Can be used as a model for purely functional programming languages

 Many functional languages, including Lisp, ML and Haskell, were based on


lambda calculus

 Lambda abstraction: the essential construct of lambda calculus:

 Can be interpreted exactly as this Scheme lambda expression:

o An unnamed function of parameter x that adds 1 to x

 This expression:

o Represents the application of the function that adds 1 to x to the constant 2

86
 A reduction rule permits 2 to be substituted for x in the lambda, yielding this:

 Syntax for lambda calculus:

 Third rule represents function application

 Fourth rule gives lambda abstractions

 Lambda calculus as defined here is fully curried

 Lambda calculus variables do not occupy memory

 The set of constants and the set of variables are not specified by the grammar

o It is more correct to speak of many lambda calculi

 In the expression

o x is bound by the lambda

o The expression E is the scope of the binding

o Free occurrence: any variable occurrence outside the scope

o Bound occurrence: an occurrence that is not free

 Different occurrences of a variable can be bound by different lambdas


87
 Some occurrences of a variable may be bound, while others are free

 Can view lambda calculus as modeling functional programming:

o A lambda abstraction as a function definition

o Juxtaposition of two expressions as function application

 Typed lambda calculus: more restrictive form that includes the notion of data
type, thus reducing the set of expressions that are allowed

 Precise rules must be given for transforming expressions

 Substitution (or function application): called beta-reduction in lambda calculus

 Beta-abstraction: reversing the process of substitution

 Beta-conversion: either beta-reduction or beta-abstraction

 Name capture problem: when doing beta-conversion and replacing variables


that occur in nested scopes, an incorrect reduction may occur

o Must change the name of the variable in the inner lambda abstraction
(alpha-conversion)

 Eta-conversion: allows for the elimination of “redundant” lambda abstractions

o Helpful in simplifying curried definitions in functional languages

 Basic operation of lambda calculus is the application of expressions such as the


lambda abstraction

88
Syntax for lambda calculus

Two sets of basic expressions:

 Variables: x,y,z, etc. (essentially identifiers representing parameters)

 Constants: numbers like 1, 2, 3; "built-in" functions like +, *, cons.

Two operations:

 Abstraction (like lambda expressions in Scheme, ML, or Haskell - anonymous


function creation).

 Application (like function call).

Grammar:
lexpr   variable . lexpr | lexpr lexpr
| ( lexpr ) | variable | constant

 Examples

 x . + ((y. (x.  x y) 2) x) y

 (x . x y) y

 ((y. 2) ((x. x x) (x. x x)))

 ( h. ( x Lambda calculus is fully Curried.

 Application works left to right, abstraction right to left.

 Application has higher precedence than abstraction.

 The set of variables is unspecified, but doesn't matter very much, as long as it
is (countably) infinite.

89
 The set of constants isn't specified either, and this can make a difference in
terms of what you want to express. This set may be infinite (all integers) or
finite or even empty (pure lambda calculus). Thus, there are really many
kinds of lambda calculus.

 h (x x)) ( x. h (x x)))

 There are no semantic restrictions on the syntactically legal expressions in the


lambda calculus: all expressions given by the syntax are legal.

 By the previous statement, there can be no type checking in the lambda


calculus. There is in fact an alternate version called the typed lambda calculus
that does have types.

 Not all lambda expressions make sense as programs: (x x) is legal, and so is (2


x).
(Exercise: try typing  x . x x in ML or Haskell.

Semantics of Lambda Calculus

 Some expressions are equivalent to others in lambda calculus even though they
are syntactically distinct:

o  x . x is equivalent to  y . y()

o  x . y x is equivalent to y ()

o ( x . x) y is equivalent to y()

 These equivalences have historical names: alpha-conversion (-conversion), eta-


conversion (-conversion), and beta-conversion (-conversion). When a
conversion simplifies an expression it is called a reduction.

90
 Conversion operations depend on the notion of the scope (or binding) of a
variable in an abstraction.

 The variable x in the expression (x.E) is said to be bound by the lambda. The
scope of the binding is the expression E.

 An occurrence of a variable outside the scope of any binding of it by a lambda is


a free occurrence. An occurrence that is not free is a bound occurrence. Thus, in
the expression x. E, all occurrences of x in E are bound.

4.9 Logic Programming


Logic programming is a type of programming paradigm which is largely based
on formal logic. Any program written in a logic programming language is a set of
sentences in logical form, expressing facts and rules about some problem domain.

4.8 Logic and Logic Programs


 Uses a set of logical assertions (i.e. statements that are either true or false), as a
program (the facts).

 Execution is initiated by a query or goal, which the system attempts to prove true
or false, based on the existing set of assertions.

 For this reason, logic programming systems are sometimes called deductive
databases.

 Two main "weirdness’s": no explicit functions, no explicit execution control.

 Computing ancestors:
A parent is an ancestor.
If A is an ancestor of B, and B is an ancestor of C, then A is an ancestor of C. (a
typical relation: called??)

91
A mother is a parent.
A father is a parent.
Bill is the father of Jill.
Jill is the mother of Sam.
Bob is the father of Sam.

A. Horn Clauses

Definition: A Horn clause is a clause with at most one positive literal.

 Any Horn clause therefore belongs to one of four categories:


 A rule: 1 positive literal, at least 1 negative literal. A rule has the form "~P1 V ~P2
V ... V ~Pk V Q". This is logically equivalent to "[P1^P2^ ... ^Pk] => Q"; thus, an
if-then implication with any number of conditions but one conclusion. Examples:
"~man(X) V mortal(X)" (All men are mortal); "~parent(X,Y) V ~ancestor(Y,Z) V
ancestor(X,Z)" (If X is a parent of Y and Y is an ancestor of Z then X is an ancestor
of Z.)
 A fact or unit: 1 positive literal, 0 negative literals. Examples: "man(Socrates)",
"parent(elizabeth,charles)", "ancestor(X,X)" (Everyone is an ancestor of
themselves (in the trivial sense).)
 A negated goal: 0 positive literals, at least 1 negative literal. In virtually all
implementations of Horn clause logic, the negated goal is the negation of the
statement to be proved; the knowledge base consists entirely of facts and goals.
The statement to be proven, therefore, called the goal, is therefore a single unit or
the conjunction of units; an existentially quantified variable in the goal turns into
a free variable in the negated goal. E.g. If the goal to be proven is "exists (X)
male(X) ^ ancestor (elizabeth,X)" (show that there exists a male descendent of
Elizabeth) the negated goal will be "~male(X) V ~ancestor(elizabeth,X)".

92
 The null clause: 0 positive and 0 negative literals. Appears only as the end of a
resolution proof.

 Drop the quantifiers (i.e., assume them implicitly). Distinguish variables from
constants, predicates, and functions by upper/lower case:

 Modified Horn clause syntax: write the clauses backward, with :- as the
(backward) arrow, comma as "and" and semicolon as "or":

Ancestor(X,Y) :- parent(X,Y).
Ancestor(X,Y) :-
ancestor(X,Z), ancestor(Z,Y).
Parent(X,Y) :- mother(X,Y).
Parent(X,Y) :- father(X,Y).
Father (bill, jill).
Mother (jill, sam).
Father (bob, am).
factorial (0,1).
Factorial (N,N*M) :- factorial(N-1,M).
Parent(X,Y)  ancestor(X,Y).
Ancestor (A,B) and ancestor(B,C)  ancestor(A,C).
Mother(X,Y)  parent(X,Y).
Father(X,Y)  parent(X,Y).
Father (bill,jill).
Mother (jill,sam).
Father (bob,sam).
Factorial (0,1).
Factorial (N-1,M)  factorial(N,N*M).

93
B. Prolog

 PROLOG is a programming language that allows the programmer to specify


declarative statements only declarative statements (things you are declaring) fall
into 2 categories predicates/propositions that are true clauses (truth preserving
rules in clausal form) once specified, the programmer then introduces questions
to be answered

 PROLOG uses resolution (backward chaining) and unification to perform the


problem solving automatically

 PROLOG was developed in France and England in the late 70s the intent was to
provide a language that could accommodate logic statements and has largely
been used in AI but also to a lesser extent as a database language or to solve
database related problems

Elements of Prolog

 Terms – constant, variable, structure constants are atoms or integers (atoms are
like those symbols found in Lisp) variables are not bound to types, but are bound
to values when instantiated (via unification) an instantiation will last as long as it
takes to complete a goal proving something is true, or reaching a dead end with
the current instantiation structures are predicates and are represented as
functor(parameter list) where functor is the name of the predicate

 All statements in Prolog consist of clauses

– headed clauses are rules

– headless clauses are statements that are always true in reality, a headless
clause is a rule whose condition is always true

– all clauses must end with a period

94
RULES

 All rules are stated in Horn clause form the consequence comes first the symbol :-
is used to separate the consequence from the antecedent .And is denoted by , and
Or is denoted by ; or separating the rule into two separately rules Variables in
rules are indicated with upper-case letters rules end with a .

o examples:

 Parent(X, Y) :- mother(X, Y).

 Parent(X, Y) :- father(X, Y).

 Grandparent(X, Z) :- parent(X, Y), parent(Y, Z).

 Sibling(X, Y) :- mother(M, X), mother(M, Y), father(F, X), father(F,


Y).

o we can use _ as a wildcard meaning this is true if we can find any clause
that fits

 Father(X) :- father(X, _), male(X).

 X is a father if X is male and is someone’s father

Advantages

 There are several advantages to using Prolog

– ability to create automated problem solvers merely by listing knowledge

– a shortcut way to build and query a database

– solving significantly difficult problems with minimal code:

95
Deficiencies of Prolog

 Lack of control structures

– Prolog offers built-in control of resolution and unification you often have
to force a problem into the resolution mold to solve it with Prolog (most
problems cannot or should not be solved in this way)

 Inefficiencies of resolution

– resolution, as a process, is intractable (O(2n) for n clauses) Useful


heuristics could be applied to reduce the complexity, but there is no way
to apply heuristics in Prolog they would just be additional rules that
increases the size of n!

 Closed world assumption

– In any form of logic reasoning, if something is not known, it is assumed to


be false and everything is either true or false

 Negation is difficult to represent

– Since there is no NOT in Prolog, how do we represent NOT? recall that


anything explicitly stated must be true so we cannot specify NOT
something as something would then be false

We can represent A! = B, but we cannot represent ~dog(X).

Prolog's Execution Strategy

 Given a query or goal, Prolog tries to pattern match the goal with the left-hand
sides of all clauses, in a sequential top-down fashion.

96
 Any lhs that matches causes the terms to be set up sequentially as sub goals,
which Prolog immediately tries to match in turn with lhs terms.

 Thus, Prolog's execution path is top-down, left-to-right, and depth-first. All


intermediate results are kept for backtracking purposes.

4.9 Problems with logic programming


 Based on logic and declarative programming 60‘s and early 70‘s, Prolog
(Programming in logic, 1972) is the most well known representative of the
paradigm.
o Prolog is based on Horn clauses and SLD resolution
o Mostly developed in fifth generation computer systems project
o Specially designed for theorem proof and artificial intelligence but allows
general purpose computation.
 Proof: by refutation, try to un satisfy the clauses with a goal clause G. Find 9(G).
Linear resolution for definite programs with constraints and selected atom.CLP
on first order terms. (Horn clauses). Unification. Bidirectional. Backtracking.
Proof search based on trial of all matching clauses
o Some other languages in paradigm: ALF, Frill,G¨odel,, Mercury, Oz, Ciao,
_Prolog, data log, and CLP languages

Constrain Logic Programming:


1. Clause: disjunction of universally quantified literals, 8(L1 _ L2 _ ... _ Ln)
2. A logic program clause is a clause with exactly one positive literal 8(A _ ¬A1
_¬A2... _ ¬An) _8(A ( A1 ^ A2... ^ An)
3. A goal clause: no positive literal 8(¬A1 _ ¬A2... _ ¬An)

-------------------------------------UNIT-IV COMPLETED-----------------------------------------------
97
5. UNIT -V

5.1 Formal Semantics


In linguistics, formal semantics seeks to understand linguistic meaning by
constructing precise mathematical models of the principles that speakers use to define
relations between expressions in a natural language and the world that supports
meaningful discourse.

5.2 Sample small language


 The semantics definition standardizes the official semantics of the language. This
is crucial to users, who require a guide to understanding the programs that they
write, and to implementers, who must write a correct code generator for the
language’s compiler.
 The semantics definition permits a formal analysis of its properties, such as
whether the definition is strongly typed, block structured, uses single-threaded
data structures, is parallelizable, etc.
 The semantics definition can be used as input to a compiler back-end generating
tool it becomes, in effect, the implementation.
 Programming-language syntax was studied intensively in the 1960’s and 1970’s,
and programming language semantics is undergoing similar intensive study.
Unlike the acceptance of BNF as the standard for syntax definition, it is unlikely
that a single definition method will take hold for.
 Semantics—semantics is harder to formalize than syntax, and it has a wider
variety of applications.
 Operational: the meaning of a well-formed program is the trace of computation
steps that results from processing the program have input. Operational
semantics is also called intentional semantics, because the sequence of internal
computation steps (the “intension”) is most important.
98
 For example, two differently coded programs that both compute factorial have
different operational semantics.
 Denotation: the meaning of a well-formed program is a mathematical function
from input data to output data. The steps taken to calculate the output are
unimportant; it is the relation of input to output that matters. Denotation
semantics is also called extensional semantics, because only the “extension”—the
visible relation between input and output—matters. Thus, two differently coded
versions of factorial have the same denotation semantics.
 Axiomatic: a meaning of a well-formed program is a logical proposition (a
“specification”) that states some property about the input and output. For
example, the proposition ∀x.x ≥ ⊃ ∃y.y = x! Is an axiomatic semantics of a
factorial program.

5.3 Operational Semantics


 There are several versions of operational semantics for arithmetic. The one that
you learned as a child is called a term rewriting system [6, 25]. It uses rule
schemes generate computation steps.
 There is just one rule scheme for arithmetic:
 N1 + N2 ⇒ N′ where N′ is the sum of the numerals N1 and N2
 The rule scheme states that adding two numerals is a computation step, e.g., 1 +
2 ⇒ 3 is one computation step. An operational semantics of a program is a
sequence of such computation steps.
 For example, an operational semantics of (1 + 2) + (4 + 5) goes as follows:
(1 + 2) + (4 + 5) ⇒ 3 + (4 + 5) ⇒ 3 + 9 ⇒ 12
 Three computation steps led to the answer, 12. An intermediate expression like 3
+ (4 + 5) is a “state,” so this operational semantics traces the states of the
computation.

99
 Another semantics for the example is (1 + 2) + (4 + 5) ⇒ (1 + 2) + 9 ⇒ 3 + 9 ⇒ 12.
The
Outcome is the same, and a set of rules that has this property is called confluent
[25].
 A structural operational semantics is a term-rewriting system plus a set of
inference rules that state precisely the context in which a computation step can
be undertaken. (A structural operational
 Semantics is sometimes called “small-step semantics,” because each computation
step is a small step towards the final answer.) Say that we demand left-to-right
computation of arithmetic expressions. This is encoded as follows:
N1 + N2 ⇒ N′ where N′ is the sum of N1 and N2
E1 ⇒ E′
1
E1 + E2 ⇒ E′
1 + E2
E2 ⇒ E′
2
N + E2 ⇒ N + E′
 The first rule goes as before; the second rule states, if the left operand of an
addition expression can be rewritten, then do this. The third rule is the crucial
one: if the right operand of an addition expression can be rewritten and the left
operand is already a numeral (completely evaluated), then rewrite the right
operand. Working together, the three rules force left-to-right evaluation.
 Each computation step must be deduced by the rules. For (1 + 2) + (4 + 5), we
deduce this
 initial computation step:
1+2⇒3
(1 + 2) + (4 + 5) ⇒ 3 + (4 + 5)

100
 Thus, the first step is (1+2)+(4+5) ⇒ 3+(4+5); note that we cannot deduce that
(1+2)+(4+5) ⇒
(1 + 2) + 9. The next computation step is justified by this deduction:
4+5⇒9
3 + (4 + 5) ⇒ 3 + 9
 The last deduction is simply 3 + 9 ⇒ 12, and we are finished. The example shows
why the semantics is “structural”: each computation step is explicitly embedded
into the structure of the overall program.
 Operational semantics is often used to expose implementation concepts, like
instruction counters, storage vectors, and stacks. For example, say our semantics
of arithmetic must show how a stack holds intermediate results. We use a state of
form hs, ci, where s is the stack and c is the arithmetic expression to evaluate. A
stack containing n items is written v1 :: v2 :: ... :: vn :: nil,
 Where v1 is the topmost item and nil marks the bottom of the stack. The c
component will be written as a stack as well. The initial state for an arithmetic
expression, p, is written hnil, p :: nili, and computation proceeds until the state
appears as hv :: nil, nili; we say that the result is v.

5.4 Denotation Semantics


 Operational semantics emphasizes internal state transitions. For the arithmetic
language, we were distracted by questions about order of evaluation of sub
phrases, even though this issue is not at all important to arithmetic. Further, the
key property that the meaning of an expression is built from the meanings of its
sub expressions was obscured.
 We use denotation semantics to establish that a program has an underlying
mathematical meaning that is independent of the computation strategy used to
compute it. In the case of arithmetic, an expression like (1 + 2) + (4 + 5) have the

101
meaning, 12. The implementation that computes the 12 is a separate issue,
perhaps addressed by an operational semantics.
 The assignment of meaning to programs is performed compositionally: the
meaning of a phrase is built from the meanings of its sub phrases. We now see
this in the denotation semantics of the arithmetic language. First, we assert that
meanings of arithmetic expressions must be taken from the domain (“set”) of
natural numbers, Nat = {0, 1, 2, ...}, and there is a binary, mathematical function,
plus : Nat × Nat → Nat, which maps a pair of natural numbers to their sum
 The denotation semantics definition of arithmetic is simple and elegant:
E : Expression →Nat
E[[N]] = N
E[[E1 + E2]] = plus(E[[E1]], E[[E2]])
 The first line states that E is the name of the function that maps arithmetic
expressions to
their meanings. Since there are two BNF constructions for expressions, E is
completely defined by the two equational clauses. (This is a Tarksi-style
interpretation, as used in symbolic logic to give meaning to logical propositions .
The interesting clause is the one for E1 +E2; it says that the meanings of E1 and
E2 are combined compositionally by plus. Here is the denotation semantics of
our example program:
E[[(1 + 2) + (4 + 5)]] = plus(E[[1 + 2]], E[[4 + 5]])
= plus(plus(E[[1]], E[[2]]), plus(E[[4]], E[[5]]))
= plus(plus(1, 2), plus(4, 5)) = plus(3, 9) = 12
 Read the above as follows: the meaning of (1+2)+(4+5) equals the meanings of
1+2 and 4+5 Added together. Since the meaning of 1 + 2 is 3, and the meaning of
4 + 5 is 9, the meaning of the overall expression is 12. This reading says nothing

102
about order of evaluation or run-time data structures—it states only
mathematical meaning.
 Here is an alternative way of understanding the semantics; write a set of
simultaneous equations based on the denotation definition:

5.5 Axiomatic Semantics

 Axiomatic semantics is a language for specifying what a program is supposed to


do.

 Based on the idea of an assertion:


o An assertion is a predicate that describes the state of a program at a point
in its execution.
 A post condition is an assertion that states the program’s result.
 A precondition is an assertion that states what must be true before the program
begins running.

5.6 Program correctness


 Axiomatic Semantics
 Fundamental Concepts
 The Assignment Rule
 Rules of Consequence
 Correctness of the Max Function
 Correctness of Programs with Loops
 Formal Methods Tools: JML
 Correctness of Object-Oriented Programs
 Correctness of Functional Programs

103
Motivation

 A correct program is one that does exactly what it is intended to do, no more and
no less.

 A formally correct program is one whose correctness can be proved


mathematically.

 This requires a language for specifying precisely what the program is intended to
do.

o Specification languages are based in mathematical logic.

o Hoare invented “

 Axiomatic semantics” in 1969 as a tool for specifying program behavior and


proving correctness.

 Until recently, correctness has been an academic exercise.

o Now it is a key element of critical software systems.


Correctness Tools

 Theorem provers

o PVS

 Modeling languages

o UML and OCL

 Specification languages

o JML

 Programming language support

o Eiffel

104
o Java

o Spark/Ada

 Specification Methodology

o Design by contract
Partial correctness

 There is no guarantee that an arbitrary program will terminate normally. That is,
for some inputs,
 It may enter an infinite loop, or

 It may fail to complete its calculations.

 E.g., consider a C-like factorial function n! Whose parameter n and result are int
values? Passing 21 as an argument should return n! = 51090942171709440000.

 But that value cannot be stored as an int, so the function fails.

 A program s is partially correct for pre- and post conditions

 P and Q if, whenever s begins in a state that satisfies P, it terminates in state that
satisfies Q.

5.7 Parallel Programming


In computing, a parallel programming model is an abstraction
of parallel computer architecture, with which it is convenient to express algorithms and
their composition in programs.

5.8 Parallel Processing and programming languages


 A second approach to parallel programming is the design and implementation of
parallel programming languages.
105
 These are languages designed to support parallel computing better than
sequential languages, though many of them are based on traditional languages in
the hope that existing code bases can be reused. This dissertation categorizes
parallel languages as being either global-view or local-view.

Issues to be addressed:

 Variable definitions
o Mutable: values may be assigned to the variables and changed
during program execution (as in sequential languages).
o Definitional: variable may be assigned a value only once.
 Parallel composition: A parallel statement, which causes additional threads of
control
to begin executing.
 Execution models (Program structure)

Transformational: transforms the input data into an appropriate output value.


E.G. parallel matrix multiplication

Reactive: the program reacts to external stimuli called events.


E.G. real-time control systems. Non-determinism - the behavior depends on the
occurring events.

 Communication

Shared memory with common data objects accessed by each parallel program;

 Synchronization. Parallel programs must be able to coordinate the execution of


various threads of control.

106
5.9 Threads
 Threads are lightweight tasks (i.e. sharing the same address space)
communication using shared data (and the join method)
Concurrent units
1. Run () method of various objects
a) Descendants of the Thread class
b) classes implementing Runnable
2 .The main method
Class My Thread extends Thread {
Public void run () {...}
}
...
Thread myTh = new My Thread ();
myTh.start();
 start executes the thread
 yield voluntarily yields the processor
 sleep postpones for a specified time (in ms)
 (after which the thread joins the ready queue)
 join waits for a (different) thread to finish

5.10 Semaphore
 Semaphore is a variable that has an integer value
 May be initialized to a nonnegative number
 Wait operation decrements the semaphore value
 Signal operation increments semaphore value
 Each task performs:

Wait;
107
/* critical section */

Signal;

The Producer/Consumer problem with infinite buffer


Solution:
s - Semaphore for entering the critical section
Delay - semaphore to ensure reading from non-empty buffer

Producer: Consumer:

Produce (); wait (delay);


Wait (s); wait(s);
Append (); take ();
Signal (delay); signal(s);
Signal; consume ();

 Allows the code to be executed only if the condition is fulfilled semaphore is an


implementation of guard semaphore data an integer counter + a queue of
waiting tasks operations
P (wait) [probeer te verlagen – try to decrease]
V (signal/resume ) [verhogen – increase]
counter values
0; 1 – binary (mutex)
0 : : : n – counting semaphores
wait(s)
if s.counter > 0 then

108
s.counter--
else
(s.queue).insert(P)
suspend P’s execution
end
signal(s)
if isempty(s.queue) then
s.counter++
else
P = (s.queue).remove()
mark P as ready
end

5.10 Monitors
 Solve some of the problems of semaphores formalized 1973 (Hansen), named
1974 (Hoare) use encapsulation shared data are packaged with operations on
these data the representation is hidden – basically a kind of ADT access
mechanism is part of the monitor if some subroutine of the monitor is running,
all other calling tasks are put into the queue guarantee mutual exclusion
cooperation is programmer’s responsibility can be implementer using
semaphores (and vice versa)
 e.g. synchronized in Java
 A monitor is a programming language construct that supports controlled access
to shared data synchronization code is added by the compiler

 why does this help?

 A monitor encapsulates:

109
o shared data structures

o procedures that operate on the shared data

o synchronization between concurrent threads that invoke those procedures

 Data can only be accessed from within the monitor, using the provided
procedures protects the data from unstructured access

 Addresses the key usability issues that arise with semaphores

 Automatic” mutual exclusion

 only one thread can be executing inside at any time thus, synchronization is
implicitly associated with the monitor – it “comes for free” If a second thread
tries to execute a monitor procedure, it blocks until the first has left the monitor

o more restrictive than semaphores

o but easier to use (most of the time)

Condition Variables

 A place to wait; sometimes called a rendezvous point

 “Required” for monitors So useful they’re often provided even when monitors
aren’t available.

110
 Three operations on condition variables

 wait(c)

o release monitor lock, so somebody else can get in

o wait for somebody else to signal condition

o thus, condition variables have associated wait queues

 signal(c)

o wake up at most one waiting thread

o if no waiting threads, signal is lost

o This is different than semaphores: no history!

 broadcast(c)

 wake up all waiting threads

5.11 Message Passing

 Message-passing is the primitive programming model for architectures of the


DM MIMD class
 The logical view of a virtual machine supporting the message-passing paradigm
(MP) consists of p processes/tasks, each with its own exclusive/private address
space
 Each data element must belong to one of the private partitions of the address
space data must be explicitly partitioned and placed in the private address
spaces of each process
 All interactions (read-only or read/write) between processes require explicit

111
 Cooperation of two processes between the process that owns the data and the
process that wants to access the data.
 This constraint, while onerous, make the underlying costs very explicit to the
programmer
 Message-passing programs are written using the asynchronous or loosely
synchronous paradigms
o All concurrent tasks execute asynchronously.
o Tasks or subsets of tasks synchronize to perform interactions.
 Languages
o Send/Receive statements, specific constructs to define communication
channels, etc. as an integral part of the language OCCAM is an old MP
language, whose MP constructs were directly supported by the
Transporter machine language
o Languages permit compile-time analyses, type checking, deadlock
checking, etc.
 Libraries offer a set of MP primitives, and are linkable to many sequential
languages (C/C++, F77/F90, etc.)
o MPI (Message Passing Interface)
o PVM (Parallel Virtual Machine)
o Optimized version for specialized networks, but there exist versions that
work for TCP/IP over an Ethernet network
 MPI (Message Passing Interface)
o standard for parallel programming
o Universities, Research centers, Industries were involves
o there exist public-domain implementations
o mpich – maintained by Argonne National Laboratories
 PVM (Parallel Virtual Machine)
112
o first MP library that has been largely adopted
o Homogeneous high-performance clusters, but also heterogeneous
 distributed architectures composed of remote hosts over Internet
o developed by Oak Ridge National Laboratories
o public domain
 Process creation
o At loading time process number decided at loading time used in MPI
(mpich), now available on PVM too
 SPMD (Single Program Multiple Data) : same code executed by the all the
process copies
o At running time given an executable code, create a process executing that
code used in PVM (spawn), now available in MPI too in principle,
processes can execute different codes (MPMD –
 Multiple Programs Multiple Data)
o At compiling time old approach: all is decided statically (number and
mapping of processes) OCCAM on Meiko CS1 – Transporter-based MPI
defines a standard library for message-passing that can be used to develop
portable message-passing programs using either C/C++ or Fortran.
 The MPI standard defines both the syntax as well as the semantics of a core set of
library routines.
 Vendor implementations of MPI are available on almost all commercial parallel
computers.
 It is possible to write fully-functional message-passing programs by using only
six routines.
MPI_Init Initializes MPI.
MPI_Finalize Terminates MPI.
MPI_Comm_size determines the number of processes.
113
MPI_Comm_rank determines the label of calling process.
MPI_Send sends a message.
MPI_Recv receives a message.
MPI_Init is called prior to any calls to other MPI routines. Its purpose is to
initialize the MPI environment.
 MPI_Finalize is called at the end of the computation, and it performs various
clean-up tasks to terminate the MPI environment.
 The prototypes of these two functions are:
Int MPI_Init (int *argc, char ***argv)
Int MPI_Finalize ()
MPI_Init also strips off any MPI related command-line arguments.
 All MPI routines, data-types, and constants are prefixed by “MPI_”.
 The return code for successful completion is MPI_SUCCESS parallelism Non
Imperative Languages
 The execution of more than one program/subprogram simultaneously.
 A subprogram that can execute concurrently with other subprograms is called a
task or a process.
Hardware supported:
o multiprocessor systems
o distributed computer systems
Software simulated - : time-sharing
Variable definitions
Mutable: values may be assigned to the variables and changed during program
execution (as in sequential languages).
Definitional: variable may be assigned a value only once.
Parallel composition: A parallel statement, which causes additional threads of control
to begin executing
114
Execution models (Program structure)
Transformational: E.G. parallel matrix multiplication
Reactive
Communication
 shared memory with common data objects accessed by each parallel
program; message
Synchronization:
 Parallel programs must be able to coordinate actions

5.12 Parallelism Non Imperative Languages


Procedural programming is a type of imperative programming in which the program is
built from one or more procedures (also termed subroutines or functions). The terms
are often used as synonyms, but the use of procedures has a dramatic effect on how
imperative programs appear and how they are constructed. Heavily-procedural
programming, in which state changes are localized to procedures or restricted to
explicit arguments and returns from procedures, is a form of structured programming.

 In the itemized list below we describe the main properties of the imperative
paradigm.
 Characteristics:
o Discipline and idea digital hardware technology and the ideas of Von
Neumann
o Incremental change of the program state as a function of time.
o Execution of computational steps in an order governed by control
structures. We call the steps for commands
o Straightforward abstractions of the way a traditional Von Neumann
computer works
o Similar to descriptions of everyday routines, such as food recipes and car
repair

115
o Typical commands offered by imperative languages
 Assignment, IO, procedure calls
o Language representatives
 Fortran, Algol, Pascal, Basic, C
o The natural abstraction is the procedure
 Abstracts one or more actions to a procedure, which can be calledas a single
command.
 "Procedural programming"

We use several names for the computational steps in an imperative language. The word
statement is often used with the special computer science meaning 'a elementary
instruction in a source language'. The word instruction is another possibility; we prefer
to devote this word the computational steps performed at the machine level. We will
use the word 'command' for the imperatives in a high level imperative programming
language.

A procedure abstracts one or more actions to a procedure, which can be activated as a


single action.

------------------------------------------------UNIT-V COMPLETED-----------------------------------

116
: I M.Sc
OBJECTIVE TEST-I

Title: Principles of programming Languages

1. Program subroutines are


a) called by other programs b)fixed variable
c) default constants d) Default variables
2. Data types are differed on basis of
a)way of storage b)type of operations
c) Type of operators used d) both a and b
3. What are the issues for languages?
a) Can it be understood by people and processed by machines?
a) Although translation may be required.
b) Sufficient expressive power?
c) Can we say what needs to be said, at an appropriate level of abstraction?
4. Monitor is a programming language construct that provides equivalent
a) Functionality b)Access c)Control d)Reliability
5. In monitor, local data variables accessible only by
a) Procedures b)Monitor's Procedures c)Monitor d)None
6. What are the three main types of computer programming languages?
a) Machine language, assembly language, high level language
b) Imperative language, functional language, declarative language
c) COBOL, Fortran-77, C++
d) None of these
7. Program which is written originally by programmer is classified as

117
a) Object code b) machine code
c) source program d) interactive program
8. Programming language 'FORTRAN' stands for
a) formula translator b) formula translation
c) Free translator d) free translation
9. Programming language which is used for scientific purposes and work is to be done
in batches is
a) PASCAL b) FORTRAN
c) LOGO d) COMAL
10. Programming language 'COMAL' stand for
a) common algorithmic language
b) common arithmetic language
c) common arithmetic learning
d) common algorithmic learning

118
M.Sc (CS) Degree examination
PRINCIPLES OF PROGRAMMING LANGUAGES
Time: Three hours maximum: 75 marks
SECTION A-(05X05=25 marks)
Answer ALL the Questions
1) a) Write short notes on language design issues (or)
b) Discuss in detail about history of programming languages
2) a) Explain about elementary data types in detail? (or)
b) Write short notes on scalar data types?
3) a) Write short notes on encapsulation and structured data types (or)
b) Write short notes on type definition.
4) a) Explain in detail about functional programming? (or)
b) Write shorts on programs with functions?
5) a) Explain about formal semantics with sample small languages? (or)
b) Write short notes on operational semantics?
SECTION C-(05X10=50 marks)
Answer ALL the Questions
6) a) Explain in detail about formal translation models (or)
b) Explain briefly stages in translation.
7) a) Explain about composite data types and scalar data types (or)
b) Explain about formal properties of languages
8) a) Explain briefly about encapsulation by subprograms. (or)
b) Explain about polymorphism and inheritance.
9) a) Explain on recursive functions and lambda calculus (or)
b) Explain briefly on logic and logic programs
10) a) Discuss about message passing and monitors (or)
b) Explain about semaphore and threads.

119
M.Sc (CS) Degree examination
PRINCIPLES OF PROGRAMMING LANGUAGES
Time: Three hours maximum: 75 marks
SECTION A-(05X05=25 marks)
Answer ALL the Questions
1) a) Write short notes programming environment (or)
b) Explain about recursive descent parsing
2) a) Write short notes on language semantics (or)
b) Discuss about properties of types and objects?
3) a) What is inheritance? Explain the concepts of inheritance. (or)
b) Write short notes on implicit passing of information
4) a) Explain about mathematical functional programming? (or)
b) Discuss on delayed evaluation?
5) a) Explain in detail about program correctness? (or)
b) Explain about monitors and threads?
SECTION C-(05X10=50 marks)
Answer ALL the Questions
6) a) Explain in detail on impact of machine architectures (or)
b) Explain briefly stages in translation.
7) a) Discuss about modeling language properties. (or)
b) Explain about composite data types.
8) a) Explain briefly about encapsulation by subprograms. (or)
b) Explain about polymorphism and inheritance.
9) a) Explain briefly on LISP (or)
b) Explain briefly on functional programming with static typing
10) a) Discuss about denotation semantics (or)
b) Explain the parallel processing and programming languages.

120

Вам также может понравиться