BCT 2104
PRINCIPLES OF
PROGRAMMING LANGUAGES
Lecture 1b:Introduction and Motivation
More is not better (or worse) than less, just different.
{The paradigm paradox}
Imperative/ Procedural programming
Most widely used & oldest paradigm
Largest number of languages
E.g. C, FORTRAN, Java/C++ (without the objects)
Features closely related to machine architecture
Based on the von Neumann stored program model
An imperative programmer declares a set of variables and data
structures that represent his/her view of the memory of the
computer.
Weak abstraction: the ability to uses names instead of addresses.
But the programming still largely requires thinking about how memory
needs to be modified.
Procedures/subroutines and objects extend this abstraction, but
they still have the same focus on modifying memory via variables.
Imperative programming contd…
An imperative program essentially consists of a sequence
of assignments to variables.
The sequence may contain loops, jumps, branches, etc
These are abstracted as for-loops, while-loops, case-
statements, etc.
More precisely, the program describes a set of possible
sequences.
Program execution consists of performing these
assignments in the sequence described by the program.
The exact sequence actually performed generally depends
on the input (and so does the output).
Turing Completeness
A programming language is said to be Turing Complete if it
contains
Integer variables, values and operations
Assignments, branching, sequencing, and conditionals
Other features make languages easier to program for complex
applications
Loops
Procedures
Object Orientation
But they have the same power as any other programming
language
i.e. what is possible to compute in one is possible in the
other
Other Features
Typical Turing complete language today supports:
Data types for reals, chars, strings, booleans
For, while, switch
Arrays
Records
I/O commands
Pointers
Procedures and functions
Imperative Programming Design Principles
Structured Programming
The structure of the program text should be the guide to
understanding what it does.
Can be more efficient
Improved readability
Easier to tune and modify
Efficiency
A language must allow an underlying assignment-oriented machine
to be used directly and efficiently.
Driving factor in the implementation of many imperative languages
Types in Typical Imperative
Languages
Emphasis on data structures with assignable
components
Based on values that can be manipulated directly by
underlying machine
Size and layout fixed at compile time
Storage allocated and deallocated explicitly
Strongly typed
Storage efficiency is key
Issues with imperative programming
Imprecise semantics
Different implementations often behave differently
Portability problem
Constrained order of execution
side-effects
different execution orders give different results
difficult to introduce parallelism
Weak abstraction mechanisms
the programmer often has to consider the computer and its store
Difficulty of storage management
The updating of variables and the manual reuse of store leads to errors due
to overwritten values, dangling pointers, aliasing, etc.
Java, C#, etc. partly avoid this by garbage collection (as in FP).
What is functional programming?
At a high level: functional programming focuses on
building functions.
The programmer declares what the program does by
defining a function that maps inputs to outputs.
Complex functions are built by composing simpler
functions.
letsquare x = x*x letsumSqr(x,y) = square x + square y
Generally this means functions in the mathematical
sense:
In particular, variables are not modified by the code.
Instead variables are just names for values.
Functional Programming: Point of Departure
Functional programming departs from the imperative model by retaining
the mathematical form of variables. This means that modifying variables
is not allowed.
Instead, to evaluate a formula many times, it is placed in a function, and
the function is called many times. This is exactly what is done in
mathematics.
Instead of loops and gotos, recursive functions are emphasized, as well as
applying functions to each element in a list or collection.
There is also an emphasis on writing simple but general functions. E.g.,
to sum the squares of the numbers from 1 to 10:
let k = sum [for xin 1..10 -> x*x]
Abstraction in Functional Languages
Functional languages are deliberately less directly based on the way
the CPU and memory work.
The programmer declares a set of data types that define the data on
which the program will operate
strong abstraction: values and store are distinct
how values are represented is left up to the implementation
The program consists of function definitions over values of these data
types: functions may be built from any well-defined operations on the
data.
Program execution consists of applying one of the defined functions to
some input values.
Advantages
Precise formal semantics
Flexible order of execution
functions operate “in isolation”
natural parallel interpretation
particularly true for “pure” functional languages
Rich abstraction mechanisms
values are distinct from the store
abstract over functions, infinite data structures, etc
Automatic storage management
let the system do the work!
Disadvantages
The programmer has less control over exactly what happens with the
CPU and memory.
More efficient programs are often possible in a lower level language like C
(with some work).
Sometimes a bad order of execution may lead to excessive memory use.
strict functional languages like F# largely avoid this. HOW???
Sometimes the natural way of expressing an algorithm is via a sequence
of assignments.
Modern functional languages generally support imperative programming also
in some way.
Pure FLs like Haskell use monads. (A structure that represents
computations defined as a sequence of steps. This allows the
programmer to apply pipelining)
What is FP used for?
Lisp and Scheme are used widely in the field of artificial intelligence, as
extension languages (e.g. for AutoCAD) and for general programming
ML(including F#) is used for building robust software, language related
tools, formal verification tools, scientific programming, financial
programming and general programming
Haskell is used widely for fast prototyping of programs, to build tools for
hardware design and verification, to prototype implementations of new
languages and for general programming
Erlang is used at Ericsson and related companies for many applications in
the field of telecommunications
Many special purpose languages such as SQL(for database queries) and
XSLT(for XML transformations) are functional languages
Functional languages have survived the test of time, and continue to
spread and influence other languages
References
Balci, O. (1998), Software Engineering Lecture
Notes, Department of Computer Science, Virginia
Tech, Blacksburg, VA.
Schach, R. (1999), Software Engineering, Fourth
Edition, McGraw-Hill, Boston, MA.