Download as pdf or txt
Download as pdf or txt
You are on page 1of 111

Programming Principles and

Paradigms

A Course Material for


CSC 331

S. O. AKINOLA (PhD)

1
General Introduction and Course Objective

By now, in the course of your studies in this programme, you have been exposed to computer
programming using some programming languages like Java and / or Python or any other.
The principles underlying the structures of these languages have not been exposed to you.

This course will NOT teach you:

 any practical programming languages; nor


 how to implement high performance programming languages.

But it will teach you:

 some common programming languages existing: their syntax and semantics


 the design elements of programming languages
 how to choose a programming language for a particular task;

Course Curriculum Contents

CSC 331 (PROGRAMMING PRINCIPLES AND PARADIGMS)


Programming Principles: History and Evolution of Programming Languages. Syntax of
Programming Languages. Semantics of Programming Languages. Procedure Calls and
parameter passing. Memory allocation and management. Type systems. Programming
paradigms: Object Oriented Programming. Functional Programming. Event-oriented
programming. Logic Programming.
Laboratory exercises
Semester 1, LH 30; PH 45; 3U; Status C

2
Table of Contents

Study Session 1: Computer Programming Fundamentals


1.1 Meaning of Computer Programming
1.2 Overview of Programming Languages
1.3 Similarities and differences between a compiler and interpreter

Study Session 2: Types of Programming Languages


2.1 Algorithmic or Scientific Programming Languages
2.2 Business-Oriented Languages
2.3 Education-Oriented Languages
2.4 Object-Oriented Languages
2.5 Functional Programming Languages
2.6 Declarative Languages
2.7 Scripting Languages
2.8 Document Formatting Languages
2.9 World Wide Web Display Languages
2.10 Web Scripting
2.11 Other categorization based on declaration of variables

Study Session 3: Programming Paradigms


3.1 Meaning and Importance of Programming Paradigms
3.2 Structured Programming Paradigm
3.3 Procedure-Oriented Programming Paradigm
3.4 Modular Programming
3.5 Object Oriented Programming Paradigm
3.6 Historical Perspective of Programming Languages
3.7 The .Net Framework

Study Session 4: Applications of Programming Languages


4.1 Scientific Applications
4.2 Data Processing Applications
4.3 Text Processing Applications
4.4 Artificial Intelligence (AI)
4.5 Systems Programming Applications

Study Session 5: Evaluation of Programming Languages


5.1 Expressivity:
5.2 Well-definedness
5.3 Data Types and Structures
5.4 Modularity
5.5 Input-output facilities
5.6 Portability
5.7 Efficiency
5.8 Pedagogy
5.9 Generality:
5.10 Other Quality Design Criteria

Study Session 6: Language Design: Syntax


6.1 The Importance of Language’s Syntax?

3
6.2 Backus-Naur Form (BNF)
6.3 The Issue of Delimiters
6.4 Some other lexical/ syntax representation as found in PASCAL
6.5 Lexical Analysis and the Compiling Process
6.6 Syntactic Analysis
6.7 Limitations of BNF Syntax
6.8 Syntactic Ambiguity
6.9 Variations on BNF

Study Session 7: Programming Type Systems


7.1 Meaning of a Type System?
7.2 Elementary Types, Values and Expressions
7.3 Elementary Types in Programming Languages
7.4 Static vs. Dynamic, Weak vs Strong Typing
7.5 Advantages of Typed Programs
7.6 Disadvantages of Typed Programs

Study Session 8: Functional vs. Imperative Languages


8.1 Meaning of Imperative Languages?
8.2 Specific Nature and Problems of Imperative Languages
8.3 Naming and Variables in Imperative Languages
8.4 Declarative vs. imperative programming
8.5 Advantages and disadvantages of imperative programming languages
8.6 Functional Programming Languages
8.7 Why functional programming is more relevant today than ever
8.8 Advantages and disadvantages of functional programming
8.9 Functional programming using the example of a parser
8.10 The Lambda λ Calculus

Study Session 9: Structured Query Language


9.1 Meaning of SQL
9.2 Business Uses of SQL
9.3 Relational Database Management System (RDBMS)
9.3 Creating Microsoft Access Database Tables
9.4 Where to type SQL statements in Microsoft Access "2007", "2010", "2013" or
Access "2016"
9.5 Some SQL Statements and Their Implications

Study Session 10: Function and Operator Overloading, Conversion and Casting
10.1 Meaning of Overloading
10.2 Function/Method Overloading in C++
10.3 Function/Method Overloading in Java
10.4 Operator Overloading
10.5 Conversion and Casting

Study Session 11: Syntax and Semantics of Control Statements in Real Languages
11.1 for / while loops
11.2 Do statement
11.3 switch (case) statements
11.4 break and continue statements

4
Study Session 12: Scope, Visibility and Lifetime of Variables
12.1 Scope of Variables
12.2 Nested Functions
12.3 Uniqueness of Identifiers

Study Session 13: Memory Management in Programs


13.1 Memory Management
13.2 Structure of Run-time Memory
13.3 Methods, Locals, Parameters and the Run-Time Stack
13.4 Argument – Parameter Linkage
13.5 Pointers
13.6 Arrays
13.7 Structures

Study Session 14: Mobile Application Programming


14.1 Application Programming
14.2 Mobile App Development Issues
14.3 Challenges

REFERENCES

5
Study Session 1: Computer Programming Fundamentals
Expected Duration: 1 week or 2 contact hours

Introduction
Computer programming is no more new to you. You have passed through at least two
programming language courses in the lower levels. In this Session, you will be reminded of
the meaning of programs, computer programming and general overview of computer
programming languages.

Learning Outcomes
When you have studied this session, you should be able to explain:
1.1 Meaning of Computer Programming
1.2 Overview of Programming Languages
1.3 Similarities and differences between a compiler and interpreter

1.1 Meaning of Computer Programming

Computer programming is the craft of writing useful, maintainable, and extensible source
code that can be interpreted or compiled by a computing system to perform a meaningful
task. Programming a computer can be performed in one of numerous languages, ranging
from a higher-level language to writing directly in low-level machine code (that is, code that
more directly controls the specifics of the computer's hardware) all the way down to writing
microcode (which does directly control the electronics in the computer).

Computer programming is one part of a much larger discipline known as software


engineering, which includes several different aspects of making software including design,
construction and quality control. The phrase software construction can be termed to be
programming. Computer programming is also a useful skill (though not always necessary)
for people who are interested in computer science. Whereas software engineering is
interested specifically in making software, computer science tends to be oriented towards
more theoretical or mathematical problems.

Although there are over 2,000 computer languages, relatively few are widely used. Machine
and assembly languages are “low-level,” requiring a programmer to manage explicitly all
of a computer’s idiosyncratic features of data storage and operation. In contrast, high-level
languages shield a programmer from worrying about such considerations and provide
a notation that is more easily written and read by programmers.

Three different interests are involved in studying programming languages:


(i) Language designers;
(ii) Professional programmers and
(iii) Language implementers.

All three interests work within the constraints and capabilities provided by a computer
organization and the fundamental limitations of computability itself.

A programmer could be a person using programming languages to develop applications or


someone who writes a compiler.

6
A language designer designs a language – its vocabulary and other pragmatics of the
language. A language implementer is a person or group that develops a compiler or
interpreter for a language on a particular machine. Most often, the primary compiler for
language Y on machine X is developed by the corporation that manufactures machine X.
For example, we have many versions of FORTRAN compilers in use. We have compilers
for IBM machines, DEC and Pentium.

The different interest groups must understand the needs and constraints that govern the other
two activities. A good language designer must be a good programmer. In many cases, the
designer of a language is also its primary implementer; who must have unusual
programming and software engineering skills.

Tutorial Questions
1. Identify all the programming languages stakeholders and their functions.
2. Why do you think high level programming languages are better than low level
languages.

1.2 Overview of Programming Languages

Programming languages are classified into two ways – by their level and by their principal
applications. There are four distinct levels of programming languages.

1. Declarative – They are English-like in their expressive power and functionality.


They are fundamentally command languages; dominated by statements, which
express “what to do” rather than “how to do it”. For example, SAS, SPSS, SQL,
etc. These languages are developed for quick assimilation and are used by skilled
professionals at work.

2. High Level Languages – Although, not fundamentally declarative, these languages


allow algorithms to be expressed in a level and style of writing which is easily read
and understood by others. They have the characteristics of portability –
implementable on several machines so that a program may be easily “ported”
(transferred) from one machine to another without substantial revision. That means
they are machine independent. For examples, PASCAL, C, FORTRAN.

3. Assembly and (4) Machine Languages – They are machine dependent. Each
machine species such as Pentium, Motorola, has its own distinct machine language
and associated assembly language. The assembly language is simply a symbolic
representation form for its associated machine language; allowing less tedious
programming than the latter. However, a mastery of the underlying machine
architecture is necessary for effective programmer. As a matter of fact, the lower the
level of a language, the closer it is to complete representation by a particular machine
specie and the further it is from comprehension by humans.

There is a close relationship (1 to 1 correspondence) between assembly statements and their


encoded machine language forms. The main difference is that symbols (X, Y, Z; A for Add,
M for multiply) are used in assembly while numeric codes (OC1A4) are required for
comprehension by machine.

7
C Language Assembly Language Machine Language

C=W+X*Y L 3, X 413OC1A4
M 2, Y 3A2OC1A8
A 3, W 1A3OC1A0
ST 3, Z 50 3OC1A4

Both assembly and high level languages require an interface with the machine language at
the time a program is to be run.

A machine language consists of the numeric codes for the operations that a particular
computer can execute directly. The codes are strings of 0s and 1s, or binary digits (“bits”),
which are frequently converted both from and to hexadecimal (base 16) for human viewing
and modification. Machine language instructions typically use some bits to represent
operations, such as addition, and some to represent operands, or perhaps the location of the
next instruction. Machine language is difficult to read and write, since it does not resemble
conventional mathematical notation or human language, and its codes vary from computer
to computer.

Assembly language is one level above machine language. It uses short mnemonic codes for
instructions and allows the programmer to introduce names for blocks of memory that hold
data. One might thus write “add pay, total” instead of “0110101100101000” for an
instruction that adds two numbers.

Assembly language is designed to be easily translated into machine language. Although


blocks of data may be referred to by name instead of by their machine addresses, assembly
language does not provide more sophisticated means of organizing complex information.
Like machine language, assembly language requires detailed knowledge of internal
computer architecture. It is useful when such details are important, as in programming a
computer to interact with input/output devices (printers, scanners, storage devices, and so
forth)

Tutorial Question: Differentiate among Declarative, High level, Assembly and Machine
languages.

1.3 Similarities and differences between a compiler and interpreter

Similarities
(i) Both are programs / tools of correct programming
(ii) They both translate a program into computer machine language
(iii) They both check programs for syntactic and semantic correctness
(iv) The lexical and syntax phases of compilation may be likened to the interpreter

Differences
(i) Translation is done once by compiler into an object program. An interpreter does
not produce object programs
(ii) Effort to execute an interpreted program is better than compiled programs
(iii) Interpreter is more versatile than compiler
(iv) Run time error is easily thrashed by interpreter than compilers
(v) Debugging is easier in interpreter than in compiler

8
(vi) Speed of execution of source program is higher with compilers than interpreters

Summary
In this brief introductory session, you have learnt the meaning of Computer Programming,
general overview of programming languages, similarities and differences between a
compiler and interpreter.

Now attempt to answer the following simple questions:

Self Assessment Questions


1. Why do we need a programming language?
2. Explain the different group of stakeholders involved in programming languages.
3. State the similarities and differences between a compiler and interpreter.
4. Different among the different categories of programming languages
5. All language designers are programmers but not all programmers are designers.
Discuss.

9
Study Session 2: Types of Programming Languages
Expected Duration: 1 week or 2 contact hours

Introduction
There are different types of programming languages in the world today. In fact thousands
of Computer Programming Languages abound in world’s natural languages. Can you
mention some of the programming languages you have heard of? How many of them have
you written before? In this session

Learning Outcomes
When you have studied this session, you should be able to explain:
2.1 Algorithmic or Scientific Programming Languages
2.2 Business-Oriented Languages
2.3 Education-Oriented Languages
2.4 Object-Oriented Languages
2.5 Functional Programming Languages
2.6 Declarative Languages
2.7 Scripting Languages
2.8 Document Formatting Languages
2.9 World Wide Web Display Languages
2.10 Web Scripting
2.11 Other categorization based on declaration of variables

2.1 Algorithmic or Scientific Programming Languages

Algorithmic languages are designed to express mathematical or symbolic computations.


They can express algebraic operations in notation similar to mathematics and allow the use
of subprograms that package commonly used operations for reuse. They were the first high-
level languages. Let us look into some of these languages one by one:

A. FORTRAN

The first important algorithmic language was FORTRAN (formula translation), designed in
1957 by an IBM team led by John Backus. It was intended for scientific computations with
real numbers and collections of them organized as one - or multi-dimensional arrays. Its
control structures included conditional IF statements, repetitive loops (so-called DO loops),
and a GOTO statement that allowed non-sequential execution of program code. FORTRAN
made it convenient to have subprograms for common mathematical operations, and built
libraries of them. FORTRAN was also designed to translate into efficient machine language.
It was immediately successful and continues to evolve.

B. ALGOL

ALGOL (algorithmic language) was designed by a committee of American and European


computer scientists during 1958–60 for publishing algorithms, as well as for doing
computations. Like LISP (described in the next section), ALGOL had recursive
subprograms—procedures that could invoke themselves to solve a problem by reducing it

10
to a smaller problem of the same kind. ALGOL introduced block structure, in which a
program is composed of blocks that might contain both data and instructions and have the
same structure as an entire program. Block structure became a powerful tool for building
large programs out of small components.

ALGOL contributed a notation for describing the structure of a programming language,


Backus–Naur Form, which in some variation became the standard tool for stating the syntax
(grammar) of programming languages. ALGOL was widely used in Europe, and for many
years it remained the language in which computer algorithms were published. Many
important languages, such as Pascal and ADA (both described later), are its descendants.

C. LISP

LISP (list processing) was developed about 1960 by John McCarthy at the Massachusetts
Institute of Technology (MIT) and was founded on the mathematical theory of recursive
functions (in which a function appears in its own definition). A LISP program is a function
applied to data, rather than being a sequence of procedural steps as in FORTRAN and
ALGOL. LISP uses a very simple notation in which operations and their operands are given
in a parenthesized list. For example, (+ a (* bc)) stands for a + b*c. Although this appears
awkward, the notation works well for computers. LISP also uses the list structure to
represent data, and, because programs and data use the same structure, it is easy for a LISP
program to operate on other programs as data.

LISP became a common language for artificial intelligence (AI) programming, partly owing
to the confluence of LISP and AI work at MIT and partly because AI programs capable of
“learning” could be written in LISP as self-modifying programs. LISP has evolved through
numerous dialects, such as Scheme and Common LISP.

D. C

The C programming language was developed in 1972 by Dennis Ritchie and Brian
Kernighan at the AT&T Corporation for programming computer operating systems. Its
capacity to structure data and programs through the composition of smaller units is
comparable to that of ALGOL. It uses a compact notation and provides the programmer
with the ability to operate with the addresses of data as well as with their values. This ability
is important in systems programming, and C shares with assembly language the power to
exploit all the features of a computer’s internal architecture. C++, along with its descendant
C++, remains one of the most common languages.

Tutorial Question: Attempt to explain the evolution, nature and application of any three
algorithmic programming languages.

2.2 Business-Oriented Languages


These are programming languages designed for business or commercial applications.
Among which are COBOL, SQL and Visual Basic

A. COBOL

COBOL (common business oriented language) has been heavily used by businesses since
its inception in 1959. A committee of computer manufacturers, users and U.S. government

11
organizations established CODASYL (Committee on Data Systems and Languages) to
develop and oversee the language standard in order to ensure its portability across diverse
systems.

COBOL uses an English-like notation—novel when introduced. Business computations


organize and manipulate large quantities of data, and COBOL introduced the record data
structure for such tasks. A record clusters heterogeneous (dissimilar) data such as a name,
ID number, age, and address into a single unit. This contrasts with scientific languages, in
which homogeneous arrays of numbers are common. Records are an important example of
“chunking” data into a single object, and they appear in nearly all modern languages.

B. SQL

SQL (structured query language) is a language for specifying the organization of databases
(collections of records). Databases organized with SQL are called relational because SQL
provides the ability to query a database for information that falls in a given relation. For
example, a query might be “find all records with both lastname: Usman and city: Lagos.”
Commercial database programs commonly use a SQL-like language for their queries.

Tutorial Question:
(i) What is/are the main differences between Scientific and Business-oriented
programming languages.
(ii) Explain what you know about Visual Basic dot Net

2.3 Education-Oriented Languages


These programming languages are originally designed for teaching. Their primary purpose
is to use them to impact knowledge of programming to students. However, they are also
suitable for scientific or business applications. Let us study some of them in the next
sections.

A. BASIC

BASIC (Beginner’s All-purpose Symbolic Instruction Code) was designed at Dartmouth


College in the mid-1960s by John Kemeny and Thomas Kurtz. It was intended to be easy to
learn by novices, particularly non-computer science majors, and to run well on a time-
sharing computer with many users. It had simple data structures and notation and it was
interpreted: a BASIC program was translated line-by-line and executed as it was translated,
which made it easy to locate programming errors. Its small size and simplicity also made
BASIC a popular language for early personal computers. Its recent forms have adopted
many of the data and control structures of other contemporary languages, which makes it
more powerful but less convenient for beginners.

B. PASCAL

About 1970 Niklaus Wirth of Switzerland designed Pascal to teach structured programming,
which emphasized the orderly use of conditional and loop control structures without GOTO
statements. Although Pascal resembled ALGOL in notation, it provided the ability to define
data types with which to organize complex information, a feature beyond the capabilities of
ALGOL as well as FORTRAN and COBOL. User-defined data types allowed the

12
programmer to introduce names for complex data, which the language translator could then
check for correct usage before running a program.

During the late 1970s and ’80s, Pascal was one of the most widely used languages for
programming instruction. It was available on nearly all computers, and, because of its
familiarity, clarity, and security, it was used for production software as well as for education.

C. LOGO

Logo originated in the late 1960s as a simplified LISP dialect for education; Seymour Papert
and others used it at MIT to teach mathematical thinking to schoolchildren. It had a more
conventional syntax than LISP and featured “turtle graphics,” a simple method for
generating computer graphics. (The name came from an early project to program a turtle-
like robot.) Turtle graphics used body-centred instructions, in which an object was moved
around a screen by commands, such as “left 90” and “forward,” that specified actions
relative to the current position and orientation of the object rather than in terms of a fixed
framework. Together with recursive routines, this technique made it easy to program
intricate and attractive patterns.

D. HYPERTALK

Hypertalk was designed as “programming for the rest of us” by Bill Atkinson for Apple’s
Macintosh. Using a simple English-like syntax, Hypertalk enabled anyone to combine text,
graphics, and audio quickly into “linked stacks” that could be navigated by clicking with a
mouse on standard buttons supplied by the program. Hypertalk was particularly popular
among educators in the 1980s and early ’90s for classroom multimedia presentations.
Although Hypertalk had many features of object-oriented languages (described in the next
section), Apple did not develop it for other computer platforms and let it languish; as
Apple’s market share declined in the 1990s, a new cross-platform way of displaying
multimedia left Hypertalk all but obsolete (see the section World Wide Web display
languages).

2.4 Object-Oriented Languages

Object-oriented languages help to manage complexity in large programs. Objects package


data and the operations on them so that only the operations are publicly accessible and
internal details of the data structures are hidden. This information hiding made large-scale
programming easier by allowing a programmer to think about each part of the program in
isolation. In addition, objects may be derived from more general ones, “inheriting” their
capabilities. Such an object hierarchy made it possible to define specialized objects without
repeating all that is in the more general ones.

Object-oriented programming began with the Simula language (1967), which added
information hiding to ALGOL. Another influential object-oriented language was Smalltalk
(1980), in which a program was a set of objects that interacted by sending messages to one
another. Other OOP languages are discussed next.

13
A. C++

The C++ language, developed by Bjarne Stroustrup at AT&T in the mid-1980s, extended C
by adding objects to it while preserving the efficiency of C programs. It has been one of the
most important languages for both education and industrial programming. Large parts of
many operating systems, such as the Microsoft Corporation’s Windows 98, were written in
C++.

B. ADA

ADA was named for Augusta ADA King, countess of Lovelace, who was an assistant to the
19th-century English inventor Charles Babbage, and is sometimes called the first computer
programmer. ADA, the language, was developed in the early 1980s for the U.S. Department
of Defense for large-scale programming. It combined Pascal-like notation with the ability
to package operations and data into independent modules. Its first form, ADA 83, was not
fully object-oriented, but the subsequent ADA 95 provided objects and the ability to
construct hierarchies of them. While no longer mandated for use in work for the Department
of Defense, ADA remains an effective language for engineering large programs.

C. JAVA

In the early 1990s, Java was designed by Sun Microsystems, Inc., as a programming
language for the World Wide Web (WWW). Although it resembled C++ in appearance, it
was fully object-oriented. In particular, Java dispensed with lower-level features, including
the ability to manipulate data addresses, a capability that is neither desirable nor useful in
programs for distributed systems. In order to be portable, Java programs are translated by a
Java Virtual Machine specific to each computer platform, which then executes the Java
program. In addition to adding interactive capabilities to the Internet through Web “applets,”
Java has been widely used for programming small and portable devices, such as mobile
telephones.

D. VISUAL BASIC

Visual Basic was developed by Microsoft to extend the capabilities of BASIC by adding
objects and “event-driven” programming: buttons, menus, and other elements of graphical
user interfaces (GUIs). Visual Basic can also be used within other Microsoft software to
program small routines.

2.5 Functional Programming Languages

The term functional programming means various things. Functional programming views
functions as ordinary data which, in particular, can be passed as arguments to other functions
and stored in data structures. A common idea behind functional programming is that
repetitive patterns can be abstracted away as functions that may be called several times so
as to avoid code duplication. Take for example, if you are to write program to compute N
Combination R, which is given mathematically as
n!
nCr =
(n – r)! r!

14
One single function can be written for the factorial. This single function will be called to
execute n!, (n – r)! and r!; instead of repeating same process for each of these terms.

For this reason, functional programming also often loosely or strongly discourages the use
of modifiable data, in favor of effect-free transformations of data. (In contrast, the
mainstream object-oriented programming languages view objects as the primary kind of
data and encourage the use of modifiable data.)

Functional programming languages are traditionally typed (Scheme and Erlang are
exceptions) and have close connections with logic. Because functional programming puts
emphasis on reusability and sharing multiple uses of the same code, even in different
contexts, they require and make heavy use of polymorphism; when programming in the
large, abstraction over implementation details relies on an expressive module system. Types
unquestionably play a central role, as explained later. Functional programming languages
are usually given a precise and formal semantics derived from the one of the lambda λ-
calculus. The semantics of languages differ in that some are strict (ML) and some are lazy
(Haskell) Hughes (1989). This difference has a large impact on the language design and on
the programming style, but has usually little impact on typing. Functional programming
languages are usually sequential languages, whose model of evaluation is not concurrent,
even if core languages may then be extended with primitives to support concurrency.

Functional languages, such as LISP, ML, and Haskell, are used as research tools in language
development, in automated mathematical theorem provers, and in some commercial
projects.

2.6 Declarative Languages

Declarative languages, also called nonprocedural or very high level, are programming
languages in which (ideally) a program specifies what is to be done rather than how to do
it. In such languages there is less difference between the specification of a program and its
implementation than in the procedural languages described so far. The two common kinds
of declarative languages are logic and functional languages.

Logic programming languages, of which PROLOG (programming in logic) is the best


known, state a program as a set of logical relations (e.g., a grandparent is the parent of a
parent of someone). Such languages are similar to the SQL database language. A program
is executed by an “inference engine” that answers a query by searching these relations
systematically to make inferences that will answer a query. PROLOG has been used
extensively in natural language processing and other AI programs. Functional languages
have a mathematical style. A functional program is constructed by applying functions to
arguments.

2.7 Scripting Languages

Scripting languages are sometimes called little languages. They are intended to solve
relatively small programming problems that do not require the overhead of data declarations
and other features needed to make large programs manageable. Scripting languages are used
for writing operating system utilities, for special-purpose file-manipulation programs, and,
because they are easy to learn, sometimes for considerably larger web-based programs.

15
PERL (Practical Extraction and Report Language) was developed in the late 1980s,
originally for use with the UNIX operating system. It was intended to have all the
capabilities of earlier scripting languages. PERL provided many ways to state common
operations and thereby allowed a programmer to adopt any convenient style. In the 1990s it
became popular as a system-programming tool, both for small utility programs and for
prototypes of larger ones. Together with other languages discussed below, it also became
popular for programming computer Web “servers.”

2.8 Document Formatting Languages

Document formatting languages specify the organization of printed text and graphics. They
fall into several classes: text formatting notation that can serve the same functions as a word
processing program, page description languages that are interpreted by a printing device
and, most generally, markup languages that describe the intended function of portions of a
document

A. TeX

TeX was developed during 1977–86 as a text formatting language by Donald Knuth, a
Stanford University professor, to improve the quality of mathematical notation in his books.
Text formatting systems, unlike WYSIWYG (“What You See Is What You Get”) word
processors, embed plain text formatting commands in a document, which are then
interpreted by the language processor to produce a formatted document for display or
printing. TeX marks italic text, for example, as {\it this is italicized}, which is then displayed
as this is italicized.

TeX largely replaced earlier text formatting languages. Its powerful and flexible abilities
gave an expert precise control over such things as the choice of fonts, layout of tables,
mathematical notation, and the inclusion of graphics within a document. It is generally used
with the aid of “macro” packages that define simple commands for common operations,
such as starting a new paragraph; LaTeX is a widely used package. TeX contains numerous
standard “style sheets” for different types of documents, and these may be further ADApted
by each user. There are also related programs such as BibTeX, which manages
bibliographies and has style sheets for all of the common bibliography styles, and versions
of TeX for languages with various alphabets.

B. POSTSCRIPT

PostScript is a page-description language developed in the early 1980s by Adobe Systems


Incorporated on the basis of work at Xerox PARC (Palo Alto Research Center). Such
languages describe documents in terms that can be interpreted by a personal computer to
display the document on its screen or by a microprocessor in a printer or a typesetting device.
PostScript commands can, for example, precisely position text, in various fonts and sizes,
draw images that are mathematically described, and specify colour or shading. PostScript
uses postfix, also called reverse Polish notation, in which an operation name follows its
arguments. Thus, “300 600 20 270 arc stroke” means: draw (“stroke”) a 270-degree arc with
radius 20 at location (300, 600). Although PostScript can be read and written by a
programmer, it is normally produced by text formatting programs, word processors, or
graphic display tools. The success of PostScript is due to its specification’s being in the
public domain and to its being a good match for high-resolution laser printers. It has

16
influenced the development of printing fonts, and manufacturers produce a large variety of
PostScript fonts.

C. SGML

SGML (Standard Generalized Markup Language) is an international standard for the


definition of markup languages; that is, it is a metalanguage. Markup consists of notations
called tags that specify the function of a piece of text or how it is to be displayed. SGML
emphasizes descriptive markup, in which a tag might be “<emphasis>.” Such a markup
denotes the document function, and it could be interpreted as reverse video on a computer
screen, underlining by a typewriter, or italics in typeset text. SGML is used to specify DTDs
(document type definitions). A DTD defines a kind of document, such as a report, by
specifying what elements must appear in the document—e.g., <Title>—and giving rules for
the use of document elements, such as that a paragraph may appear within a table entry but
a table may not appear within a paragraph. A marked-up text may be analyzed by a parsing
program to determine if it conforms to a DTD. Another program may read the markups to
prepare an index or to translate the document into PostScript for printing. Yet another might
generate large type or audio for readers with visual or hearing disabilities.

2.9 World Wide Web Display Languages

A. HTML

The World Wide Web is a system for displaying text, graphics, and audio retrieved over the
Internet on a computer monitor. Each retrieval unit is known as a Web page, and such pages
frequently contain “links” that allow related pages to be retrieved. HTML (hypertext markup
language) is the markup language for encoding Web pages. It was designed by Tim Berners-
Lee at the CERN nuclear physics laboratory in Switzerland during the 1980s and is defined
by an SGML DTD. HTML markup tags specify document elements such as headings,
paragraphs, and tables. They mark up a document for display by a computer program known
as a Web browser. The browser interprets the tags, displaying the headings, paragraphs, and
tables in a layout that is adapted to the screen size and fonts available to it.

HTML documents also contain anchors, which are tags that specify links to other Web
pages. An anchor has the form <A HREF= “http://www.britannica.com”> Encyclopædia
Britannica </A>, where the quoted string is the URL (universal resource locator) to which
the link points (the Web “address”) and the text following it is what appears in a Web
browser, underlined to show that it is a link to another page. What is displayed as a single
page may also be formed from multiple URLs, some containing text and others graphics.

B. XML

HTML does not allow one to define new text elements; that is, it is not extensible. XML
(extensible markup language) is a simplified form of SGML intended for documents that
are published on the Web. Like SGML, XML uses DTDs to define document types and the
meanings of tags used in them. XML adopts conventions that make it easy to parse, such as
that document entities are marked by both a beginning and an ending tag, such as
<BEGIN>…</BEGIN>. XML provides more kinds of hypertext links than HTML, such as
bidirectional links and links relative to a document subsection. Because an author may
define new tags, an XML DTD must also contain rules that instruct a Web browser how to

17
interpret them—how an entity is to be displayed or how it is to generate an action such as
preparing an e-mail message.

2.10 Web Scripting

Web pages marked up with HTML or XML are largely static documents. Web scripting can
add information to a page as a reader uses it or let the reader enter information that may, for
example, be passed on to the order department of an online business. CGI (Common
Gateway Interface) provides one mechanism; it transmits requests and responses between
the reader’s Web browser and the Web server that provides the page. The CGI component
on the server contains small programs called scripts that take information from the browser
system or provide it for display. A simple script might ask the reader’s name, determine the
Internet address of the system that the reader uses, and print a greeting. Scripts may be
written in any programming language, but, because they are generally simple text-
processing routines, scripting languages like PERL are particularly appropriate.

Another approach is to use a language designed for Web scripts to be executed by the
browser. JavaScript is one such language, designed by the Netscape Communications Corp.,
which may be used with both Netscape’s and Microsoft’s browsers. JavaScript is a simple
language, quite different from Java. A JavaScript program may be embedded in a Web page
with the HTML tag <script language=“JavaScript”>. The browser will execute JavaScript
instructions following that tag when the page is selected. In order to speed up display of
dynamic (interactive) pages, JavaScript is often combined with XML or some other
language for exchanging information between the server and the client’s browser. In
particular, the XML HTTP Request command enables asynchronous data requests from the
server without requiring the server to resend the entire Web page. This approach, or
“philosophy,” of programming is called Ajax (asynchronous JavaScript and XML).

VB Script is a subset of Visual Basic. Originally developed for Microsoft’s Office suite of
programs, it was later used for Web scripting as well. Its capabilities are similar to those of
JavaScript, and it may be embedded in HTML in the same fashion. Behind the use of such
scripting languages for Web programming lies the idea of component programming, in
which programs are constructed by combining independent previously written components
without any further language processing. JavaScript and VB Script programs were designed
as components that may be attached to Web browsers to control how they display
information.

2.11 Other categorization based on declaration of variables

(a) Strongly Typed languages: These are languages that demand that their variables
and constants must be declared before they are used. One peculiarity of them is that
they are usually case sensitive. However, case sensitivity does not warrant a
language being strongly typed. Examples of languages in this category are C, C++,
Java, Pascal, etc.

(b) Weakly Typed languages: These languages have some implicit way of declaring
and using variables in them. There is no stringent rule for declaring variables in these
languages. Take for example, FORTRAN. In this language, any variable name
starting with I, J, K, L, M or N is regarded as being Integer-numeric. So, if we don’t
declare those variables before they are used, they are implicitly regarded as integers.

18
Other ones beginning with other letters are implicitly regarded as Real or floating
point numbers. Visual Basic too is somehow weak. It also has implicit naming
convention. For example, a variable declared such as Num% is regarded as Integer-
numeric. Weakly typed languages are not necessarily case sensitive.

(c) Loosely Typed Languages: In these types of languages, variables declared can
assume any value depending on the context of usage. The variables have multiple or
dynamic usages. In PHP, we can declare a variable $Name and be assigned a value
3.4. This means that $Name is a floating-point or real variable. At latter time, if we
assign to it “Akinola”, this assignment has changed its data type to a string value.
The same variable is used in different contexts. In other words, the data types of
variables depend on their present assignments. These languages are highly case
sensitive.

Summary
In this Session, you have been introduced to different categories of Computer Programming
languages. You had learnt that several programming languages exist starting from the
earliest scientific and Business oriented languages to the modern web scripting languages.
Now answer the following questions.

Self-Assessment Questions
1. Give one characteristic feature and one example each of the following programming
Languages:
(i) Imperative languages
(ii) OOP Languages
(iii) POP Languages
(iv) Scripting Languages
(v) Type-less Languages

2. Inheritance is peculiar with OOP languages.


(i) What is inheritance?
(ii) Give one example each of programming languages that support
single and multiple inheritance
(iii) What is the rationale behind using inheritance in programming?

19
Study Session 3: Programming Paradigms
Expected Duration: 1 week or 2 contact hours

Introduction
Paradigm means model, prototype or example. Therefore, in this session, we are interested
in studying the different models of computer programming that exist today.

Learning Outcomes
When you have studied this session, you should be able to explain:
3.1 Meaning and Importance of Programming Paradigms
3.2 Structured Programming Paradigm
3.3 Procedure-Oriented Programming Paradigm
3.4 Modular Programming
3.5 Object Oriented Programming Paradigm
3.6 Historical Perspective of Programming Languages
3.7 The .Net Framework

3.1 Meaning and Importance of Programming Paradigms

Programming paradigms are the fundamental principles used when developing software.
They are best described as fundamentally different programming styles, which in turn
result in differently structured software code. The classic concept is imperative
programming, where the source code clearly defines which steps a program has to
complete and in what order. Sub-types include procedural and object-oriented
programming. On the other hand, the declarative programming principle involves
describing only what software should do (i.e. only the result and not the individual steps).
Sub-types include functional programming and logic programming.

Tutorial Question: State the differences between Imperative and Declarative programming
paradigms?

Figure 3.1: Programming Paradigms (Source:


https://www.ionos.com/digitalguide/websites/web-development/programming-paradigms/)

20
Within the imperative programming paradigm, there are three important subordinate
methods for writing and structuring software code: structured, procedural, and modular
programming.

3.2 Structured Programming Paradigm

The structured programming method is a simplified form of imperative programming. The


crucial difference from the basic principle is that instead of absolute jump commands
(instructions that lead to processing continuing at another point instead of the next
command), this software programming paradigm makes use of control loops and
structures. An example is the use of “do...while”, which executes an instruction
automatically for as long as a particular condition is true (at least once).

Structured programming is an approach that breaks a program into logical sections, called
modules, in such a way as to minimize the program’s complexity. In other words,
modularity of programs’ source code is the essence of structured programming. A structured
program is classified as readable program.

Structured programming is a way of ensuring that subsidiary sections are arranged in such
a way that they can be worked on, truly independently, that is, without reference to other
parts of the program. Each section can be tested and debugged as it is completed; thus,
considerably enhancing the chances of obtaining a working program. In addition, if
problems do occur, they can be isolated and found very more easily than in a single complete
(monolithic) program. It is usually only necessary to correct code in the section in which the
problem occurred so that re-programming can also be minimized.

Conclusively, a structured program must be made up of a series of sections (modules). Each


of which must be able to do the following:

(i) It has a label or name.


(ii) Perform only one specified task.
(iii) Complete the task satisfactorily before continuing.
(iv) Have only one entry point.
(v) Have only one exit point.
(vi) Be composed of the necessary program statements or calls to other subsections,
which perform various subtasks and which themselves strictly satisfy these
conditions.
(vii) It should only call another module at a lower level than itself.
(viii) Be independent.

3.3 Procedure-Oriented Programming Paradigm

The procedural programming paradigm extends the imperative approach with the possibility
of dividing algorithms into more manageable sections. Depending on the programming
language, these are referred to as sub-programs, routines, or functions. The purpose of this
division is to make the programming code clearer and to prevent unnecessary code
repetitions. Because of the abstraction of algorithms, the procedural software paradigm
represents a crucial step from simple assembly languages towards more complex high-level
languages.

21
Conventional programming, using high-level languages such as COBOL, FORTRAN and
C, is commonly known as procedure-oriented programming (POP). Simple, POP programs
may be one "long" list of statements (or commands). More complex programs will often
group smaller sections of these statements into functions or subroutines, each of which
might perform a particular task. With designs of this sort, it is common for some of the
program's data to be 'global', i.e. accessible from any part of the program. As programs grow
in size, allowing any function to modify any piece of data means that bugs can have wide-
reaching effects. In essence, while we concentrate on the development of functions, very
little attention is given to the data that are being used by various functions. What happens
to the data? How are they affected by the functions that work on them?

In a multi-function program, many important data items are placed as global so that they
may be accessed by all the functions. Each function may have its own local data. Global
data are more vulnerable to an inadvertent change by a function. In a large program it is
very difficult to identify what data is used by which function. In case we need to revise an
external data structure, we also need to revise all functions that access the data. This provides
an opportunity for bugs to creep in.

Another serious drawback with the procedural approach is that it does not model real world
problems very well. This is because functions are action-oriented and do not really
correspond to the elements of the problem.

Some characteristics exhibited by procedure-oriented programming are:


 Emphasis is on doing things (algorithms)
 Large programs are divided into smaller programs known as functions.
 Most of the functions share global data.
 Data move openly around the system from function to function.
 Functions transform data from one form to another.
 Employs top-down approach in program design.

3.4 Modular programming

Modular programming is categorized as a subordinate form of the imperative programming


paradigm. It is essentially very similar to the procedural method and applies this
programming style to the requirements and demands of larger and more comprehensive
software projects. It involves selectively breaking down the source code into logical,
independent sub-blocks to ensure greater clarity and to simplify the debugging process.
The sub-blocks, known as modules, can be tested individually before they are subsequently
linked together to create a collective application.

3.5 Object Oriented Programming Paradigm

An object-oriented program will usually contain different types of objects, each type
corresponding to a particular kind of complex data to be managed or perhaps to a real-world
object or concept such as a bank account, a hockey player, or a bulldozer.

A program might well contain multiple copies of each type of object, one for each of the
real-world objects the program is dealing with. For instance, there could be one bank
account object for each real-world account at a particular bank. Each copy of the bank

22
account object would be alike in the methods it offers for manipulating or reading its data,
but the data inside each object would differ reflecting the different history of each account.

Objects can be thought of as wrapping their data within a set of functions designed to ensure
that the data are used appropriately, and to assist in that use. The object's methods will
typically include checks and safeguards that are specific to the types of data the object
contains. An object can also offer simple-to-use, standardized methods for performing
particular operations on its data, while concealing the specifics of how those tasks are
accomplished. In this way alterations can be made to the internal structure or methods of an
object without requiring that the rest of the program be modified.

This approach can also be used to offer standardized methods across different types of
objects. As an example, several different types of objects might offer print methods. Each
type of object might implement that print method in a different way, reflecting the different
kinds of data each contains, but all the different print methods might be called in the same
standardized manner from elsewhere in the program. These features become especially
useful when more than one programmer is contributing code to a project or when the goal
is to reuse code between projects.

An object-oriented program may thus be viewed as a collection of interacting objects, as


opposed to the conventional model, in which a program is seen as a list of tasks (subroutines)
to perform. In OOP, each object is capable of receiving messages, processing data, and
sending messages to other objects. Each object can be viewed as an independent "machine"
with a distinct role or responsibility. The actions (or "methods") on these objects are closely
associated with the object. For example, OOP data structures tend to "carry their own
operators around with them" (or at least "inherit" them from a similar object or class) -
except when they have to be serialized.

3.5.1 OOP Languages

Simula (1967) is generally accepted as the first language to have the primary features of an
object-oriented language. It was created for making simulation programs, in which what
came to be called objects were the most important information representation. Smalltalk
(1972 to 1980) is arguably the canonical example, and the one with which much of the
theory of object-oriented programming was developed. Concerning the degree of object
orientation, following distinction can be made:

 Languages called "pure" OO languages, because everything in them is treated


consistently as an object, from primitives such as characters and punctuation, all the
way up to whole classes, prototypes, blocks, modules, etc. They were designed
specifically to facilitate, even enforce, OO methods. Examples: Scala, Smalltalk, Eiffel,
JADE, Emerald.

 Languages designed mainly for OO programming, but with some procedural elements.
Examples: C++, Java, C#, VB.NET, Python.

 Languages that are historically procedural languages, but have been extended with some
OO features. Examples: Visual Basic (derived from BASIC), FORTRAN 2003, Perl,
COBOL 2002, PHP, ABAP.

23
 Languages with most of the features of objects (classes, methods, inheritance,
reusability), but in a distinctly original form. Examples: Oberon (Oberon-1 or Oberon-
2) and Common Lisp.

 Languages with abstract data type support, but not all features of object-orientation,
sometimes called object-based languages. Examples: Modula-2 (with excellent
encapsulation and information hiding), Pliant, CLU.

3.6 Historical Perspective of Programming Languages

We need to understand the historical evolution of languages, in order to appreciate why


different features are present. For instance, GOTO statements are forbidden in newer
languages and this is correct in the context of current philosophies of software engineering
and structured programming. GOTO combined with IF was the order of those days when
there was no facility for while or If –Then-Else constructs.

More important, history allows us to see the evolution of families of programming


languages, to see the influence of evolving computer architectures and applications on
language design and to avoid future design mistakes by learning lessons of the past.

From history, FORTRAN is scientific and had its origin from Algebra. COBOL was directly
designed for data processing and its linguistic origin was English. Church’s Lambda
Calculus provides the foundation for the functional notation of LISP (AI), while the Markov
algorithm motivates the pattern matching style of SNOBOL, meant for text processing.

Usually languages descend from other languages. For example, FORTRAN 77 is a direct
descendant of FORTRAN IV; MODULA-2 from MODULA, while all of FORTRAN,
COBOL, ALGOL 60, LISP, SNOBOL and Assembly Language influenced the design of
PL/1.

Figure 3.1 depicts how programming languages evolve from each other.

The Unix operating system was conceived of, designed, and written around 1972. Ken
Thompson was working on the design of Unix with Dennis Ritchie. It was their project that
encouraged Ritchie to create the C language. C was more structured than the assembly
language most operating systems were written in at the time and it was portable and could
be compiled to efficient machine code. Thompson and Ritchie wanted an operating system
that was portable, small, and well organized.

In 1980 Bjarne Stroustrup began working on the design of C++ whileworking at Bell Labs.
He envisioned C++ as a language that would allow C programmers to keep their old code
while new code could be written using these Object-Oriented concepts. In 1983 he named
this new language C++, as in the next increment of C, and with much anticipation, in 1985
the language was released. About the same time Dr. Stroustrup released a book called The
C++ Programming Language, which described the language.

C++ is a very powerful language, but also demands that programmers be very careful when
writing code. The biggest problem with C++ programs are memory leaks. When objects are
created on the heap in C++, they remain on the heap until they are freed. If a programmer
forgets to free an object, then that space cannot be re-used while the program is running.

24
That space is gone until the program is stopped, even if no code has a pointer to that object
anymore. This is a memory leak. And, for long-running C++ programs it is the number one
problem. Destructors are a feature of C++ that help programmers prevent memory leaks.
Depending on the structure of a class in a program, it may need a destructor to take care of
cleaning up instances of itself (i.e. objects of the class) when they are freed. C++ programs
can create objects in the run-time stack, on the heap, or within other objects. This is another
powerful feature of C++. But, with this power over the creation of objects comes more
responsibility for the programmer. This control over object creation leads to the need for
extra code to decide how copies of objects are made. In C++ every class may contain a copy
constructor so the programmer can control how copies of objects are made.

In 1991 a team called the Green Team, was working for a company named Sun
Microsystems. This group of software engineers wanted to design a programming language
and run-time system that could be used in the next generation of personal devices. The group
was led by a man named James Gosling. To support their vision, they designed the Java
Virtual Machine (i.e. JVM), a program that would interpret byte code files. The JVM was
designed as the run-time system for the Java programming language. Java programs, when
compiled, are translated into byte code files that run on the JVM. Java has become very
important in that respect. It now is the basis for the Android operating system that runs on
many phones and other personal devices like tablets.

In Java objects can only be created in one location, on the heap. Sticking to one and only
one memory model for objects simplifies many aspects of Java. Objects are never copied by
the language. So, copy constructors are unnecessary in Java. When an object is passed to a
function, a reference to an object is passed without making a copy of the object. When one
object wants to contain another object, it keeps a reference to that object. Java objects are
never stored inside other objects. Simplifying the memory model for objects means that in
Java programs we don’t have to worry about copying objects. Objects can still be copied in
Java, but making copies of objects is the responsibility of the programmer. The Java
language does not make copies. Programmers make copies by calling a special method
called clone. Java also includes garbage collection. This means that the Java Virtual
Machine takes care of deciding when the space that an object resides in can be reclaimed. It
can be reclaimed when no other objects or code have a reference to it any more. This means
that programmers don’t have to write destructors. The JVM manages this for them.

Java has a simpler memory model. Garbage collection removes the fear of memory leaks in
Java programs. The Java Virtual Machine also provides other advantages to writing Java
programs.

Python was designed and implemented by Guidovan Rossum. He started Python as a hobby
project during the winter months of 1989. A more complete history of this language is
available on the web at http://python-history.blogspot.com. Python is another object-
oriented language like C++ and Java. Unlike C++, Python is an interpreted language. Mr.
vanRossum designed Python’s interpreter as a virtual machine, like the Java Virtual
Machine (i.e. JVM). But Python’s virtual machine is not accessible separately, unlike the
JVM. The Python virtual machine is an internal implementation detail of the Python
interpreter. Virtual machines have been around for some time including an operating system
for IBM mainframe computers, called VM. Using a virtual machine when implementing a
programming language can make the language and its programs more portable across
platforms. Python runs on many different platforms like Apple’s Mac OS X, Linux, and

25
Microsoft Windows. Virtual machines can also provide services that make language
implementation easier (Kent D. Lee, Foundations of Programming Languages, 2nd Edition).

Figure 3.1: Evolution of Computer Programming Languages

26
3.7 An Introduction To The .Net Framework

The .NET framework was designed to make life simpler for programmers by providing a
common platform that can be used when writing programs in several different programming
languages (C# and Visual Basic among others). The .NET platform provides common
features that can be used by programmers of all .NET languages. These include :-

a) a Common Language Runtime (CLR) engine that allows all .NET programs to run
and use common features based on a Common Language Specification (CLS). The
CLR also shields the programmer from having to deal with issues that are specific
to individual operating systems.

b) a comprehensive class library providing a wealth of in built functionality (GUI,


File I/I, Database, Threading, Serialization, Security, Web applications,
Networking etc)

c) a Common Intermediate Language (CIL). All .NET source code is compiled into a
common intermediate language this provides the ability to integrate code written in
any .NET language making use of common exception handling facilities.

C# programs are thus partly compiled into a common intermediate language. This is then
linked with a CLR engine to give a .exe file. Taken all together the .NET framework does
not mean that all of the .NET languages are identical but they do have access to an identical
library of methods that can be used by all .NET Languages. Thus learning to program one
.NET language makes it easier to learn and program another .NET language. .NET programs
can only run where a CLR engine has been created for the underlying operating system.
Windows Vista and Windows 7 comes with a CLR engine and can therefore run .NET
programs but older versions of windows may need a CLR engine installed before .NET
programs can be run.

To enable .NET programs to be platform independent Microsoft published an open source


specification for a CLR engine (called a Virtual Execution System) this included the
definition of the C# language and a Common Language Infrastructure (CLI). By using these
definitions CLR engines have been created for other operating systems (e.g. Mac OS and
Linux) and by using these .NET programs can run on different platforms… not just
Microsoft Windows. However before programs can be run on these different platforms they
do need to be recompiled for each platform thus .NET programs, including C# programs,
are not as portable as Java programs.

While CLR engines are perhaps not as widely available as JREs they do exist for other
platforms. One example of an open source CLR is Mono (www.mono-project.com). Mono
is an open source, cross-platform, implementation of C# and the CLR that is compatible
with Microsoft.NET. One part of the Mono project is MonoTouch. MonoTouch allows you
to create C# and .NET apps for iPhone and iPod Touch, while taking advantage of iPhone
APIs. As well as compiling our C# programs it is possible to create a software installation
routine that will download via the web a .NET runtime environment and automatically
install this along with our software (assuming a .NET runtime environment is not already
installed).

Figure 3.2 depicts the Dot Net Framework

27
Figure 3.2: The .NET Framework

Summary
The different computer programming paradigms have been explained in this Session. The
structured, procedural and object orientation paradigms were explained. Now answer the
following questions.

Self-Assessment Questions
1. Discuss the nature and characteristics of Structured programming
2. Explain some of the differences between POP and OOP programming paradigms.
3. With reference to OOP paradigms, categorize the different OOP languages
according to degree of object orientation.
4. What are the peculiarities of the Dot Net (.Net) Framework

28
Study Session 4: Applications of Programming
Languages

Expected Duration: 1 week or 2 contact hours

Introduction
Even though we have many high level programming languages existing in the world today,
each of the languages has specific area of applications such as scientific, data processing,
AI, text processing and system programming. Some of them have universal applications,
but majority of them are application domain specific. In this Session, the major application
areas of Programming Languages are discussed.

Learning Outcomes
When you have studied this session, you should be able to explain how programming
languages are used in:
4.1 Scientific Applications
4.2 Data Processing Applications
4.3 Text Processing Applications
4.4 Artificial Intelligence (AI)
4.5 Systems Programming Applications

4.1 Scientific Applications

These are characterized as those which predominantly manipulate numbers and arrays of
numbers using mathematical and statistical principles as a basis for the algorithms. These
algorithms encompass such problems as statistical significance tests, linear programming,
regression analysis and numerical approximations for the solutions of differential and
integral equations. Amount of data in such problem could be small or large such as in
satellite or radar devices. Programmers must be well-used in the mathematical principles
underlying the Algorithm in order to properly diagnose problems. Finally, scientific
problems require significantly more of a computer’s central processor than the input-output
devices i.e. most of the computing time will be consumed with arithmetic calculations as
opposed to input-output operations. This is often known as “compute bound” process.

4.2 Data Processing Applications

These are characterized as those programming problems whose predominant interest is the
creation, maintenance, extraction and summarization of data in records and files. Normally,
data processing is found at the heart of an organization’s management support and includes
the payroll, accounting, billing, inventory, production and sales data processing functions.
Usually, volume of data found in these files is generally large, several thousand records per
file. By contrast, the amount of arithmetic calculations or other manipulation of data in an
individual record is relatively low. Mostly, data processing is “input-output bound”, passing
through the record of a file to locate and/or update some of the information on a regular
(daily, weekly, monthly) basis. By their nature, most classical data processing applications
are “batch” rather than “interactive” i.e. they can be scheduled on regular predictable basis
and their computer requirements are generally known in advance. An exception to this
generalization is that organizations now prefer interactive computing for their data

29
processing functions such as airplane flight reservation. Integrity, security, accuracy, and
reliability of data are characteristics that must be embedded in programming languages
meant for data processing.

4.3 Text Processing Applications

These are programming languages whose principal activity involves the manipulation of
natural language text, rather than numbers, as their data. The evolution of the modern Word
processing technology relies principally on text processing algorithms to perform the
various formatting and other functions that the typist uses during manuscript preparation.
Usually, the text in such an application is in English, although, recent advances in word
processing show multilingual capabilities in the form of alternative keyboards and
alphabets; SNOBOL and C programming languages have strong text processing
capabilities.

4.4 Artificial Intelligence (AI)

These are languages characterized as those programs which are designed solely to emulate
(copy) intelligent behaviour; including game playing algorithms (e.g chess), natural
language understanding programs, computer vision, robotics and expert systems where the
computer is programmed to play the role of an expert, such as medical diagnostician. AI has
confined its work to research labs where various pilot experts modeled different kinds of
intelligent behaviour. Nowadays many of these experts have been brought into practical
domains and their effects are shown in such diverse areas as automobile production lines
and the monitoring of complex instruments. LISP was used in those days but prolog is a
newer language designed on the principle of “logic programming”.

4.5 Systems Programming Applications

These involve developing those programs that interface the computer hardware with the
programmer and the operator. Programs like compilers, assemblers, interpreters, input-
output routine program management facilities and schedulers for utilizing and serving the
various resources that comprise the computer system.

4.5.1 Major characteristics of system programming languages

1. The requirement to deal effectively with unpredictable events or exceptions such as


input-output error.
2. The need to coordinate the activities of various asynchronously executing programs,
or simultaneous activity of several independent programs (or online users), which,
for the most part, have no need for interaction with each other in the frequent event
that they do interact (or conflict in their use of the same file simultaneously), the
system must respond gracefully and manage the interaction, or resolve the conflict.
Traditionally, most system programming has been done with Assembly Languages;
but along the line C, ADA and Modula-2 have been used.

Many programming problems do not fall into one or another of these five application areas.
For example, the need to effectively apply database techniques originated in the data
processing area, but now this need is shared by many scientific and AI application that store
large volumes of data in an effective way. Boundaries are also fuzzy between AI and text

30
processing, as illustrated by such applications as natural language translation. In order for
natural language translation to be effective, the program must, at least marginally be able to
understand the text to be translated. Thus, the need for AI in addition to text processing for
this problem is apparent.

SUMMARY
This Session has discussed that the different programming languages were developed for
different application areas as depicted below

Scientific→ FORTRAN, ALGOL 60, PASCAL, BASIC


Data processing→ COBOL
AI→LISP, PROLOG
Text processing→ SNOBOL, ICON
Systems programming→ C, MODULA.

Self Assessment Questions (SAQs)


1. (a) Identify suitable programming languages for developing the following applications
with reasons:
(i) String/Text processing
(ii) Chess playing game
(iii) Inventory control system
(iv) Compiler for Pascal
(v) Linear programming solution for mathematicians.
(b) For each of the identified programming languages in (a) above, state its language
application category and one major characteristic of the category.

2. An application requires the use of an array that will accommodate data of different types.
Identify a suitable programming language for this application and write an example code
in that language that implements this functionality.

3. An application requires the use of dynamic 2-dimensional array in which the rows’ and
columns’ sizes are known only at run –time. Identify a suitable programming language
for this application. Write a declaration for this array using the identified language’s
syntax.

31
Study Session 5: Evaluation of Programming
Languages

Expected Duration: 1 week or 2 contact hours

Introduction
Quality of the programming languages must be ascertained before they are adopted for use
by programmers. Therefore, in this Session, the criteria for evaluating and comparing
programming languages are discussed.

Learning Outcomes
When you have studied this session, you should be able to explain the criteria being used to
assess the quality of programming languages such as:
5.1 Expressivity:
5.2 Well-definedness
5.3 Data Types and Structures
5.11 Modularity
5.12 Input-output facilities
5.13 Portability
5.14 Efficiency
5.15 Pedagogy
5.16 Generality:
5.17 Other Quality Design Criteria

5.1 Expressivity:

The ability of a language to clearly reflect the meaning intended by the algorithm designer
(the programmer) is its expressivity. An expressive language permits an utterance to be
compactly stated and encouraged the value of statement forms associated with structured
programming. Finally, an expressive language is one whose symbols are uniformly used;
the meaning of a symbol should not vary unreasonably from one instance in a program to
another.

Consider the following 4 different statement from four different languages.


C=A+B
C := A + B
(SETQ C (+AB))
ADD A, B GIVING C

In the first two, the operators (assignment = and +) are infixed as they are in ordinary
algebra, while in the third, the operators are prefixed and the statement is fully
parenthesized. The fourth bears a resemblance to English in its style and is less compact
than the others. In language two, = is used for comparison operator (if A = B then…) and
:= distinguishes assignment from comparison.

Thus, we see that even the relatively simple problem of choosing symbols to denote
operations has a direct influence on a language’s expressivity.

32
5.2 Well-definedness

By this term, we mean that the language syntax and semantics are free from ambiguity, are
internally consistent and complete. Thus, a well-developed programming language should
have a complete specification of all the language’s expressive forms and their meanings.
The program should be able to predict exactly the behavior of each expression before it is
actually executed. This well-defined language encourages portability. For example, early
version of FORTRAN was not well-developed. We have statement like;
Do 10 I = 10
which is to be parsed as an assignment statement; and variables are not necessarily declared.
More recent versions of FORTRAN have eliminated most of these problems due to the
evolution of formed language description methods and language standardization
procedures.

5.3 Data Types and Structures

This is the ability of a language to support a variety of data values (integers, reals, strings,
pointers), and non-elementary collections of these like arrays, and records, but do not
exclude such dynamic data structures as linked lists, queues, stacks and trees.

5.4 Modularity

This has two aspects; the language’s support for sub programming and the language’s
extensibility in the sense of allowing programmer-defined operators and data types.
Subprograms connotes independent procedures and functions that communicate via
parameters or global variables with the invoking programs

5.5 Input-output facilities

Language’s support for sequential, indexed and random access files, as well as its support
for database and information retrieval functions. Files generally reside on secondary (direct
access or magnetic tape) storage, as opposed to data structures, which generally reside in
primary memory.

5.6 Portability

A portable language is one which is implemented on a variety of computers. Its design is


relatively machine independent. Languages that are standardized by American National
Institute (ANS languages) and well-defined tend to be more portable than others. Thus, ANS
Fortran or ANS COBOL was supported by almost all mainframes because they are
standardized. On the other hand, BASIC has different dialect. Some support one collection
of graphics functions, some support not at all. Thus, when porting a BASIC program from
one machine to another, programmers must be both aware of the different dialect and willing
to portions of the program accordingly.

5.7 Efficiency

An efficient programming language is one which permits fast compilation and execution on
the machines where it is implemented. Usually compiled programs are more efficient than
interpreted ones.

33
5.8 Pedagogy

By pedagogy, we mean easier to teach and to learn; they have better textbooks, they are
implemented in a better programming environment: widely known, and used by the best
programmers in an application area. BASIC and Pascal were designed especially as
pedagogical tools.

5.9 Generality:

This means the language is useful in a wide-range of programming applications e.g. APL
has been used in mathematical application involving matrix algebra and in business
applications as well. PL/1 is most general in those days intentionally designed as a “general
purpose length”. Most other languages are designed for a narrower purpose and audience.
Java is a platform independent language that can be adopted for various categories of
applications.

Tutorial Questions
1. What are the application area areas of C#, Java, PHP and VB.
2. Assess the language in term of the 9 evaluations criteria studied.

5.10 Other Quality Design Criteria / Programming Languages Qualities

By quality we mean what makes an idea programming language. The following design
criteria have evolved over the years.

1. Simplicity and clarity: How easy is the language to learn and teach? Pascal was
designed for teaching features that fascinated the teaching and learning of structured
programming. Some languages were designed to minimize the total number of
keystrokes when coding. Examples are C, C# and APL. This embraces economy of
expression but sometimes at the peril of persons reading the programs.

2. Binding: A language element is bounded to a property at the time that property is


defined for it. For example, a variable is bound to its type at the time it is declared
int x; // binding variable x to type int.

Binding can take place at any of the following times


 Language definition time: basic data types are bound to reserve words that
represent them at the language is defined. E.g. integers are bound to int and real
numbers to float in C, C# and Java.

 Language implementation time: values are bound to machine representations


when the translator for the language is written e.g. the real value1 1.5 is bound to
its IEEE 754 standard floating point representation, which is supported by modern
computer architectures.

 Program writing time: when programs are written in some languages, variable
names are bound to types, which remain associated with those names through the
run of the program e.g. int x;

34
 Program compile/load time: when programs are compiled/ loaded, the “static”
variables are assigned to fixed memory and the machine code itself is assigned to
a block of memory.

 Program runtime: variables are bounded to values when programs are running
as in the execution of the assignment x = 5. Generally, we have early binding
(binding takes place as early as possible when, an element is bound to a property)
and late binding- to delay binding until the last possible opportunity.

All these binding options must be taken into consideration in a language design.

3. Orthogonality: This term specifies if a symbol or reserved word always carry the same
meaning regardless of the context in which it is used or if the language contains a small
number of basic features that interact in a predictable fashion no matter how they
interact in a predictable fashion no matter how they are combined in a program.
Orthogonality occurs when a particular name is bound to a type when the program is
written and that binding cannot be changed throughout the run-time life of the program.
A counter example of orthogonality can occur with an inappropriate overloading of an
operator like ‘+’ in Java which is used for both arithmetic addition and string
concatenation operations.

4. Reliability of Programs: Does programs behave the same way every time they are
run with input data or when they are run on different platforms. To achieve this in a
language, it must be incorporated appropriate exception handling mechanism into
the language that resist aliasing and memory leaks, support strong typing, have well-
defined syntax and semantic and support programs verification and validation have
the reliability edge.

5. Applicability: Does the language provide appropriate support for applications in the
domain in which it is being used? E.g. a language designed especially to support
logical deductions in artificial intelligence research may be for client-server
applications in electronic commerce.

6. Abstraction: A good programming language supports data and procedural


abstraction in such a way that it is a preferred design tool in the programming
process. Abstraction entails code reusability. For example, Java’s class libraries
contain implementations of basic data structures (e.g. vectors and stacks) that, in
earlier languages, had to be explicitly designed by programmers themselves. Sorting
algorithm routines and linked list data structure have been implemented in some
languages.

7. Efficient implementation: A language feature and construct must permit its


practical and efficient implementation in contemporary platforms. E.g. ALGOL 68
was an elegant language design, but its specification was so complex that it was
nearly impossible to efficiently implement. ADA’s earlier versions were criticized
for their inefficient run-time characteristics since ADA was designed in part to
support real-time programming. Programs embedded in systems like airplanes had
to respond immediately to a sudden change in input values like wind speed, and
ADA’s program stood at the intersection of the sensors that provided the readings

35
and the mechanisms that were to respond to them. Early versions of ADA’s
implementation fell short of these ambitious performance goals.

Summary
In this Session, the various criteria that can be used to assess quality of programming
languages are discussed. These criteria are many and sometimes are interwoven in
interpretation.

Self- Assessment Questions


Using the concepts of Orthogonality and Portability, explain the programming-
friendliness of the following languages:
(i) Java
(ii) C#
(iii) Python
(iv) C
(v) JavaScript

36
Study Session 6: Language Design: Syntax
Expected Duration: 1 week or 2 contact hours

Introduction
The syntax of a language is a set of rules that defines what sequences of symbols are
considered to be valid expressions (programs) in the language. That is, the syntax is a
definition of what constitutes a grammatically valid program in that language. This will be
our point of discussion in this Session.

Learning Outcomes
When you have studied this session, you should be able to explain the following language’s
syntax design elements:
6.1 The Importance of Language’s Syntax?
6.2 Backus-Naur Form (BNF)
6.3 The Issue of Delimiters
6.4 Some other lexical/ syntax representation as found in PASCAL
6.5 Lexical Analysis and the Compiling Process
6.6 Syntactic Analysis
6.7 Limitations of BNF Syntax
6.8 Syntactic Ambiguity
6.9 Variations on BNF

6.1 What is the Importance of Language’s Syntax?

Syntax refers to the words and symbols of a language and how to write the symbols down
in some meaningful order. It determines the well-formed or grammatically correct programs
of the language. Semantics describes how or whether such programs will execute. Syntax
has nothing to do with the meaning or run-time behaviour of a program, yet syntax is a
prerequisite to meaningful expressions. Formal notations / methods are used to express
syntax in languages, usually in form of meta-languages. A meta language is used to define
other languages.

It is not always clear which questions pertain to syntax and which pertain to semantics.
Some questions may concern semantic issues that can be determined statically, meaning
before the program is run. Other semantic issues may be dynamic issues, meaning they can
only be determined at run-time. The difference between static semantic issues and syntactic
issues is sometimes a difficult distinction to make. The code: a = b + c; is correct syntax in
many languages. But is it a correct C++ statement?

1. Do b and c have values?


2. Have b and c been declared as a type that allows the + operation? Or, do the values
of b and c support the + operation?
3. Is a assignment compatible with the result of the expression b + c?
4. Does the assignment statement have the proper form?

There are lots of questions that need to be answered about this assignment statement. Some
questions could be answered sooner than others. When a C++ program is compiled it is
translated from C++ to machine language.

37
Questions 2 and 3 are issues that can be answered when the C++ program is compiled.
However, the answer to the first question might not be known until the C++ program
executes in some cases.

The answers to questions 2 and 3 can be answered at compile-time and are called static
semantic issues.
The answer to question 1 is a dynamic issue and is probably not determinable until run-time.
In some circumstances, the answer to question 1 might also be a static semantic issue.
Question 4 is definitely a syntactic issue (Kent D. Lee, Foundations of Programming
Languages, 2nd Edition). A metalanguage is a higher-level language used to specify, discuss,
describe, or analyze another language. English is used as a metalanguage for describing
programming languages, but because of the ambiguities in English, more formal
metalanguages have been developed.

6.2 Backus-Naur Form (BNF)

BNF is a metalanguage tool for defining the syntax of various programming languages. A
BNF grammar is a set of rewriting rules P, a set of terminal symbols ∑, a set of non-terminal
symbols N and a start symbol, S  N. A rewriting rule is of the form
A  w where

A  N and w  (N  ∑). That is, w is a string of non-terminal and terminal symbols. When
used for defining programming language’s syntax the words in N identity grammatical
categories (like identifiers, integers, expressions, loop and program) and the start symbol S
identifies the principal grammatical category being defined by the grammar. The symbols
in ∑ form the basic alphabet (e.g. ASCII character set) from which programs are
constructed.

For instance, the BNF grammar for binary digit is:


binaryDigit  0 | 1

This means binary digit is 0 or 1.


In BNF we use the following meta linguistic symbols:

a.  or ::= means “is defined as”


b. { } means “any sequence of 0 or more of the items enclosed”
c. [ ] means “either 0 or 1 concurrence of the items enclosed”
d. | means “or” in the exclusive sense.

Other examples
1. An identifier is defined as any letter, followed optionally by any sequence of letters
and/or digits
Identifier  letter {letter | digit}
Letter  a | b | c … | z | A | B | C …| Z
Digit  0 | 1 | 2 | 3 | 4 | 9
2. Integer  Digit | Integer Digit. This means an integer could be a Digit alone or an
integer followed immediately by a digit.
3. Natural  Digit {Digit}
Integer  [+ | −] Natural
Number  Integer | [+ | −] . Natural | Integer. Natural

38
Here, the class Natural includes the unsigned integers like 7, 28, 258. The class integer
allows signed natural numbers like −7, +32. The class number includes integers and adds
decimal fractions like ( .7 and –..32) and decimal numbers ( like −7.32 and 32.7). Thus,
the definition is both complete and concise and allows for efficient recognition of such
tokens by a lexical analyzer.

The lexicon of a programming language is the set of all grammatical categories that defines
strings of nonblank characters, called tokens, from which programs are written. The lexicons
or tokens in a programming language are
(a) Identifier (variable names, function names, etc)
(b) Literals (integer and decimal numbers)
(c) Operator (+, −, *, |, etc)
(d) Separator (;, ., {, }, etc)
(e) Keywords (int, main, if, for, swing, etc)

Each of these categories is defined by a simple BNF grammar. Together, this set of
grammatical categories defines the lexical syntax of the language, which is the simplest
level from the viewpoint of the compiler. These categories allow the compiler to look at a
program as a stream of tokens; each one separated from the next token by either a white
space (blanks) or a comment. Consider the annotated diagram program below

Comment // Compute the result


Keyword class myClass {

public static void main (String [ ] args ) {

int n; Identifiers
Separators
n = 8;

Literal
Operator

First programming Practical

Implement a program called lexicon that will read all the tokens in a programming language
(Java) code file and place all the tokens into their lexicon categories. The program code file
would be a source file to your own program.

6.3 The Issue of Delimiters

Another serious issue that confronts language designers is the treatment of delimiters such
as Begin, End, program, class. This is important because languages usually allow variable
names, procedure names and statement labels as well to be identified as identifiers and it is
possible for programmers to choose identifiers like “begin” and “end” as variable names.
This could cause confusion for the compiler during compilation.

One solution is that we prescribe in the language definition that all such tokens are “reserved
words”. That is, they are excluded by fiat from the class of identifiers that a program can
define for its own use. The advantage of the reserved word is that it simplifies lexical
analysis by the compiler. The disadvantage is that a long reserved word list encumbers the

39
programmer, since it usually takes out of circulation words which would naturally be chosen
as identifiers in a program. For example, SUM is a reserved word in COBOL.

The second solution is to designate these tokens as “keywords” by requiring that they be
explicitly flagged in the program text by special delimiters or typing conventions. ALGOL
and BASIC adopt this method. For instance, in some implementations, an apostrophe (‘) is
typed against the keywords such as

‘Program P;
‘Var X, Y: ‘INTEGER;
‘BEGIN
READ(X);
WRITE(X + 2.5);
‘END

By the keyword approach, tokens like PROGRAM, BEGIN, VAR, END, etc are now free
for use within the program as programmer’s variable names. While this method keeps the
compiler’s lexical analysis process simple, it makes the program preparation more tedious
and difficult to a reader.

The third approach is to allow these tokens to be used also as identifiers in the program and
place the burden of distinguishing between the two uses of an identifier on the context in
which it appears in the program. PL/1 is a good example of programming language on this.
For instance, we could have statements like

IF IF = 1 THEN IF = 0; ……….(i)
DO DO = IF To THEN; ………..(ii)

In the first statement, the variable IF is tested and conditionally reassigned the value 0 using
an IF statement. In the second statement, the loop variable DO is initialized to the value of
the variable IF and the loop is repeated until it value reaches that of the variable THEN,
using a DO statement.

Programmers using this method deserve whatever consequence they get. Moreover, a
significant burden is placed on the compiler to support such ‘freedom of expression’.

6.4 Some other lexical/ syntax representation as found in PASCAL

statement  unlabelled-statement | label unlabelled statement.


Unlabeled statement simple statement | structured-statement
Simple statement  assignment statement | procedure statement | GOTO statement
Structured statement compound statement | conditional statement | repetitive statement |
with statement
Compound statement  BEGIN statement {; statement} END
Conditional statement  if statement | case statement
If-statement  if expression then statement | if expression then statement else statement
Assignment statement  identifier := expression
Expression  simple expression | simple expression relop simple expression
Relop  = | < > | < | <= | >= | > | in Relop means Relational Operators
Simple expression  [+ | - ] term | simple expression relop term

40
AddOp  + | - | or
Term  factor | term mulop factor
Mulop  * | / | div | mod | and
Factor  identifier | number | (expr) | function-designator | set | not factor

Note: Mulop means Multiplication Operator while Relop means Relational Operator

Exercise: Find out the BNF rules in C, C# and Java.

6.5 Lexical Analysis and the Compiling Process

All programs must be parsed and analyzed for semantic correctness before they are
translated to machine code or interpreted. A lexical analysis process separates the program’s
individual characters into a stream of tokens that is parsed on, one token at a time, to a higher
level of analysis.

The major step in compilation process is depicted below.

Program  Lexical Analysis  Token Stream  Syntactic Analysis  Parse  Semantic


Analysis  Parse  Optimization  Code Generation  Machine Code

Lexical analysis basically translates the program text into a stream of tokens, passing the
token one-by-one to the syntactic analysis stage as they are needed. Syntactic analysis
develops an abstract representation or ‘parse’ for the program, detecting syntactic errors
along the way. In the absence of no errors, semantic analysis and optimization stage analyze
the parse for semantic consistency; e.g. checking consistent use of operators and data types,
and transform the parse so that it can efficiently utilize the architecture where the program
will run. Finally, the code generation stage uses the resultant abstract representation as a
basis for generating executable machine code.

The lexical analysis is governed strictly by the BNF rules that define the language’s lexical
syntax. The simple nature of these rules allows lexical analysis to be defined in a straight
forward and efficient manner. That is, each new character appearing in the program provides
a clue to a specific token class to which the next token belongs. For example, the appearance
of a slash (/) may indicate the beginning of a comment or a division operator, while the
appearance of a letter may indicate the beginning of a identifier or a keyword. The end of
each token is signaled clearly by the presence of a whitespace, the beginning of a comment
or the beginning of a new token.

6.6 Syntactic Analysis

The syntax analysis uses the output of lexical analysis as a basic for defining the structure
of all the different parts of a program such as arithmetic expression (e.g. x + 2* y),
assignments (z = 2 * x + y), loops (e.g. for loop), function / method definitions, declaration
of variables (e.g. int n) and even complete programs themselves. The syntax uses BNF as
the primary tool to provide a precise definition and strict guidance for the syntax phase to
detect syntax errors and develops a parse from a stream of tokens.

41
Consider the BNF syntax for the syntactic categories assignment and Expression below.
Assignment  identifier = expression
Expression term | expression + term | expr - term
Term factor | term * factor | term | factor
Factor identifier | literal (expression)
Literal  Boolean | integer
Identifier  letter | identifier letter | identifier digit
Derivations and parse trees for integer-valued expression can be easily constructed from this
grammar, using the same techniques used for parsing tokens at the lexical level.

To parse the expression x + 2 * y:

Expression

Expression + Term

Term * Factor
Term

Factor Factor identifiers

Identifiers literal

x z y

In the tree above, expression forms the root since that is the grammatical class of interest,
and the string being parsed as its leaves, reading from to right

Syntactic grammars reveal important information to the compilation process about the
structure of the computation described by the program as well as the particular sequence
of tokens that participate in the computation. Traversing the nodes of a particular parse
tree in-order, i.e., from the bottom up and from left to right at each level, would reveal if a
particular expression is syntactically correct or not.

6.7 Limitations of BNF Syntax

1. The syntax for expression does not guarantee that every identifier that appears in
that expression has been declared.
2. The syntax does not guarantee that the identifiers used in an expression have been
assigned values by the time the expression is executed at run time.

A complete parse tree for a program has as its root the syntactic category “program” and
as its leaves, the stream of individual tokens that are the outputs of lexical analysis. A
parse tree for the following simple program is shown next.

42
void main( ) {
int x;
x = 1;
}
Program

void main ( ) { }

Declarations Statements

Declaration Statement

Type Identifiers ; Assignment

int Identifier Identifier = Expression ;

x x Literal

1
The shape of the resultant parse tree suggests that the Declarations be processed first;
followed by the statements. The shape enables type checking to take place, since by the
time the Statements are reached, the names and types of all the declared variables are
known.

6.8 Syntactic Ambiguity

A grammar is ambiguous if we can have two different parse trees for the same expression.

AmbExp  integer | AmbExp – AmbExp

The grammar allows an expression to have two different interpretations at run time. For
example, 2 – 3 – 4 could be interpreted as 2 – (3 – 4) = 3 or (2 – 3) – 4 = – 5; Syntax
trees shown next.

AmbExp AmbExp

AmbExp – AmbExp AmbExp - AmbExp

Integer AmbExp – AmbExp AmbExp – AmbE Integer

2 Integer Integer Integer Integer

3 4 2 3 4
2 – (3 – 4) = 3 (2 – 3 – 4) = – 5

The two syntax trees show that the expression 2 – 3 – 4 is ambiguous. Braces would make
the expression un-ambiguous. These types of expressions should be avoided in
programming language design. A classical example of ambiguity in language design is the

43
dangling else problem. It occurs when two adjacent IF statements are followed by an else
statement.
For example:
IF (x < 0)
IF (y < 0) y = y – 1;
ELSE y = 0;

The issue here is that if the parse attaches the ELSE clause to the second IF statement, y will
become 0 whenever x < 0 and y >= 0. However, if the parse attaches the ELSE clause to
the first IF statement, y will become 0 whenever x >= 0.

IF statement  IF (Expression) Statement |


IF (Expression) Statement ELSE Statement
Statement  Assignment | IF Statement

IF Statement IF Statement

IF ( Expr ) Statement IF ( Expr ) stmt ELSE Stmt

x<0 IF Statement x<0 IF Stmt y= 0;

IF ( Expr ) Stmt ELSE Stmt IF ( Expr ) Stmt

y<0 y=y–1 y=0 y<0 y=y–1

In solving the dangling else problem, SR and ADA solves the problem by providing a
special keyword like fi to explicitly close every IF statement. Others like C and C++ define
how the attachment should be made. For example, by attaching the ELSE clause to the first
IF statement in the expression.

In PASCAL and PL/1, each ELSE with the nearest (innermost) IF which precedes it. In
ALGOL, no two IF statements must follow each other immediately. In ADA, FORTRAN
and VISUAL BASIC, all IF statements are closed by a mandatory END IF statement
whether they have an ELSE part or not.

Interestingly, Java solves the problem by expanding the BNF grammar for IF statements in
a rather bizarre (strange) way. That is, it separates the definition into two different syntactic
categories:

IfThenStmt  IF ( Exp ) Stmt


IfThenElseStmt  IF ( Expr) StmtNoShortIf ELSE Stmt

This means all IF statements must have an explicit ELSE clause.

6.9 Variations on BNF

Several minor variations have been used, but the basic expressive power of BNF has not
been affected. These variations exist mainly to improve the clarity of syntax description and
the efficiency of syntax analysis. Extended BNF (EBNF) was introduced to simplify the

44
specification of recursion in grammar rules and to introduce the idea of an optional part in
a rule’s right hand side. Consider the following:

Expression  Term | Expression + Term | Expression – Term


Term  Factor | Term * Factor | Term / Factor

This means that the expression is a series of one or more Terms separately individually by
+ or – signs. EBNF would eliminate the left recursion in these rules and allow them to be
equivalently written as follows:

Expression  Term { [ + | – ] Term }*


Term  Factor { [ ‘*’ | / ] Factor } *

The * operator denotes “zero or more occurrences of the symbols that are enclosed in braces
{ } immediately before it. The brackets, [ ], enclose a series of alternatives from which one
must be chosen. Finally, the aesterik (‘*’) indicating multiplication is enclosed in quotes to
distinguish it from the meta-linguistic use of the aesterisk as an EBNF operator. Consider
the derivation tree for the expression x + 2 * y, that uses EBNF below.

Expression

Term + Term

Factor Factor * Factor

Identifier Literal Identifier

x 2 y

1. Definitions of language syntax in EBNF is slightly clearer and briefer than BNF
definitions.
2. Moreover, EBNF does not force the use of recursive definitions on the reader in
every instance. For example, the star (*) notation in EBNF, meaning zero or more
occurrences, suggests a loop in the implementation of the structure, rather than a
recursive method.

One variation on BNF is the syntax diagrams, made popular by the syntactic definition of
the PASCAL language. An example is as shown below.

Expression Term

Read the diagram from left to right. All the paths that lead to the right hand arrowhead are legal
expressions.

45
Summary
This Session has introduced you to how programming elements are validated through the syntax
analysis in programming languages. The definition of syntax and its major difference from
semantic analysis were discussed. A powerful metalanguage tool, BNF was also discussed
extensively. Now answer the following questions.

Self-Assessment Questions

1. Consider the following code snippet in a programming language.

if (a > b)
if (a < c)
a++;
else
k = a – b + c;
(a) What is the syntactic ambiguity associated with the above code snippet?
(b) What happens on the values of k if the else part of the code is attached
to the innermost and the outermost if-statements?
(c) Illustrate your solutions with syntax trees.
(d) Explain how C, Java and FORTRAN solve this problem.

2. (a) Define BNF grammar using some formal notations.


(b) Assuming you are interested in designing a programming language,
identify all the different lexical categories you will need in the design
(c) Design a comprehensive BNF grammar for the lexical categories identified
in (b) above.
(d) State any two likely limitations of the BNF grammar designed in (c) above.
[

46
Study Session 7: Programming Type Systems
Expected Duration: 1 week or 2 contact hours

Introduction
A type is a concise, formal description of the behaviour of a program element. For instance,
int describes an expression that evaluates to an integer; int → bool describes a function that
maps an integer argument to a boolean result; (int → bool) → (list int → list int) describes
a function that maps an integer predicate to an integer list transformer. In this Session, we
shall study elementary concepts in programming type systems.

Learning Outcomes
When you have studied this session, you should be able to explain the following concepts
in languages’ type systems:
7.1 Meaning of a Type System?
7.2 Elementary Types, Values and Expressions
7.3 Elementary Types in Programming Languages
7.4 Static vs. Dynamic, Weak vs Strong Typing
7.4.1 Weak Static Languages: C, C++ and Objective-C
7.4.2 Strong Static Languages: Java
7.4.3 Strong Dynamic Languages: JavaScript, Python, Ruby and Many More
7.5 Advantages of Typed Programs
7.6 Disadvantages of Typed Programs

7.1 What is a Type System?


A type is a well-defined set of values and operations on those values. For example, values
on int can be …, -2, -3, 0 …, 8, 9 .. and operations allowed on int values are members of
the set {+, -, *, /, %, \ …}. Also {true, false} are values of Boolean and operations on these
values could be { &&, | |, !}.

A type system is a well-defined system of associating types with variables and other objects
defined in a program. In another view, a type system is a logical system comprising a set of
rules that assigns a property called a type to the various constructs of a computer program,
such as variables, expressions, functions or modules. These types formalize and enforce the
otherwise implicit categories the programmer uses for algebraic data types, data structures,
or other components (e.g. "string", "array of float", "function returning boolean").
The main purpose of a type system is to reduce possibilities for bugs in computer programs
by defining interfaces between different parts of a computer program, and then checking
that the parts have been connected in a consistent way. This checking can happen statically
(at compile time), dynamically (at run time), or as a combination of both. Type systems have
other purposes as well, such as expressing business rules, enabling certain compiler
optimizations, allowing for multiple dispatch, providing a form of documentation, etc.

A type system associates a type with each computed value and, by examining the flow of
these values, attempts to ensure or prove that no type errors can occur. The given type
system in question determines what constitutes a type error, but in general the aim is to
prevent operations expecting a certain kind of value from being used with values for which
that operation does not make sense (logic errors). Type systems are often specified as part
of programming languages, and built into the interpreters and compilers for them; although
the type system of a language can be extended by optional tools that perform added checks

47
using the language's original type syntax and grammar (Wikipedia
https://en.wikipedia.org/wiki/Type_system).

7.2 Elementary Types, Values and Expressions

A type is a set of values and a set of operations on those values. For example, the type int
has values { …, -2, -1, 0, 1, 2, …} with operations { +, -, *, /, \ }.

An expression is either a value, a variable, a binary or a unary. The type of an expression is


defined on the basis of the types of its constituents. For example,
1. The type of an expression consisting of a value is just the type of that value. For
example, 2 is of type integer.
2. The type of an expression which is a variable is the type of that variable.
3. The type of a binary is either int or Boolean.
4. The type of a unary is Boolean.

Recall that a type map, tm of a program gives the set of variables and types as defined in
the program’s declarations.
Tm = { (v1, t1), (v2, t2), …, (vn, tn) }

Now, given the following declarations and expressions:

int x, y;
x + 2 * y;
x<2*y
x < 2 * y && x > 0

From the declarations,

tm = { (x, int), (y, int) }

The typeOf (x + 2 * y, tm) = int +  {Arithmetic operators}


typeOf (x < 2 * y, tm) = Boolean <  {Relational operators}
typeOf (x < 2 * y && x > 0, tm) = Boolean &&  {Boolean operators}

However, defining the type of an expression does not make it valid. An expression is valid
if it is either
(i) An int or Boolean value
(ii) A variable in the program’s type map tm, or
(iii) A binary or unary whose operands satisfy the following additional constraints:
a. A binary whose operator is either an arithmetic operator or relational
operator must have two valid operands of type int.
b. A binary whose operator is a Boolean must have two valid operands of type
Boolean.
c. Unary must have unary operator and a valid Boolean operand.

All other combinations of operand types and operators are invalid expressions in the original
Von Neumann machine.

48
Recursively defined,
V (Expression e, type map tm) = true, if e is a value
V = e  tm, if e is a variable.
V = V(e.term1, tm)  V(e.term2, tm)  typeOf (e.term1, tm)
= int  typeOf (e.term2, tm)
= Boolean if e is a binary  e.op  { Boolean operators}
= V(e.term, tm)  typeOf (e.term, tm) = Boolean  e.op = ! if e is a unary.

For example, V(x + 2 * y, tm) = V(x, tm)  V(2 * y, tm)  typeOf(x, tm)
= int  typeOf(2 * y, tm)
= int since +  {Arithmetic operators}

7.3 Elementary Types In Programming Languages

Data types in programming languages are of two classes: Elementary / Atomic and
structured types. Elementary types are stored in fixed memory space while structured types
require a variable memory space to store their values, e.g. arrays.

Elementary types are Bytes in Java, Integers in form of short, int, long in C / C++ and Java,
Integer in ADA and FORTRAN. Real number in form of float and double in C / C++ and
Java. ADA has float or decimal. Character in form of char in C / C++ and Java and
CHARACTER written in full in FORTRAN and ADA.; Boolean in C / C++, ADA and Java
and Pointer in C / C++.

Memory are allocated to these data types based on their requirements:


 Nibble – 4 contiguous bits of memory, a half byte
 Byte – 8 contiguous bits of memory
 Half Word – 16 contiguous bits of memory, 2 bytes
 Word – 32 contiguous bits of memory, 4 bytes
 Double Word – 64 contiguous bits of memory, 8 bytes
 Quad Word – 128 contiguous bits of memory, 16 bytes

Java short uses half word, int occupies a word and a long value occupies a double word.
Float requires 32 bits memory word and double occupies 64 bits word. Char uses 16 bits.
Usually, floating point values are stored using IEEE 754 Standard, where the sign s on the
value, exponent e and mantissa m are stored in fixed parts of the memory space.

Single precision Double precision

s| e | m s| e | m

Bit 0 1-----8 9 -------31 Bit 0 1---11 12------63

If the number is negative, then 1 is placed in position 0 and 0 otherwise.

Java uses UNICODE character set as different from ASCII, which other languages used.
The UNICODE set provides a rich assortment of characters that allow Java programs to
embody a more international vocabulary than other languages.

49
The Unicode standard includes codes for character sets that spans the world’s major written
languages. It also includes punctuation marks, diacritics, mathematical symbols and a wide
array of other technical symbols. It provides codes for modifying characters, such as the
tilde (~) and codes that are used to encode accented letters (ñ ). The current version of
Unicode defines codes for 49,194 characters from the world’s alphabets and other symbols
sets.

In C, strings are encoded as arrays of ASCII characters, one character per byte, terminated
by a null character. Thus, “hello” would be encoded in hexadecimal as 68 65 6C 6C 6F 00.
Therefore, the string “hello” requires 6 storage bytes, one for each character plus one for the
null character. In contrast, Java stores each character in a string in Unicode using 2 bytes
per character. Thus, the hexadecimal representation of ‘hello” is 00 68 00 65 00 6C 00 6C
00 6C.

7.4 Static vs. Dynamic, Weak vs Strong Typing

Languages like C and Java associates a single type with a variable throughout the life of the
variable in a program’s compilation time. These languages are called statistically typed
languages. Others like LISP and SCHEME, which allow changes to values and their types
as their programs run are called dynamically typed languages.

A statically languages allows its type rules to be fully defined on the basis of its abstract
syntax alone. This definition is often called static semantics and it provides a means of
adding context sensitive information to a parser that the BNF grammar cannot provide. A
type error is a run time error that occurs when an operation is attempted on a value for which
it is not well-defined (Allen Tucker and Robert Noonan, 2002).

A programming language is strongly-typed if its type systems allows all its type errors in
program to be detected, either at compile time or at run time, before the statement in which
they can occur is actually executed. Whether a language is statically or dynamically typed
does not prevent it from being strongly typed. For example, Java is strongly typed while C
is not. Strong typing generally promotes more reliable programs and is viewed as a virtue
in programming language design.

A program is type safe if it is known to be free of type errors. All the programs in a strongly
typed language are type safe. Moreover, a language is type safe if all its programs are.
Dynamically typed languages like LISP must necessarily be type safe since all their type
checking occurs at run time, variables’ types can change dynamically (Allen Tucker and
Robert Noonan, 2002).

C treats everything like a number. A character like a or 7 or % is the number of the ASCII
symbol representing it; “true” and “false” are just 1 and 0.

C defines variables with types such as int for integer and char for character, but that just
defines how much memory to use. To access the variable and print it out, one needs to
know the type.

int a = 1;
printf("The number is %in", a);

50
char z = 'z';
printf("The character is %cn", z);

When this program is run, it shows this:


The number is 1
The character is z

The printf function needs a hint from us to know how to format the variable. If a wrong hint
is given …
char z = 'z';
printf("The character is %in", z);

… then we get this:


The character is 122

In this case, C doesn’t know whether z is a character or an integer. This means C-language
has a weak type.

Weak typing is fast because there’s no overhead of remembering the different types,
but it leads to some nasty bugs. There’s no way to format the z if we don’t know its type
ahead of time. Imagine accessing a variable and getting the number 1229799107. The
number could be the result of a mathematical calculation (1,229,799,107), the cost of a
project (N1.2 billion) or a date (Saturday, 20 December 2023). When all we have is the
number, there’s no way to know that it’s really the code for the letters in a name: Usman.

So far, we’ve just covered weak typing. “Weak versus strong” and “static versus dynamic”
are often spoken of synonymously, but they each describe a different phase of the same
problem. They’re also politicized, with the words carrying an implied value judgment.
“Weak versus strong” makes one of them sound a lot better than the other, while “static vs.
dynamic” makes one sound stodgy (heavy) and the other exciting.

These two terms are used interchangeably, but they describe the difference between the way
a language defines types and how it figures them out when the program runs. For example:

Assembly languages don’t provide any way of


Weak with no typing specifying or checking types at all. Everything is just a
number.

C lets you define object types as structures, but it doesn’t


do much to enforce or remember them. C automatically
Weak static typing convert between many types. C++ and Objective-C go
further with the definitions but still don’t enforce the
resulting types.

Java forces you to define all types and checks them with
Strong static typing
a virtual machine.

51
Python, JavaScript and Ruby dynamically infer the
types of objects, instead of forcing you to define them,
and then enforce those types when the program runs in
Strong dynamic typing
the interpreter. All dynamically typed languages need a
strong typing system at runtime or else they won’t be
able to resolve the object types.

Dynamically inferred types don’t work in a weakly typed


Weak dynamic typing
language because there aren’t any types to infer.

No programming language fits any of these definitions 100%. Java is considered one of
the most static languages, but it implemented a comprehensive reflection API that lets us
change classes at runtime, thus resembling more dynamic languages. This feature allows the
Java Virtual Machine to support very dynamic languages such as Groovy.

Functional programming languages such as Lisp, Erlang and Haskell blur the lines even
more. Usually when people argue about the merits of strong versus weak programming
languages, they really mean the varying degrees of weak, strong, static and dynamic
philosophies in every language.

7.4.1 Weak Static Languages: C, C++ and Objective-C

These programming languages use a subset of C’s functionality and strict guidelines to
improve the loose nature of the language. C++ and Objective-C compile into the same bytes
as C, but they use the compiler to restrict the code we can write.

In C++ and Objective-C, our number (1229799107) has a meaning. We can define it as a
string of characters and make sure that no one uses it as a currency or a date. The compiler
enforces its proper use.

Static typing supports objects with sets of functionality that always work in a well-defined
way. Now we can create a Person object and make sure the getName function always
returns the string of someone’s name.
class Person {
public:
string getName() {
return "Usman";
}
};
Now we can call our object like this:
Person p;
printf("The name is %sn", p.getName().c_str());

52
Static typing goes a long way to avoid the bugs of weakly typed languages by adding more
constraints in the compiler, but it can’t check anything when the program is running
because a C++ or Objective-C program is just like C code when it runs. Both languages also
leave the option of mixing weakly typed C code with static typed C++ or Objective-C to
bypass all of the type checking. Java goes a step beyond that, adding type checking when
the code runs in a virtual machine.

7.4.2 Strong Static Languages: Java

C++ offers some stricter ways of using C; Java makes sure we use them. Java needs
everything to be defined so that you know at all times what type of object we have, which
functions that object has and whether we are calling them properly. Java also stopped
supporting C code and other ways of getting out of static typing.

The Person object looks almost the same in Java:


public class Person {
public String getName() {
return "Usman";
}
}

We can get the name by creating a new object and calling the getName function, like this:
public class Main {
public static void main (String args[]) {
Person person = new Person();
System.out.println("The name is " + person.getName());
}
}

This code creates a new Person object, assigns it to a variable named person, calls
the getName function and prints out the value.

If we try to assign the person variable to a different type, such as a character or integer, then
the Java compiler will show an error that these types are incompatible. If we call a separate
API that had changed since the code was compiled, then the Java runtime would still find
the type error.

Java doesn’t allow code outside of a class. It’s a major reason why people complain that
Java forces us to write too much boilerplate (standard text or program code used routinely
and added with a text editor or word processor).

The popularity of Java and its strong adherence to strong typing made a huge impact on the
programming landscape. Strong typing advocates lauded Java for fixing the cracks in C++.
But many programmers found Java overly prescriptive and rigid. They wanted a fast way to
write code without all of the extra definition of Java.

53
7.4.3 Strong Dynamic Languages: JavaScript, Python, Ruby and Many More

In JavaScript, we define a variable with the keyword var, instead of a type like int or char.
The type of this variable is not known and we don’t need to until we actually want to access
it. We can define an object in JavaScript with the getName function.
var person = {
getName: function() {
return 'Usman';
}
};

alert('The name is ' + person.getName());

Now we have an object named person, and it has a function named getName. If we
call person.getName( ), it will result in Usman. Even though we declared person as a var,
we can can reassign it to anything.
var person = {
getName: function() {
return 'Usman';
}
};
person = 5;
alert('The name is ' + person.getName());

This code creates a variable named person and assigns it to an object with
a getPerson function, but then it reassigns that variable to the number 5. When this code
runs, the result is TypeError: Object 5 has no method ‘getName’. JavaScript says that the
object 5 doesn’t have a function named getName. In Java, this error would come up during
compilation, but JavaScript makes us wait for runtime.

We can also change the type of the object based on the conditions of the program.
var person = {
getName: function() {
return 'Usman';
}
};

if (new Date().getMinutes() > 29) {


person = 5;
}

alert('The name is ' + person.getName());

54
Now this code will work at 9:15 but will fail at 9:30. Java would call this a type error, but
it’s fine in JavaScript.

The most popular form of dynamic typing is called “duck typing” because the code looks at
the object during runtime to determine the type — and if it walks like a duck and quacks
like a duck, then it must be a duck.

Duck typing enables one to redefine any object in the middle of the program. It can
start as a duck and turn into a swan or goose.
var person = {
getName: function() {
return 'Usman';
}
};

person['getBirthday'] = function() {
return 'July 18th';
};

alert('The name is ' + person.getName() + ' ' +


'and the birthday is ' + person.getBirthday());

At any point, we can change the nature of our Person object to add the
new getBirthday function or to remove existing functionality. Java won’t allow that because
we can’t check object types when they’re always changing. Dynamically redefining objects
gives us a lot of power; however, for good and bad.
C shows errors when the program runs. C++, Objective-C and Java use the compiler to catch
errors at compile time. JavaScript pushes those errors back to the runtime of the application.
That’s why supporters of strong typing hate JavaScript so much: it seems like a big step
backward. They’re always looking for JavaScript alternatives.

7.4.4 Which Is Better?

Dynamic code is generally shorter than static code because it needs less description of what
the code is going to do. Programs generally are shorter in Python than in C++ and shorter
in Ruby than in Objective-C.

So, which is better? Judge from the following survey from programmers according to Zack
Grossbart (2013)

55
The static programmer says: The dynamic programmer says:

“Static typing only catches some bugs,


“Static typing catches bugs with the
and you can’t trust the compiler to do
compiler and keeps you out of trouble.”
your testing.”

“Static languages are easier to read because


“Dynamic languages are easier to read
they’re more explicit about what the code
because you write less code.”
does.”

“Just because the code compiles doesn’t


“At least I know that the code compiles.”
mean it runs.”

“I trust the static typing to make sure my “The compiler doesn’t stop you from
team writes good code.” writing bad code.”

“Debugging an unknown object is “Debugging overly complex object


impossible.” hierarchies is unbearable.”

“Compiler bugs happen at midmorning in “There’s no replacement for testing, and


my office; runtime bugs happen at midnight unit tests find more issues than the
for my customers.” compiler ever could.”

Static typing made our Person object easier to understand. We defined a Person with a name
and agreed about which fields mattered ahead of time. Establishing everything clearly
makes our Person easier to debug but harder to change.

There’s no clear conclusion. Dynamically typed languages are popular now. The pendulum
will swing back and forth many times in the coming years. The only solution is flexibility.
Learn to work in each environment and you’ll work well with any team.

7.5 Advantages of Typed Programs

Types must be sound. That is, programs must behave as prescribed by their types. Hence,
types must be checked and ill-typed programs must be rejected. Types are useful for quite
different reasons:
(i) They first serve as machine-checked documentation. More importantly, they
provide a safety guarantee. As stated by Milner (1978), “Well-typed expressions
do not go wrong.”
(ii) Advanced type systems can also guarantee various forms of security, resource
usage, complexity, etc.
(iii) Types encourage separate compilation, modularity, and abstraction.
(iv) Types can also be used to drive compiler optimizations. Type-checking is
compositional: type-checking an application depends on the type of the function
and the type of the argument and not on their code. This is a key to modularity

56
and code maintenance: replacing a function by another one of the same type will
preserve well-typedness of the whole program.

7.6 Disadvantages of Typed Programs


(i) Annotating programs with types can lead to a lot of redundancies.
(ii) Types can even become extremely cumbersome when they have to be explicitly and
repeatedly provided.
(v) In some pathological cases, they may even increase the size of source terms non
linearly. This creates a need for a certain degree of type reconstruction (also called
type inference), where the source program may contain some—but not all—type
information.

Summary
In this Session, you have been introduced to the meaning and importance of type systems in
programming languages. We have some languages that are statically typed while many of
today’s languages are dynamically typed. Languages are also categorized as weak and
strongly typed. Now answer the following questions:

Self-Assessment Questions
1. Differentiate between strongly and weakly, static and dynamic typed languages,
citing copious examples.
2. In between static and dynamic typed languages, which is your take? Support your
option with cogent reasons
3. State the advantages and disadvantages of typed programs

57
Study Session 8: Functional vs. Imperative Languages
Expected Duration: 1 week or 2 contact hours

Introduction

Most of the programming languages today are imperative. Examples are C, C++, ADA,
PASCAL and Java. They follow Von Neumann architecture in which program and its data
are stored in the computer memory (RAM) during compilation and execution. On the other
hand, functional languages are based on mathematical function principle. In this session, we
shall discuss the nature and types of these languages.

Learning Outcomes

When you have studied this session, you should be able to explain the following concepts
With respect to Functional and Imperative Languages:
8.1 Meaning of Imperative Languages?
8.2 Specific Nature and Problems of Imperative Languages
8.3 Naming and Variables in Imperative Languages
8.4 Declarative vs. imperative programming
8.5 Advantages and disadvantages of imperative programming languages
8.6 Functional Programming Languages
8.7 Why functional programming is more relevant today than ever
8.8 Advantages and disadvantages of functional programming
8.9 Functional programming using the example of a parser
8.10 The Lambda λ Calculus

8.1 What are Imperative Languages?

Von Neumann machine forms the basis of imperative languages. The machine has a
memory, which contains both program instructions (program store) and data values (data
store).

An imperative language has variable declarations, expressions and commands.


 Declarations assign names to memory locations and associate types with the stored
values, e.g. int x.
 Expressions are the current values in the data store. Given x, the store returns the
current value of x in the data store.
 Commands are executed in the order they appear in the program store, although
conditional and unconditional jumps can change the flow of execution. Originally,
commands in an imperative language were simple abstractions of the instructions in
standard Von Neumann machine. Commands include Assignment, Conditional and
Branching Statements. Assignments update the data store while conditional and
branching statements allowed a set of statements to be either skipped or repeatedly
executed.

A programming language is said to be Turing complete if it contains integer variables,


values and operations, and has assignment statements. In addition, it has control constructs,
statement sequencing, conditionals and branching statements. All other statement forms,
like while, for, case selections, procedure declarations and calls, and data types (strings,

58
floats) are added in modern languages to enhance the ease of programming various complex
applications.

Therefore, an imperative programming language must be Turing complete and also supports
a number of fundamental features that are have emerged with the evolution of the imperative
programming paradigm since 1940s. The additional features are:
 Data types for real numbers, characters, strings, Booleans and their operators.
 Control structures – for and while loops, switch statements.
 Arrays and element assignments
 Record structures and element assignments
 Input / output commands
 Pointers, and
 Procedures and functions (methods).

8.2 Specific Nature and Problems of Imperative Languages

Imperative programming (from Latin imperare = command) is the oldest programming


paradigm. A program based on this paradigm is made up of a clearly-defined sequence of
instructions to a computer.

Therefore, the source code for imperative languages is a series of commands, which specify
what the computer has to do – and when – in order to achieve a desired result. Values used
in variables are changed at program runtime. To control the commands, control structures
such as loops or branches are integrated into the code.

Imperative programming languages are very specific, and operation is system-oriented. On


the one hand, the code is easy to understand; on the other hand, many lines of source text are
required to describe what can be achieved with a fraction of the commands using declarative
programming languages.

These are the best-known imperative programming languages:


 Fortran
 Java
 Pascal
 ALGOL
 C
 C#
 C++
 Assembler
 BASIC
 COBOL
 Python
 Ruby

The different imperative programming languages can, in turn, be assigned to three further
subordinate programming styles – structured, procedural, and modular.

The structured programming style extends the basic imperative principle with
specific control structures: sequences, selection, and iteration. This approach is based on a

59
desire to limit or completely avoid jump statements that make imperatively designed code
unnecessarily complicated.

The procedural approach divides the task a program is supposed to perform into smaller
sub-tasks, which are individually described in the code. This results in programming
modules which can also be used in other programs. The modular programming model goes
one step further by designing, developing, and testing the individual program components
independently of one another. The individual modules are then combined to create the actual
software.

Languages like C, C++, Java, Python, and Ruby are considered imperative languages
because the fundamental construct is the assignment statement. In each of these languages
we declare variables and assign them values, updating those variables as a program’s
execution progresses.

Imperative languages are heavily influenced by the von Neumann architecture of computers
that includes a store and a program counter; the computation model has control structures
that iterate over instructions that make incremental modifications of memory. Assignment
of values to variables, for loops, and while loops are all part of imperative languages.

The principal operation in imperative languages is the assignment of values to variables.


Programs are statement oriented, and they carry out algorithms with statement level
sequential control. In other words, computing is done by side-effects. Sometimes problems
with imperative programs stem from these side-effects. It is difficult to reason about a
program that relies on side-effects. If we wish to reuse the code of an imperative program
then we must be sure that the same conditions are true before the reused code executes since
imperative code relies on a certain machine state. As programmers we sometimes forget
which preconditions are required and what post-conditions result from executing a segment
of code. That can lead to bugs in our programs.

8.3 Naming and Variables in Imperative Languages

Names are the identifiers, which are used to denote locations in the data store. Names are
composed of letters and digits or an underscore; the first character must be a letter (a – z).
names could be case – sensitive or insensitive. Java, C and C++ names are case sensitive
while ADA and LISP are not. Some names could be reserved, meaning they may not be
used for user variable names.

In some languages like PASCAL and SCHEME, some names are merely predefined.
Programmers are free to redefine them. This is common with their library functions. For
instance, true in PASCAL could be redefined and used as a variable.

Most imperative languages does not allow two different variables with the same name.
However, the concept of scope of a declaration overrules this.

60
8.4 Declarative vs. imperative programming

Imperative programming languages differ from declarative languages on one fundamental


point: imperative programming focuses on the “how”, declarative programming on the
“what”.

But what does that mean? Imperative programming languages are composed of step-by-step
instructions (how) for the computer. They describe explicitly which steps are to be
performed in what order to obtain the desired solution at the end. By contrast, in declarative
programming, the desired result (what) is described directly. This becomes clearer when
using a cooking analogy for illustration: imperative languages provide recipes; declarative
languages contribute photos of the finished meal.

In declarative languages, the source code remains very abstract in terms of the specific
procedure. To get to the solution, an algorithm is used which automatically identifies and
applies appropriate methods. This approach has numerous advantages: Programs can
be written much more quickly, and applications are also very easy to optimize. If a new
method is developed in the future, the abstract instructions in the source code mean that the
algorithm can easily utilize the newer method.

Imperative programming example

Imperative programming languages are characterized by their instructive nature and, thus,
require significantly more lines of code to express what can be described with just a few
instructions in the declarative style. In the following example, the aim is to output a list of
first names:

Imperative programming (PHP)

$participantlist = [1 => 'Peter', 2 => 'Henry', 3 => 'Sarah'];


$firstnames = [ ];
foreach ($participantlist as $id => $name) {
$firstnames[ ] = $name;
}

Declarative programming (PHP)

$firstnames = array_values($participantlist);

Table 8.1: Imperative and declarative programming

Imperative programming
paradigm Declarative programming paradigm

“How?” “What?”
Classic New trend
A program based on this paradigm is A program based on this paradigm is made up of
made up of a series of instructions instructions for how the program should deal with
an input. Calculations are performed by

61
Imperative programming
paradigm Declarative programming paradigm

that tell the computer what it should manipulation of values, with the procedure
calculate/do and in what order. controlled by the process of recursion.
The name comes from “imperare”, The name comes from “declarare”, the Latin
the Latin word for “command”. word for “describe”.
The desired solution path is The desired result is specified.
specified
Typical programming languages Typical programming languages include Lisp,
include C, Pascal, Fortran, ALGOL, ML, Haskell, F#, Prolog, and Oz
and all assembly languages.

8.5 Advantages and disadvantages of imperative programming languages

Many programming languages based on the imperative programming paradigm are in use
today. On the one hand, this is because the approach is the original form of programming.
On the other hand, despite the existence of alternative models, the imperative paradigm still
has some practical advantages.

The languages are relatively easy to learn, as the code can be read like a step-by-step
instruction. Therefore, programmers normally learn an imperative language first as part of
their training.

Easy legibility is a crucial factor in day-to-day operations. Ultimately, maintenance and


optimization of applications should not be linked to a specific person; different employees
should be able to do it without too much difficulty even if they haven’t written the code
from scratch themselves.

One disadvantage of procedural programming is that for more complex problems to be


solved, the amount of code quickly starts to grow. It remains easy to read but becomes
confusing due to its volume.

Execution is not clearly delineated from the programming as it is in the declarative style,
therefore, subsequent interventions can produce unwanted errors. Extensions are also more
difficult to implement in pure imperative code – unlike in the declarative paradigm, where
there are methods that can be used to add them separately.

62
Advantages Disadvantages

Code quickly becomes very extensive and


Easy to read thus confusing
Relatively easy to learn Higher risk of errors when editing
Conceptual model (solution path) is System-oriented programming means that
very easy for beginners to maintenance blocks application
understand development
Characteristics of specific
applications can be taken into Optimization and extension is more
account difficult
In practice, mixed forms of the paradigms are generally used these days because both,
imperative and declarative programming styles, have their advantages and disadvantages.
However, the declarative programming style is becoming increasingly dominant,
supplemented by imperative methods.

8.6 Functional Programming Languages

Functions exist in every higher-level programming language. However, the functional


approach in software development deals with functions in a very particular way.

A functionally programmed program is made up of a string of function calls, where each


program section can be understood as a function. In functional programming, the functions
can take on different forms. For example, they can be linked to one another like data or
be used in the form of parameters. In addition, they can subsequently be used as function
results. Conversely, the paradigm leads to there being no independent assignment of values.

This subsidiary form of declarative programming is very important for computer science in
general – and at the same time can be used for a wide range of specific purposes. The special
handling of functions enables programmers using the functional method to create and use
extensive calculation rules made up of functions.

As the name suggests, the focus of the functional approach to programming is on functions.
With a functional program, all elements can be considered a function, and the code can be
executed with concatenated function calls. Conversely, there are no independent
assignments of values. A function is best envisaged as a special variant of a subprogram.
This is reusable and, unlike a procedure, directly returns a result.

Functional languages are based on the mathematical concept of a function and do not reflect
the underlying von Neumann architecture. These languages are concerned with data objects
and values instead of variables. The principal operation is function application. Functions
are treated as first-class objects that may be stored in data structures, passed as parameters,
and returned as function results. Primitive functions are generally supplied with the
language implementation.

Functional languages allow new functions to be defined by the programmer. Functional


program execution consists of the evaluation of an expression, and sequential control is

63
replaced by recursion. There is no assignment statement. Values are communicated
primarily through the use of parameters and return values. Without variables, loop
statements don’t have a purpose and so they also don’t exist in pure functional languages.
Pure functional languages have no side-effects other than possibly reading some input from
the user. Scheme is a pure functional language.

In general, functional languages avoid or at least isolate code with side-effects. Even input
and output operations in functional languages do not update the state of variables within a
program. What is amazing is that it has been proven that exactly the same things can be
computed with functional languages as can be computed with imperative languages. This is
known because a Turing machine, the theoretical basis for imperative programming and the
design of the computer, have been proven equivalent in power to the Lambda Calculus, the
basis for all functional programming languages.

You might be surprised by the number and types of languages that support functional
programming. Of course, Standard ML was designed as a functional language
From the ground up, but languages like C++, Java and Python also support functional
programming. While C++, Java and Python are also object-oriented imperative languages,
they all support functional programming as well. Functional programming does not depend
so much on the language, but how you use the language.

8.6.1 Functional Programming: Ideal for algorithms

Common programming languages usually allow for several programming paradigms,


whereby a rough distinction is made between declarative and imperative programming. To
put it simply, such paradigms form the basic approach when programming software. A sub-
form of the declarative approach is so-called functional programming, which is
predominantly used in the development of the following programs or codes:

 Technical and mathematical applications


 Artificial intelligence (AI)
 Compilers and parsers
 Algorithms

What makes the programming approach or functional programming languages so interesting


for this type of computer application? And how does it differ from other concepts such as
object-oriented programming?

8.7 Why functional programming is more relevant today than ever

Although the roots of functional programming date back to the 1930s (as part of basic
mathematical research), the functional approach continues to be very popular, especially
within technical and mathematical fields. There are several reasons for this:

 Extensive possibilities for algebraic program transformation


 Extensive possibilities for algebraic program synthesis
 Simple semantic analysis possibilities thanks to the renunciation of "inner states in
the calculation process" and "by-effects".
 Elimination of internal conditions: unlike imperative programming, no internal
states of a calculation process are required.

64
 Renunciation of side effects: the state changes which go hand-in-hand with the
internal states, the so-called by-effects, can also be dispensed within functional tasks.

Functional programming offers a high degree of abstraction as it is based on the


mathematical concept and principle of function. Clean application of this type of
programming leads to very precise code. Many small, reusable and highly specialized units,
as well as the functions, create a program to solve a much larger task.

Therefore, there are many practical reasons why functional programming and the functional
programming languages working with this principle are very popular in computer science,
in particular, when it comes to complex mathematical problems and algorithms. At the same
time, the very specific application areas ensure functional programming languages play
something of a niche role.

At a glance: The most important functional programming languages

The most important programming languages based on the functional approach include the
following:

 LISP
 ML
 Haskell
 OCaml
 F#
 Erlang
 Clojure
 Scala

Furthermore, there are well-known programming languages that allow functional


programming as one of several possible paradigms:

 Perl
 Ruby
 Visual Basic .NET
 Dylan
 ECMAScript

8.8 Advantages and disadvantages of functional programming

Advantages Disadvantages

Programs are stateless Data (e.g. variables) cannot be changed


Well-suited for parallelization Retrieval of large amounts of data not
possible efficiently
Easily testable code Not recommended for connections to
databases and servers
Easily verifiable code, even stateless Not suitable for many recursions of the
functions can be verified same stack

65
Advantages Disadvantages

Can be combined with imperative, object- Recursive programming can lead to


oriented programming serious errors
More accurate, shorter code Not suitable for all tasks

The table provides an overview to determine whether the functional paradigm is the right
approach for your software programming project or not. The decision in favor of a
programming style is often strongly dependent on the personal preferences of the developer.
For this reason, for example, object-oriented programming is a popular alternative to the
functional approach. The two approaches should, therefore, be briefly compared in the
following - including a final practical example.

8.8.1 Trend or no trend? Object-oriented and functional programming in cross-


comparison

Just as in fashion, there are various trends in programming. For quite some time now, object-
oriented programming has been on-trend. It’s particularly popular in the development of
web applications and computer games. In comparison to functional programming, one does
not describe the individual elements as a function but as objects and classes when using this
approach. In combination with an inheritance system, this offers the advantage that all
components can be easily reused and expanded at any time. Functional code, on the other
hand, is shorter, clearer, and preferred where testable and verifiable code is needed.

Incidentally, the choice between object-oriented and functional programming does not
necessarily have to be made. Many modern programming languages support working with
both programming styles. This way, they can be easily combined and developers benefit
from the merits of both paradigms.

8.9 Functional programming using the example of a parser

Parsers are software components that are often indispensable as supervisory mechanisms
for compilers to translate programming language into machine language.

A parser can generally be implemented on the basis of various programming paradigms, for
example, with an object-oriented language. However, the functional approach offers a set
of useful advantages with regard to a parser’s code design:

 There are no global and changeable variables. Accordingly, no programming


error can result from the so-called "mutable global state”, as can be the case with
object-oriented projects. This benefits a parser as a central element of the program.
 Thanks to higher-order functions and manageable program code, larger data
collections can be easily handled. This is very useful to a parser, which processes
large amounts of data.
 A parser is a program element that is run frequently. It helps the overall program,
provided that this central element is precisely programmed and runs efficiently, as
is the case with functional programming.
 An error in the parsing process is usually fatal and must be avoided at all costs. While
a program is running, however, there will certainly be a lot of semantic dependencies

66
that can often lead to serious errors. When implemented properly, functional
programming can help to minimize or even prevent such serious errors in execution.

8.10 The Lambda λ Calculus

All functional programming languages are derived either directly or indirectly from the
work of Alonzo Church and Stephen Kleene. The lambda calculus was defined by Church
and Kleene in the 1930s, before computers existed. At the time, mathematicians were
interested in formally expressing computation in some written form other than English or
other informal language. The lambda calculus was designed as a way of expressing those
things that can be computed. It is a very small, functional programming language.

In the lambda calculus, a function is a mapping from the elements of a domain to the
elements of a codomain given by a rule. Consider the function cube(x) = x3. What is the
value of the identifier cube in the definition cube(x) = x3? Can this function be defined
without giving it a name?

λx.x3 defines the function that maps each x in the domain to x3. We can say that this
definition or lambda abstraction, λx.x3, is the value bound to the identifier cube. We say that
x3 is the body of the lambda abstraction. Every lambda abstraction in lambda notation is a
function of one identifier. However, lambda expressions may contain more than one
identifier.

The expression y2 + x can be expressed as a lambda abstraction in one of two ways:

λx.λy.y2 +x
λy.λx.y2 +x

In the first lambda abstraction the x is the first parameter to be supplied to the expression.
In the second lambda abstraction the y is the parameter to get a value first. In either case,
the abstraction is often abbreviated by throwing out the extra λ. In abbreviated form the two
abstractions would become λxy.y2 +x and λyx.y2 +x.

Summary
In this Session, you have been introduced to Functional and imperative languages. The
specific nature of the programming paradigms are discussed

Self-Assessment Questions
1. Discuss the characteristics, advantages and disadvantages of Imperative Languages.
2. Discuss the characteristics, advantages and disadvantages of Functional languages

67
Study Session 9: Structured Query Language
Expected Duration: 1 week or 2 contact hours

Introduction

SQL is a standard language for storing, manipulating and retrieving data in databases. In
this Session, we shall learn the basic rudiments of using SQL with standard databases like
MySQL, Oracle, Access, etc.

Learning Outcomes

When you have studied this session, you should be able to explain the following concepts
With respect to Structured Query Language (SQL):
9.1 Meaning of SQL
9.2 Business Uses of SQL
9.3 Relational Database Management System (RDBMS)
9.3 Creating Microsoft Access Database Tables
9.4 Where to type SQL statements in Microsoft Access "2007", "2010", "2013" or
Access "2016"
9.5 Some SQL Statements and Their Implications

9.1 Meaning of SQL

Structured Query Language or SQL, is a programming concept used to do set operations


(like union, intersect, and minus) to organize and retrieve information in relational
databases, based on “set theory and relational algebra.”

In any system that uses SQL, “data elements or attributes, categorized into columns, are
related into tuples (rows). Sets of relations with identical structure form tables.” These
elements, correlated rows, columns, and tables form the basis for a Relational Database
Management System (RDBMS) (Michelle, 2017). SQL is a data sub-language widely used
to access relational databases.

SQL belongs to the set of declarative languages, which are fundamentally command-driven.
They are dominated by statements, which express “what to do” rather than “how to do
it”

9.2 Business Uses of SQL

According to (Michelle, 2017), the following are the different ways SQL is used in
businesses.
 Access and manipulate information.
 Generate reports to aid decision making process.
 Make it easier to import and export data to/from different systems.
 To facilitate finding and supporting roles using data analysis.

68
9.3 Relational Database Management System (RDBMS)

RDBMS is the basis for SQL, and for all modern database systems such as MS SQL Server,
IBM DB2, Oracle, MySQL, and Microsoft Access. The data in RDBMS is stored in database
objects called tables. A table is a collection of related data entries and it consists of columns
and rows.

Every table is broken up into smaller entities called fields. A column is a vertical entity in a
table that contains all information associated with a specific field in a table.

The fields in the Customers table consist of CustomerID, CustomerName, ContactName,


Address, City, PostalCode and Country. A field is a column in a table that is designed to
maintain specific information about every record in the table.

The rows form the records or tuples of the table while the columns contain the attributes or
properties of individual instances (records) in the table. A record, also called a row, is each
individual entry that exists in a table. Some relational database tables are shown below from
MS Access Database.

Table Customer:

Table Product:

Table Customer_Product

69
9.3 Creating Microsoft Access Database Tables

1. Open MS Access, Blank Database is selected by default. Now Type the name you
want to give to the database at the lower right corner under File Name. Finally click
on Create.
2. Suppose we are interested in creating Tables for Customer and Product that look like
the ones depicted above:
(a) As soon MS Access is opened, a table called Table 1 is displayed by default. You
can use this Table1 for the Customer Table. Right Click on Table 1 at the left pane
and click on Design View.
(b) In the popped up window, type Customer as the name of the Table1
(c) Change the default ID to CustID. Observe that this field has been chosen for you to
be the primary key for the table
(d) Change the Data Type from Autonumber to Text
(e) Change the Field Size in the down pane to 10 or maximum number of characters that
you desire. You may leave the Description column for now. It is where you type the
description of the fields ( A form of data dictionary).
(f) Click on second row, type CustName as field name. Click on Data Type cell, Text
is selected by default. Just change the field size to something like 30.
(g) Continue in this way to create the other fields. Save the table
(h) To enter some records into the table, double click the table Customer in the Tables
pane. Add the records.
(i) To create the second table, click on Create Menu, then Table design
(j) Type all the field names and their data types.
(k) To insert the Primary Key on PID, click on PID cell, a window is popped up. Look
for the Key symbol by the left of the popped up window, click on the key icon.
(l) Save the table as Product.

3. The Third table will be a relationship (look-up) table for the initial tables Customer
and Product. Note that both CustID and PID from the base tables will jointly form
the primary key for this relationship table (You will learn this aspect in a proper
Database Course at a higher level). So, we set them up to “look up to their sources”.
We shall call it Customer_Product Table. A sample of it looks like the one re-drawn
below:

(a) Click on Create, then Table Design.


(b) Type CustID in the first cell and PID in the second row. Leave the Data Types as
they were for now.
(c) Select the two rows and assign them as Primary key together. Note that the key
symbol must appear on both rows, as shown below.

70
(d) Save the table as Customer_Product
(e) Create the other fields in the table: OrderedDate, Quantity, InvoiceNo, etc
(f) Add data into the database tables

9.4 Where to type SQL statements in Microsoft Access "2007", "2010", "2013" or
Access "2016"
Follow this procedure as outlined in
http://www.jaffainc.com/SQLStatementsInAccess.htm#Access2007:

1. After launching Microsoft Access, either select "more" to open an existing database or
click "Blank Database" to create a New database. If you are creating a new database, type
a name (any name is fine) for your database in the “File Name” box. Next, click the
“Create” button.
Note: If you are selecting an existing database (i.e the downloaded course database),
browse (locate where you saved the database on your computer) for the database after
you click "more".

2. Once Access opens, Click “Create” from the menu running across the top of the screen.

3. Next, Click the “Query Design” button.

4. You'll see a “Show Table” dialog box. Click close on this dialog box without selecting
any tables.

5. Select the “SQL View” or “SQL” button near the top left of the screen.

6. Use the "SQL View" or “SQL” button to select “SQL View”. (Click the down arrow
located on this button to locate “SQL View”).

7. Type your SQL commands in this view (SQL View).

To run a command, click the "Run" button.

9.5 Some SQL Statements and Their Implications

(i) SELECT Statement (Microsoft Access SQL)

The SELECT command instructs the Microsoft Access database engine to return
information from the database as a set of records. To perform this operation, the Microsoft®
Jet database engine searches the specified table or tables, extracts the chosen columns,
selects rows that meet the criterion, and sorts or groups the resulting rows into the order
specified. SELECT statements do not change data in the database.

71
SELECT is usually the first word in an SQL statement. The minimum syntax for a SELECT
statement is:
SELECT fields FROM table

You can use an asterisk (*) to select all fields in a table. The following example selects all
of the fields in the Employees table:

SELECT * FROM Customer;

If a field name is included in more than one table in the FROM clause, precede it with the
table name and the . (dot) operator. In the following example, the Department field is in both
the Employees table and the Supervisors table. The SQL statement selects departments from
the Employees table and supervisor names from the Supervisors table:

SELECT Employees.Department, Supervisors.SupvName;

Whenever you use aggregate functions or queries that return ambiguous or


duplicate Field object names, you must use the AS clause to provide an alternate name for
the Field object. The following example uses the title HeadCount to name the
returned Field object in the resulting Recordset object:

SELECT COUNT(EmployeeID) AS HeadCount FROM Employees;


SELECT Count(PostalCode) AS Tally FROM Customers;

SELECT Count (*) AS TotalEmployees, Avg(Salary) AS AverageSalary, Max(Salary) AS


MaximumSalary FROM Employees;

(ii) WHERE Clause

The WHERE clause specifies which records from the tables listed in the FROM clause are
affected by SELECT, UPDATE, or DELETE statement. The Microsoft Access database
engine selects the records that meet the conditions listed in the WHERE clause. If you do
not specify a WHERE clause, your query returns all rows from the table. If you specify more
than one table in your query and you have not included a WHERE clause or a JOIN clause,
your query generates a Cartesian product of the tables.

WHERE is optional, but when included, follows FROM. For example, you can select all
employees in the sales department
(
WHERE Dept = 'Sales'
)

or all customers between the ages of 18 and 30 (


WHERE Age Between 18 And 30
).

WHERE is similar to HAVING. WHERE determines which records are selected. Similarly,
once records are grouped with GROUP BY, HAVING determines which records are
displayed. Use the WHERE clause to eliminate records you do not want grouped by a
GROUP BY clause.

72
Use various expressions to determine which records the SQL statement returns. For
example, the following SQL statement selects all employees whose salaries are more than
N21,000:

SELECT LastName, OtherNames, Salary FROM Employees WHERE Salary > 21000;

A WHERE clause can contain up to 40 expressions linked by logical operators, such


as And and Or. To find records dated May 10, 1996 in a United Kingdom database, you
must use the following SQL statement:

SELECT * FROM Orders WHERE ShippedDate = #5/10/96#;

You can also use the DateValue function which is aware of the international settings
established by Microsoft Windows®. For example, use this code for the United States:

SELECT * FROM Orders WHERE ShippedDate = DateValue('5/10/96');

And use this code for the United Kingdom:

SELECT * FROM Orders WHERE ShippedDate = DateValue('10/5/96');


SELECT LastName, FirstName FROM Employees WHERE LastName = 'King';

(iii) FROM Clause

Specifies the tables or queries that contain the fields listed in the SELECT statement. FROM
is required and follows any SELECT statement. The order of the table names
in tableexpression is not important. For improved performance and ease of use, it is
recommended that you use a linked table instead of an IN clause to retrieve data from an
external database.

The following example shows how you can retrieve data from the Employees table:

SELECT LastName, FirstName FROM Employees;

This following example shows the number of employees and the average and maximum
salaries.

SELECT Count (*) AS TotalEmployees, Avg(Salary) AS AverageSalary, Max(Salary) AS


MaximumSalary FROM Employees;

(iv) GROUP BY Clause

This combines records with identical values in the specified field list into a single record. A
summary value is created for each record if you include an SQL aggregate function, such
as Sum or Count, in the SELECT statement. The GROUP BY clause is optional. Summary
values are omitted if there is no SQL aggregate function in the SELECT statement.

Null values in GROUP BY fields are grouped and are not omitted. However, Null values
are not evaluated in any SQL aggregate function.

73
Use the WHERE clause to exclude rows you do not want grouped, and use
the HAVING clause to filter records after they have been grouped.

SELECT Title, Count([Title]) AS TallyFROM Employees GROUP BY Title;

For each unique job title, this example calculates the number of employees in Ibadan who
have that title.

SELECT Title, Count(Title) AS Tally FROM Employees WHERE Region = 'WA' GROUP
BY Title;

(v) HAVING Clause

This specifies which grouped records are displayed in a SELECT statement with a GROUP
BY clause. After GROUP BY combines records, HAVING displays any records grouped
by the GROUP BY clause that satisfy the conditions of the HAVING clause. The HAVING
clause is optional in SQL statements.

HAVING is similar to WHERE, which determines which records are selected. After records
are grouped with GROUP BY, HAVING determines which records are displayed:

SELECT CategoryID, Sum(UnitsInStock) FROM Products GROUP BY CategoryID


HAVING Sum(UnitsInStock) > 100 And Like "BOS*";

A HAVING clause can contain up to 40 expressions linked by logical operators, such


as And and Or.

SELECT Title, Count(Title) as Total FROM Employees WHERE Region = 'WA'


GROUP BY Title HAVING Count(Title) > 1;

Let’s discuss a little about LIKE phrase. There are four different ways in which we can use
LIKE.
a) WHERE CustAdd LIKE “Oshodi”;
This will retrieve records that have only Oshodi as the only entry in the CustAdd
fields.

b) WHERE CustAdd LIKE “Oshodi*”;


This will retrieve records that have Oshodi as the first entry in the CustAdd fields
followed by any other entries. For example, addresses like “Oshodi, Lagos”,
“Oshodi near Ojota, Lagos”

c) WHERE CustAdd LIKE “*Oshodi”;


This will retrieve records that have any number of entries but Oshodi is the last
entry in the CustAdd fields f. For example, addresses like “No. 4, Salami Street,
Oshodi”, “Arowojoye lane Oshodi”

d) WHERE CustAdd LIKE “*Oshodi*”;


This will retrieve records that have Oshodi as part of the entries in the CustAdd
fields. For example, addresses like “No. 4, Salami Street, Oshodi, Lagos”,

74
“Arowojoye lane Oshodi near Ojota, Lagos”, “Arowojoye lane Oshodi”,
“Oshodi near Ojota, Lagos”

(vi) ORDER BY Clause

This sorts a query's resulting records on a specified field or fields in ascending or descending
order. ORDER BY is also optional in SQL statements. However, if you want your data
displayed in sorted order, then you must use ORDER BY.

The default sort order is ascending (A to Z, 0 to 9). Both of the following examples sort
employee names in last name order:

SELECT LastName, FirstName FROM Employees ORDER BY LastName;

SELECT LastName, FirstName FROM Employees ORDER BY LastName ASC;

To sort in descending order (Z to A, 9 to 0), add the DESC reserved word to the end of each
field you want to sort in descending order. The following example selects salaries and sorts
them in descending order:

SELECT LastName, Salary FROM Employees ORDER BY Salary DESC, LastName;

If you specify a field containing Memo or OLE Object data in the ORDER BY clause, an
error occurs. The Microsoft Jet database engine does not sort on fields of these types.

ORDER BY is usually the last item in an SQL statement.

You can include additional fields in the ORDER BY clause. Records are sorted first by the
first field listed after ORDER BY. Records that have equal values in that field are then sorted
by the value in the second field listed, and so on.

The SQL statement shown in the following example uses the ORDER BY clause to sort
records by last name in descending order (Z-A).

SELECT LastName,FirstName FROM Employees ORDER BY LastName DESC;

(vii) DELETE Statement

This creates a delete query that removes records from one or more of the tables listed in
the FROM clause that satisfy the WHERE clause. DELETE is especially useful when you
want to delete many records.

To drop an entire table from the database, you can use the Execute method with
a DROP statement. If you delete the table, however, the structure is lost. In contrast, when
you use DELETE, only the data is deleted; the table structure and all of the table properties,
such as field attributes and indexes, remain intact.

You can use DELETE to remove records from tables that are in a one-to-many relationship
with other tables. Cascade delete operations cause the records in tables that are on the many

75
side of the relationship to be deleted when the corresponding record in the one side of the
relationship is deleted in the query.

For example, in the relationship between the Customers and Orders tables, the Customers
table is on the one side and the Orders table is on the many side of the relationship. Deleting
a record from Customers results in the corresponding Orders records being deleted if the
cascade delete option is specified.

A delete query deletes entire records, not just data in specific fields. If you want to delete
values in a specific field, create an update query that changes the values to Null.

DELETE * FROM Employees WHERE Title = 'Trainee';

(viii) INSERT INTO Statement

This adds a record or multiple records to a table. This is referred to as an append query.
You can use the INSERT INTO statement to add a single record to a table using the single-
record append query syntax as shown above. In this case, your code specifies the name and
value for each field of the record. You must specify each of the fields of the record that a
value is to be assigned to and a value for that field. When you do not specify each field, the
default value or Null is inserted for missing columns. Records are added to the end of the
table.

You can also use INSERT INTO to append a set of records from another table or query by
using the SELECT … FROM clause as shown above in the multiple-record append query
syntax. In this case, the SELECT clause specifies the fields to append to the
specified target table.

INSERT INTO Customers SELECT * FROM [New Customers];

This example creates a new record in the Employees table.

INSERT INTO Employees (FirstName,LastName, Title) VALUES ('Harry', 'Washington',


'Trainee');

(ix) UPDATE STATEMENT

This creates an update query that changes values in fields in a specified table based on
specified criteria. UPDATE is especially useful when you want to change many records or
when the records that you want to change are in multiple tables. You can change several
fields at the same time. The following example increases the Order Amount values by 10
percent and the Freight values by 3 percent for shippers in Nigeria:

UPDATE Orders SET OrderAmount = OrderAmount * 1.1, Freight = Freight * 1.03


WHERE ShipCountry = 'NG';

76
(x) SQL Aggregate Functions

Using the SQL aggregate functions, you can determine various statistics on sets of values.
You can use these functions in a query and aggregate expressions in the SQL property of
a QueryDef object or when creating a Recordset object based on an SQL query.

 Avg Function

This calculates the arithmetic mean of a set of values contained in a specified field on a
query.

SELECT Avg(Freight) AS [Average Freight] FROM Orders WHERE Freight > 100;

 Count Function

This calculates the number of records returned by a query.


SELECT Count(*) AS TotalOrders FROM Orders;

 Min, Max Functions

This return the minimum or maximum of a set of values contained in a specified field on a
query. You can use Min and Max to determine the smallest and largest values in a field
based on the specified aggregation, or grouping. For example, you could use these functions
to return the lowest and highest freight cost. If there is no aggregation specified, then the
entire table is used.

SELECT Min(Freight) AS [Low Freight], Max(Freight)AS [High Freight]


FROM Orders WHERE ShipCountry = 'UK';

 StDev, StDevP Functions

These return estimates of the standard deviation for a population or a population sample
represented as a set of values contained in a specified field on a query. The StDevP function
evaluates a population, and the StDev function evaluates a population sample.If the
underlying query contains fewer than two records (or no records, for the StDevP function),
these functions return a Null value (which indicates that a standard deviation cannot be
calculated). To calculate the standard deviation of the freight charges for orders shipped to
Nigeria

SELECT StDev(Freight) AS [Freight Deviation] FROM Orders WHERE ShipCountry =


'NG';

 Sum Function

This returns the sum of a set of values contained in a specified field on a query.
The Sum function totals the values in a field. For example, you could use the Sum function
to determine the total cost of freight charges.

SELECT Sum(UnitPrice * Quantity)AS [Total Revenue] FROM [Order Details];

77
Summary

You have been introduced to SQL in this Session. The uses, syntax and running of SQL
statements were discussed. Now answer the following practical questions with the aid of
your laptop.

Practical Question 1

At CSC Company, located in Ibadan, an Attendance Clocking Machine (ACM) is installed


at the main gate entrance to take attendance of staff once a day in the morning. Each staff
has a clocking card containing a chip on which are recorded the ID and other information
of the staff. When a staff arrives the company premises, the card is inserted into the ACM
which identifies the staff, his/her department and the time the clocking is done.

A computerized database is connected to the ACM on a Local Area Network (LAN). The
database contains data about Staff (StaffID, StaffSurname, StaffOtherNames, StaffAge,
StaffDesignation), Department (DeptID, DeptName, DeptFunction) and Attendance
(StaffID, DeptID, DateClocked, TimeClocked). Time is recorded on 24 hours scale like
8.00, 13.45, 18.23, etc.

(i) Design the Database using Microsoft Access or otherwise. Insert about five
records each into the tables
(ii) Generate reports for the following information from the database:
(a) List of all Staff including their Departments from the database. You may
need to create a relationship table for Staff and Department in this case.
(b) List of all Staff names (and their Departments) that resume at exactly
8.00 on 21/10/2019
(c) List of all Staff names (and their Departments) whose age is 55 years and
above and resume before 8.00 on 21/10/2019. The company will like to
reward them for prompt resumption at work on that day.

Practical Question 2

CSC College of Business Studies currently uses paper-based method to manage her
students, staff and administrative data. This has been giving them serious problems in
retrieving and computing results for the students. Forms are usually filled by both students
and staff to capture their vital data. This year, several forms are missing or mixed up, thereby
compounding the problems of students’ record management the more.

The management is therefore interested in automating her business processes for the
College. One better option suggested to the management is to utilize database technology.
As the only Management Information System (MIS) expert in the College, you have been
contacted to design a database-driven MIS for the College.

(a) Identify the essential entities and attributes needed in the database design. Using MS
Access database engine, design a suitable database for the College.
(b) The College is interested in the following Reports
(i) List of students’ matriculation numbers, names, mobile phone numbers
and email addresses in the college;

78
(ii) List of matriculation numbers and names of students who are in the 16 –
20 age bracket and their State of origin is Lagos;
(iii) The mean score of all students in CSC 331 course for 2020/2021 Session
(iv) The matric number and name of student(s) that has the highest score in
CSC 331 in 2020/2021 Session
(v) The list of all courses and scores of a particular student in 2020/2021
session

79
Study Session 10: Function and Operator Overloading,
Conversion and Casting
Expected Duration: 1 week or 2 contact hours

Introduction
In this study session, we are interested in discussing situations where functions or methods
and operators are overloaded in programs. By overloading we mean the concept is being
used for different contexts in the same program. For example, two or more functions with
same names but with different arguments or parameters can be found in a class. Overloading
is a form of polymorphism in Object Oriented Programming. Polymorphism is an important
concept of object-oriented programming. It simply means more than one form. That is, the
same entity (method or operator or object) behaves differently in different scenarios.

Learning Outcomes

When you have studied this session, you should be able to explain the following concepts
with respect to overloading, type conversions and Casting in programming languages:
10.1 Meaning of Overloading
10.2 Function/Method Overloading in C++
10.3 Function/Method Overloading in Java
10.4 Operator Overloading
10.5 Conversion and Casting

10.1 Concept of Overloading

C++ allows us to specify more than one definition for a function name or an operator in the
same scope, which is called function overloading and operator overloading respectively.
An overloaded declaration is a declaration that is declared with the same name as a
previously declared declaration in the same scope, except that both declarations have
different arguments and obviously different definition (implementation).

When an overloaded function or operator is called, the compiler determines the most
appropriate definition to use, by comparing the argument types you have used to call the
function or operator with the parameter types specified in the definitions. The process of
selecting the most appropriate overloaded function or operator is called overload
resolution.

10.2 Function/Method Overloading in C++

One can have multiple definitions for the same function name in the same scope. The
definition of the function must differ from each other by the types and/or the number of
arguments in the argument list. We cannot overload function declarations that differ only
by return type. Following is the example where same function print() is being used to print
different data types –

80
#include <iostream>
using namespace std;

class printData {
public:
void print(int i) {
cout << "Printing int: " << i << endl;
}
void print(double f) {
cout << "Printing float: " << f << endl;
}
void print(char* c) {
cout << "Printing character: " << c << endl;
}
};

int main(void) {
printData pd;

// Call print to print integer


pd.print(5);

// Call print to print float


pd.print(500.263);

// Call print to print character


pd.print("Hello C++");

return 0;
}

When the above code is compiled and executed, it produces the following result –

Printing int: 5
Printing float: 500.263
Printing character: Hello C++

10.3 Function/Method Overloading in Java

Suppose two same methods are created in the superclass and its subclasses, respectively. In
this case, the method that will be called depends upon the object used to call the method.
For example,

abstract class Animal {


public abstract void makeSound();
}

class Dog extends Animal {


@Override
public void makeSound() {
System.out.println("Bark bark..");
}
}

81
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Meow meow..");
}
}
class Main {
public static void main(String[] args) {
Dog d1 = new Dog();
d1.makeSound();

Cat c1 = new Cat();


c1.makeSound();
}
}

Output:
Bark bark…
Meow-meow...

In the above example, the method makeSound( ) has different implementations in two
different classes. When we run the program,
 the expression d1.makeSound( ) will call the method of Dog class. It is because d1 is
an object of the Dog class.
 the expression c1.makeSound() will call the method of Cat class. It is because c1 is an
object of the cat class.

The method that will be called is determined during the execution of the program. Hence,
method overriding is a run-time polymorphism. In Java, run-time polymorphism can be
achieved through method overriding. The above example illustrates a run-time method
overloading. The compile-time polymorphism can be achieved through method overloading
and operator overloading in Java. The next example code illustrates a compile time method
overloading:

class Demo {
public void displayPattern(){
for(int i = 0; i < 10; i++) {
System.out.print("*");
}
}

public void displayPattern(char symbol) {


for(int i = 0; i < 10; i++) {
System.out.print(symbol);
}
}
}

class Main {
public static void main(String[] args) {
Demo d1 = new Demo();
d1.displayPattern();
System.out.println("\n");
d1.displayPattern('#');

82
}
}

Output:
**********
##########

In the above program, the displayPattern( ) method is overloaded.


 If we call the method without passing any arguments, a pattern of * is created.
 If we call the method by passing a character as an argument, a pattern of that character
is created.

10.4 Operator Overloading

The trio is common with C/C++ and Java where operator is overloaded and intermediate
results are converted to compatible types along the way. An operator is overloaded if it can
be used in different contexts with different results. For example, + operator used for
arithmetic addition and string concatenation in Java ordinary division (/) in C/ C++/ Java
depends on the data types of the operands. There may be some intermediate conversion
along the way.

Java does not support operator overloading, except for string concatenation for which
it overloads the + operator internally; due to the following reasons −

 Makes code complex − In case of operator overloading the compiler and interpreter
(JVM) in Java need to put an extra effort to know the actual functionality of the
operator used in a statement.
 Programming error − Custom definition for the operators creates confusion for the
programmers especially the new developers. Moreover, while working with
programming languages that support operator overloading the program error rate is
high compared to others.
 Easy to develop tools like IDEs − Removal of operator overloading concept keeps
the language simple for handling and process leading to a number of Integrated
development environment in Java.
 Method overloading − The functionality of operator overloading can be achieved
in Java using method overloading in Java in a simple, error free and clear manner.

10.4.1 Operator Overloading in C++

In C++ the overloading principle applies not only to functions, but to operators too. That is,
of operators can be extended to work not just with built-in types but also classes. A
programmer can provide his or her own operator to a class by overloading the built-in
operator to perform some specific computation when the operator is used on objects of that
class. Is operator overloading really useful in real world implementations? It certainly can
be, making it very easy to write code that feels natural (we'll see some examples soon). On
the other hand, operator overloading, like any advanced C++ feature, makes the language
more complicated. In addition, operators tend to have very specific meaning, and most
programmers don't expect operators to do a lot of work, so overloading operators can be
abused to make code unreadable.

83
Complex a(1.2,1.3); //this class is used to represent complex numbers
Complex b(2.1,3); //notice the construction taking 2 parameters for the real and imaginary part
Complex c = a+b; //for this to work the addition operator must be overloaded

The addition without having overloaded operator + could look like this:
Complex c = a.Add(b);
This piece of code is not as readable as the first example though--we're dealing with
numbers, so doing addition should be natural. (In contrast to cases when programmers abuse
this technique, when the concept represented by the class is not related to the operator--ike
using + and - to add and remove elements from a data structure. In this cases operator
overloading is a bad idea, creating confusion.)

In order to allow operations like Complex c = a+b, in above code we overload the "+"
operator. The overloading syntax is quite simple, similar to function overloading, the
keyword operator must be followed by the operator we want to overload:
class Complex
{
public:
Complex(double re,double im)
:real(re),imag(im)
{};
Complex operator+(const Complex& other);
Complex operator=(const Complex& other);
private:
double real;
double imag;
};
Complex Complex::operator+(const Complex& other)
{
double result_real = real + other.real;
double result_imaginary = imag + other.imag;
return Complex( result_real, result_imaginary );
}

The assignment operator can be overloaded similarly. Notice that we did not have to call
any accessor functions in order to get the real and imaginary parts from the parameter other
since the overloaded operator is a member of the class and has full access to all private data.
Alternatively, we could have defined the addition operator globally and called a member to
do the actual work. In that case, we'd also have to make the method a friend of the class, or
use an accessor method to get at the private data:
friend Complex operator+(Complex);

Complex operator+(const Complex &num1, const Complex &num2)


{
double result_real = num1.real + num2.real;
double result_imaginary = num1.imag + num2.imag;
return Complex( result_real, result_imaginary );
}

Why would you do this? When the operator is a class member, the first object in the
expression must be of that particular type. It's as if you were writing:
Complex a( 1, 2 );
Complex a( 2, 2 );

84
Complex c = a.operator=( b );

when it's a global function, the implicit or user-defined conversion can allow the operator
to act even if the first operand is not exactly of the same type:
Complex c = 2+b; //if the integer 2 can be converted by the
// Complex class, this expression is valid
By the way, the number of operands to a function is fixed; that is, a binary operator takes
two operands, a unary only one, and you can't change it. The same is true for the precedence
of operators too; for example the multiplication operator is called before addition. There are
some operators that need the first operand to be assignable, such as: operator =, operator (),
operator[ ] and operator ->, so their use is restricted just as member functions (non-static),
they can't be overloaded globally. The operator =, operator & and operator |, (sequencing)
have already defined meanings by default for all objects, but their meanings can be changed
by overloading or erased by making them private.

Another intuitive meaning of the "+" operator from the STL string class which is overloaded
to do concatenation:

string prefix("de");
string word("composed");
string composed = prefix+word;

Using "+" to concatenate is also allowed in Java, but note that this is not extensible to other
classes, and it's not a user defined behavior. Almost all operators can be overloaded in C++:

+ - * / % ^ & |
~ ! , = =
++ -- << >> == != && ||
+= -= /= %= ^= & = |= *=
<<= >>= [ ] ( ) -> ->* new delete

The only operators that can't be overloaded are the operators for scope resolution (::),
member selection (.), and member selection through a pointer to a function(.*). Overloading
assumes you specify a behaviour for an operator that acts on a user defined type and it can't
be used just with general pointers. The standard behavior of operators for built-in (primitive)
types cannot be changed by overloading, that is, you can't overload operator+(int,int).

The logic (boolean) operators have by the default a short-circuiting way of acting in
expressions with multiple boolean operations. This means that the expression:

if(a && b && c)

will not evaluate all three operations and will stop after a false one is found. This behavior
does not apply to operators that are overloaded by the programmer.

Even the simplest C++ application, like a "hello world" program, is using overloaded
operators. This is due to the use of this technique almost everywhere in the standard library
(STL). Actually the most basic operations in C++ are done with overloaded operators, the
IO(input/output) operators are overloaded versions of shift operators(<<, >>). Their use
comes naturally to many beginning programmers, but their implementation is not
straightforward. However a general format for overloading the input/output operators must

85
be known by any C++ developer. We will apply this general form to manage the input/output
for our Complex class:

friend ostream &operator<<(ostream &out, Complex c) //output


{
out<<"real part: "<<c.real<<"\n";
out<<"imag part: "<<c.imag<<"\n";
return out;
}
friend istream &operator>>(istream &in, Complex &c) //input
{
cout<<"enter real part:\n";
in>>c.real;
cout<<"enter imag part: \n";
in>>c.imag;
return in;
}

Notice the use of the friend keyword in order to access the private members in the above
implementations. The main distinction between them is that the operator>> may encounter
unexpected errors for incorrect input, which will make it fail sometimes because we haven't
handled the errors correctly. An important trick that can be seen in this general way of
overloading IO is the returning reference for iostream/ostream which is needed in order to
use them in a recursive manner:

Complex a(2,3);
Complex b(5.3,6);
cout<<a<<b;

10.4.2 Criticisms of Operator Overloading


Operator overloading has often been criticized because it allows programmers to reassign
the semantics of operators depending on the types of their operands. For example, the use
of the << in C++'s:
a << 1

shifts the bits in the variable a left by 1 bit if a is of an integer type, but if a is an output
stream then the above code will attempt to write a "1" to the stream. Because operator
overloading allows the original programmer to change the usual semantics of an operator
and to catch any subsequent programmers by surprise, it is considered good practice to use
operator overloading with care (the creators of Java decided not to use this feature, although
not necessarily for this reason).

Another, more subtle, issue with operators is that certain rules from mathematics can be
wrongly expected or unintentionally assumed. For example, the commutativity of + (i.e.
that a + b = = b + a) does not always apply; an example of this occurs when the operands
are strings, since + is commonly overloaded to perform a concatenation of strings (i.e. "bird"
+ "song" yields "birdsong", while "song" + "bird" yields "songbird").

A typical counter to this argument comes directly from mathematics: While + is


commutative on integers (and more generally any complex numbers), it is not commutative
for other "types" of variable. In practice, + is not associative even with floating-point values,

86
due to rounding errors. Another example: In mathematics, multiplication is commutative for
real and complex numbers but not commutative in matrix multiplication.

10.5 Conversion and Casting

A conversion (or cast) is just translation of a data value from one type to an equivalent value
in another type. int value 1 is equivalent to float 1.0 in Java: which is also equivalent to
double value 1.0d.
In Java, type casting rules that are applied to arithmetic expressions are:

i. If either operand is of type double, other types in automatically converted to


double in the expression and a double result is returned.
ii. Otherwise, if either operand is float, others are converted to float.
iii. Otherwise, if either operand is long, others are converted to long
iv. Otherwise, convert both operands to type int and compute an int result.

These rules also apply in C/C++, saving the programmer the tedium of explicitly converting
intermediate values in most arithmetic calculations.

Assignment conversion in Java has the following rules:

i. If the expression on the right has type byte, short, char, int, long or float; its value
may be “widened” to an equivalent double value
ii. If it is byte, short, char, int or long, it may be widened to a float value
iii. If it is byte, short, char, int widened to long value
iv. If byte, short, or char; widened to int
v. If byte or short; widened to char
vi. If byte, widened to short

The process of widening is the graceful conversion of a narrower type (set of values) to a
type that is a superset of those values. For example, all types are int’s but not all int’s are
bytes. Thus, in a division operation k = i / j, if k-type is double and result-type of i / j is int,
a widening will automatically be performed, which converts that result to double before it
is assigned to k.

On the reverse, if k is of int type and (i / j) is double, a “narrowing” conversion takes place,
in which information may be lost. The fractional part of 1.5d would be lost. A narrowing
conversion may be used in an assignment if all the following are true:

i. The expression on the right is a constant expression


ii. The type of the variable on the left is byte, short or char
iii. The value of the expression is representable in the type of the variable on the left

Because of strong static typing in Java, all errors of typing are detected at compile time.

Suppose k in k = i / j expression is of type int and i / j is double, a compile time (type) error
result. This is not the case for C/C++ and other languages, whose type systems are less
secure.

87
Explicit conversion from one type to another can be specified using the cast operator in the
expression int k = (int) ( i / j);

Here we override the warning that information may be lost, and we are saying it is okay to
go ahead and truncate that double quotient. What Java does that other languages typically
don’t do is force the programmer to explicitly override a negative consequence rather than
allow it to slip through until run time where the consequence might be much more difficult
to detect.

Summary

In this session, you have been introduced to the Concept of Overloading in C++ and Java.
The concepts of Conversion and Casting were also discussed

Self-Assessment Questions

1. Explain how function and operator overloadings occur in C++ and Java
2. What are the problems of operator overloading in programming languages

88
Study Session 11: Syntax and Semantics of Control
Statements in Real Languages
Expected Duration: 1 week or 2 contact hours

Introduction
Control statements are used to control the order of execution of statements in a program.
They are the basic building blocks of programs. The basic control structures or statements
are discussed in this session

Learning Outcomes

When you have studied this session, you should be able to explain how the following
control statements are written and used in programming languages:
11.1 for / while loops
1.3 Do statement
1.4 switch (case) statements
11.4 break and continue statements

11.1 for / while loops

for statement  for (Assignment 1opt ; Expopt ; Assignment 2opt) statement

The for and while loops have three parts, which serve to count how many times the statement
is executed. The first part initializes the counting variable via assignment, the second part
supplies in expression the condition for repeating the loop and the third specifies how the
counting variable is to be incremented after each repetition of statement.

i = initial;
These five lines can be compressed into
while (i <= final){ two
for (i= initial; i<=final; i = i +1)
S; s;

i = i + increment ; This is why for loop is widely used in


} // end while programming

1.5 Do statement

This loop performs its exit’s test after each iteration of the statement rather than before. The
while and for statements both test for continuing the loop before each iteration of the
statement. Thus, it is possible that the loop body will not be executed at all. Sometimes it is
useful for the body of the loop to be guaranteed at least one execution. Other reason for such
an occurrence is that the execution of the loop defines the initial value of the variable used
in the loop test.

Do stmt  do stmt while (expression);

89
1.6 switch (case) statements

Imperative languages provide a multi-way conditional test apart from the simple if statement

switch statement  switch (expression) { cases }


cases  case cases | default
case  caseHead cases | caseHead statement
casehead  case literal:
default  default : statements

The grammar states that a switch statement begins with the keyword switch, followed by an
expression in parenthesis, followed by a series of cases in braces.

The cases are ended by a default case (though optional in C-like languages). Each case
(including the default case) has a case head followed by a list of statements. The case head
for the default case consists of the keyword default followed by a colon; for the others, the
keyword case is followed by a literal and a colon.

switch (e) {
case v1: s1 if (e = = v1) s1;
case v2: s2 else if (e = = v2) s2;
. . .
. . .
. . .
case vn: sn else if (e = = vn) sn
default : sn + 1 else
} sn + 1

Note:
1. The case head may have more than one literal value associated with it and a
statement may be affected by a number of case heads.

2. Expression in an if-statement can be any Boolean-value expression; while in switch


statement, it must be an equality comparison whose second term is a literal. This
requirement can be guaranteed by the parser as it generates the abstract syntax.

11.4 break and continue statements

These statements allow the program to interrupt the normal flow of control inside a while,
for or switch statements.
Syntax:
Break  break;
Continue  continue;

11.4.1 Uses of break

1. To terminate the execution of a current case in a switch statement; so as to prevent


the flow of control from continuing into the next case.
2. To terminate a loop.

90
11.4.2 Uses of continue

A continue statement is used to terminate the current iteration with control, proceeding
directly to the loop test and beginning the next iteration. If the loop test is true, then the body
is again executed, else the loop terminated

Summary
The basic building blocks of computer programs were discussed in this Session. The
following control statements were explained: for / while loops, Do statement, switch (case)
statements and break and continue statements

Self-Assessment Questions

Write a program to compute the standard deviation of any n float data items stored in a one-
dimensional array of size n; using some suitable control structures.

91
Study Session 12: Scope, Visibility and Lifetime of
Variables
Expected Duration: 1 week or 2 contact hours

Introduction
Variables cannot just be declared or accessed anyhow in a program. In this Session, you
shall be introduced to the concepts of variables’ scope and visibility in computer
programming.

Learning Outcomes

When you have studied this session, you should be able to explain the following variable
scope concepts in programming languages:
12.1 Scope of Variables
12.2 Nested Functions
12.3 Uniqueness of Identifiers

12.1 Scope of Variables

The scope of a variable declaration is that collection of statement which can access that
variable. C-like languages (Java, C++, C#) and Pascal like (ADA), all use static scoping; in
which variable references can be resolved by an inspection of the source text of the program
without regard to its execution history. The static scope of a global variable includes all
statement in the statement in the program. The static scope of a local variable includes only
those statements inside the function/method where it is declared. Thus, scopes are either
disjoint or nested. Thus the same identifier can be reused inside different functions to name
different variables.

Also, a global variable can be re-declared inside a function. If a name declared in an outer
scope is re-defined in an inner scope, the new declaration ‘hides’ the outer declaration. A
name is visible in a statement if its scope includes that statement and the name is not hidden.
Some languages like Java provide a mechanism for referencing a hidden name; e.g. a hidden
class variable x, can be referred as this.x, where this refers to the current object.

What constitutes a scope varies from language to languages. Some programming languages
like Pascal allow scopes to be nested, so that static scope of a variable has a more complex
definition. However, Pascal allows function declaration to be nested. ALGOL allows any
compound statement to contain new declarations and hence, introduce a new scope in this
language, any compound statement which declared a new variable was termed a block. C-
like languages do not follow this principle. C does not allow function declarations to be
nested. So also Java. Given the following C-code to exchange two array elements

if ( A[i] > A [j] ) {


tnt t = A [i]; The scope of t is precisely the
A [i] = A [j]; body of the if statement
A[j] = t;
}

92
12.2 Nested Functions

PASCAL, MODULA and ADA, all permit the nesting of functions or procedures. Consider
the skeletal PASCAL program

program main; The reference to x in p3 and main refers to the


var x: integer; integer x declared in main, while the references
procedure p1; to x in p1 and p2 refer to the real (float) x,
var x: real; declared in p1. In these languages, procedures
procedure p2; and functions can be arbitrarily nested.
begin { p2 }
…x… Although Java does not allow nesting of
end; { p2 } methods, it does permits nesting of classes,
begin { p1 } which are referred to as inner classes.
…x…
end; { p1 } In a for loop, Java allows the initializer
procedure p3 statement to declare a new variable
begin { p3 }
…x… for (int i = …)
end; { p3 }
in this case, the scope of the variable is limited
begin { main } to the for statement itself,. Any reference to i
…x… after the for block is illegal.
end;

ADA also limits the scope of the for loop variable to the for statements, however, in ADA, the for
loop variable is implicitly and automatically declared.

12.3 Uniqueness of Identifiers

Early languages (FORTRAN, C and PASCAL) insisted that a locally defined identifier be unique in
its scope. In other words, an identifier could not be declared twice within the same scope. Later
languages, from ADA to Java permitted overloading of name, allowing multiple definitions of the
same identifiers within the same scope, so long as context could be used to distinguish which
declaration was being referenced. For example, Java allows within a class both instance variables
and methods to have the same name, since a method is normally followed by a parenthesis:

class overloading{
int name; // instance variable
int name ( ) {…] // a method

name = name ( ) // instance variable = method call

}

Java also permits methods overloading as long as the actual method invoked can be
determined by either the number or types of the parameters. Modula, a heir of Pascal does
not support overloading of names.

Summary
By now you must have known why variables cannot be accessed at some points in a program
due to the concept of scope in programming languages. Now answer the following question.

93
Self-Assessment Question

Consider the following program snippet:

class test {
int a = 6;
float j;
public static void main (String[ ] args) {

for (int a = 1; a< 5; a++) {


j = add(a);
…..
} // next a
}// end main
static int add (int [ ] demo, a) {
int j;
a++;
…..
return;
} // end method sum
} // end class

a) Using the above program snippet, explain the concepts of local and
global variable scope.
b) Using the above program snippet, explain how parameters are passed by
values and / or references
c) How is ‘a’ passed into the method/function add?
d) How is ‘demo’ passed into the method/function add?
e) How can we pass an array by value into a method/function?
f) What happens to the values of the variables passed by value and
reference after the execution of the method/function?
g) Using the above program snippet, explain how local scope can mask
a global scope in a program.

94
Study Session 13: Memory Management in Programs
Expected Duration: 1 week or 2 contact hours

Introduction
When programs are running, they make use of the RAM memory unit of the computer. The
program and data (Variables and their values) are co-resident in memory as long as the
program runs. In this Session, how variables are stored in memory during program’s
execution are discussed.

Learning Outcomes

When you have studied this session, you should be able to explain how the following
concepts are handled in programming languages:
13.1 Memory Management
13.2 Structure of Run-time Memory
13.3 Methods, Locals, Parameters and the Run-Time Stack
13.4 Argument – Parameter Linkage
13.5 Pointers
13.6 Arrays
13.7 Structures

13.1 Memory Management

Memory management is the process of binding values to memory, taking into consideration
both the static and the dynamic characteristics of these values. Values in programming
languages can be assigned to any of three different categories of memory: Static memory,
the run-time stack and the heap. Static memory is allocated to values whose storage
requirements are known before run-time and remain constant throughout the life of the
running program.

The run-time stack is the center of control for dispatching active methods (procedures and
functions), their local variables and their parameter – argument linkage, as they gain and
relinquish control to the caller. The heap is the least structured of the three memory
categories, and contains all other values that are dynamically allocated during the run-time
life of the program.

The structure of the run-time stack is predictable and regular. A ‘stack frame’ is pushed onto
the top of the stack whenever a method is called and popped from the stack at the time the
method returns control to the caller. The structure of the heap is far less predictable and
regular. The heap becomes fragmented as it is used for the dynamic allocation and de-
allocation of storage blocks.

At any point in time, the active memory blocks in the heap are not contiguous. Therefore
programming languages use “garbage collection” algorithms to manage the heap as blocks
of memory become unusable during the run of a program.

95
13.2 Structure of Run-time Memory

At run-time, memory divides into three parts – the static area, the run-time stack and the
heap.
0 Static
.
.
Area
a -1
a Stack

h

n
Heap
From the above figure, the stack is a contiguous region that grows and shrinks at one end
during run time. The heap is a region of storage whose active blocks are spread out from
each other in an unpredictable pattern during run-time. Heap blocks are accessed indirectly
using references called pointers, which appear either in the stack or elsewhere in the heap.

Initial space for the run-time stack and the heap is allocated in a way that reflects the
dynamic features of the program and remains inside the limits of that fixed block of
addresses (0 …. n), called the program’s address space. The size of the static area is fixed
before run-time, the top of the stack is marked by address a – 1 and the beginning of the
heap is marked by the address h. the following invariant relation must hold throughout the
program run, to avoid raising the stack overflow condition:

0 < = a <= h < n

The parameters h and n are initially defined at the beginning of run-time. Some programs
require very little predefined heap space, while others require a lot. Similarly, the maximum
stack size can vary among different programs, depending upon the maximum depth of
nested method calls that occur during the program run.

Allocations of variables in the static area and the run-time stack is serial, beginning at
address 0. At any time, during the run of a program, the range of active addresses in these
two areas is (0 … a – 1) where a is the number of active variables. Every variable value
takes exactly one addressable unit of memory, although this is not the usual case.

13.3 Methods, Locals, Parameters and the Run-Time Stack

Whenever a method is called, including the main method, a new set of “local declarations”
is allocated space on the run-time stack. This space is part of a block called a stack frame,
which remains active throughout the life of the call and then is relinquished to the system
when control returns to the caller. When a method calls another method, another stack frame
is pushed onto the stack. The stack frame contains spaces for the called method’s argument
values, local variables, a “static link” to the static area and a “dynamic link” to the stack
frame for the method that called this method.

96
Static Link | Dynamic Link
Argument values
Local variables

Structure of a called Method’s stack frame

At any time during program execution, the run time stack contains a frame for every method
whose call is still active at that time with the most recently called method’s frame at the top
of the stack.
Consider the following Java-like method segment:

package test {
int h, i;
void A (int x, int y) {
boolean i, j;
B (h);
…….
}
void B (int w) {
int j, k;
i = 2 * w;
w = w + 1;
……
}

void main ( ) {
int a, b;
h = 5; a= 3; b = 2;
A (a, b);
}
}

On calling the main, the static memory contains variables h and i; and a new stack frame is
pushed onto the stack with the variables a and b as shown in the left-hand part of the figure
below.

97
Static h undef h 5 h 5
Area i undef i undef i 10
| | |
Frame for
a 3 a 3 a 3
main
b 2 b 2 b 2
| |
Frame x 3 x 3
for A y 2 y 2
i i
undef undef
j j
undef Frame undef
for B |
w 5
j
undef
When A is called by main, another frame is created with A’s local variables (i and j) together
k
with the values of the arguments corresponding to parameters x and y (3 and 2). Finally,
undef
when B is called from A, a third frame is placed on the stack with an argument value for
parameter w. the first assignment within B therefore assigns the value 2 * w = 10 to the
static global variables i, which is reached through the static link in the stack frame for B.

13.4 Argument – Parameter Linkage

Arguments are “passed” from the call to called method. Arguments can be passed by
reference or by value. Passing an argument by value means that the value of the argument
is obtained at the time of the call and placed in a memory location for the corresponding
parameter. Examples are seen in the method calls A (a, b) from main ( ) and B (h) in method
A.

Passing an argument by references means that the address of the arguments (given by the
name of a simple variable, array or structure) is associated with the corresponding
parameter, so that the parameter becomes an indirect reference to the corresponding
argument. Thus all assignments to the parameter within the life of the call directly affect the
value of that variable, which is the argument.

For example, suppose the program above had the argument for parameter w inside method
B passed by reference rather than by value. Now, the assignment w = w + 1 inside B will
directly increment the value of h rather than a copy of their value inside B’s stack frame.

Passing by value is widely used in programming languages like C, C++, ADA and Java.
Passing by reference is used in cases when the actual value of the argument must be changed
during the life of the call. Passing by reference is also preferred when the argument passed
is not a scalar object, such as an array, a structure or an object. The main disadvantage of
this parameter passing by reference is that side effects on the original value of the argument
passed may not be desired by the caller.

98
Most languages have a means of distinguishing call by value from reference. In C++, an
ampersand & symbol is written to signal a reference parameter and its absence signals a
value parameter. For example, the code written before is re-written in C++ below:

void B (int& w) { //signifies a reference parameter


int j, k;
i = 2 * w;
w = w + 1;
}

The call from A would remain B (h). That is, the declaration of parameter w in B requires
that the argument in any call provide an address (the name of a variable, array or structure;
but not an expression with operators). The impact of declaring w by reference in this call is
to alter the value of h in the caller’s environment when the statement w = w + 1 is executed
inside method B. if w has not been called by reference, the value of h would not have been
altered by this statement.

If we pass an entire array in Java, we have done so by reference passing. However, if it is a


particular element in an index, say A[6], is passed, then we pass it by value. Java uses value
passing, but those which are reference types (arrays and objects that are members of classes)
are passed differently than those which are elementary types (byte, short, int, etc.).
Elementary types are passed by value while reference types are passed by associating a copy
of their references (address) with the parameter.

13.5 Pointers

Pointers are commonly used in C / C++ and ADA. A pointer is implemented at a memory
address or reference and provides a level of indirection in referencing a value or collection
of values that other data types do not. In C and others like, pointers are denoted by an asterisk
(*) and by an arrow () in a diagram of dynamic (stack and heap) memory.
Key next
Head 1 3 5 null
7

The diagram is a linked list of odd numbers. Each block is a node containing an integer key
and a pointer next. The pointer head refers to the first node in the list. To declare a node in
C, we write:

struct Node {
int key;
Node* next;
}
Node* head // initializes head as pointer to type Node

// Code to search a linked list for a value, say x


Node* p = head;
while (p != NULL && p  key != x)
p = p  next;

99
Pointers often complicate the proper implementation and management of data structures.
Languages that require the program to manage pointers to allocate dynamic heap data
structures also expect the program to properly restore heap blocks when they are no longer
used. This is the process of garbage collection.

13.6 Arrays

Arrays are ordered finite sequences of values of the same type. In general, array memory is
dynamically allocated at the time it is declared and its dimension become known. Array
declarations share the same scope rules as simple variables. In Java, arrays are treated like
objects, and so their elements are allocated space in either the static area, the run time stack
or the heap. All the elements in an array in Java are pre-initialized. Numeric types are set to
zero; chars are set to the UNICODE ‘\u0000’; arrays of objects’ references at NULL and
Booleans at FALSE. Programmers can also initialize the arrays with known elements, like

int [ ] [ ] X = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };

C, C++ and Java use the 0 – origin indexing for their arrays.

13.7 Structures

A structure or record structure is a collection of elements that do not share the same type;
and is distinguished from an array in this way. A Java class is comparable to C’s record /
struct structure.

C struct: Java class:


typedef struct { class employeeType {
int id; int id;
char [35] name; String name[ ] = new String [35];
int age; int age;
float salary; float salary;
char dept; char dept;
} employeeType; }

employeeType employee; employeeType employee;

Every field within a record structure may have a different type than the others, and the fields
have mutually unique names. A dot notation (.) is used to reference every field in a record.
For instance, employee.age is a qualified reference that identifies an individual employee’s
age. The type validity and semantic implications of structures are several.

(i) The names of fields with the structure must be mutually unique and the name of the
structure itself must be unique from that of any variable declared within the same
scope.
(ii) The name of a field referenced on the right of a dot must be among the field names
defined for the structure whose type is the variable referenced.
(iii)The type of each component must be compatible with that of any value assigned to
it. For example, the assignment: employee.age = y;

is valid only if age is a defined field of the record structure employeeType and the
type of variable y matches the type of that field.

100
(iv) The semantics of expression evaluation and assignment must be defined to allow
proper memory addressing for a qualified reference whenever it appears in an
expression or as the target of an assignment.

Summary

You have been introduced to how memory is being shared when programs are executed in
the RAM. The use of Pointers, Arrays and Structures were also discussed. Now answer the
following questions.

Self-Assessment Questions
1. With the aid of illustrating diagrams, describe how the memory is utilized by several
nested methods/functions when they are being executed in a program
2. Differentiate between arrays and record/structures as used in C-language.
3. Explain the semantic constraints on the use of structures in programs.

101
Study Session 14: Mobile Application Programming
Expected Duration: 1 week or 2 contact hours

Introduction
In this Session you will be briefly introduced to the rudiments of mobile application
programming.

Learning Outcomes

When you have studied this session, you should be able to explain the following concepts
in mobile application programming:
14.1 Application Programming
14.2 Mobile App Development Issues
14.3 Challenges

14.1 Application Programming

Application programming means the act of building (developing, creating) application


software for various computer devices to aid the tasks of human users. Application
programming is distinct from systems programming in that, while application programming
produces software that runs at a top level system software run at the low-level. By low-level,
it means that system applications interact directly with the hardware and make them work
whereas, the high-level application programs rely on system software to assist in
communicating with the hardware. Application programs by their names are software
written to be applied to human problems. Systems programs on the other hand are written
to control computer systems
.
There are three major platforms for which application programs can be built. These are:
a. Desktop: Desktop applications are built to run directly on a computer system. They
are installed on a computer an all data needed for their functionality resides fully
on the computer system. These types of computer applications were the first to be
created. Desktop applications could be command-line driven or GUI-driven.

b. Web-based: With the advent of the internet and the World Wide Web (WWW),
applications began to be developed that resided partly or totally on the internet.
They are referred to as online or web-based systems. Web based applications
generally work on a three-tier architecture consisting of the frontend, developed
with a mark-up language such as HTML, the Middleware, which carries the core
functionality of the system, developed with programming languages such as the
.NET family of languages, PHP, JSP, Python, Perl, JavaScript; the backend, which
is the database store, implemented in some relational database system such as MS-
SQL, MySQL, Oracle. A key component of the architecture is he webserver and
the browser which help to process and serve content to the user of the system.

c. Native Mobile: Of a more recent appearance are Native mobile applications. With
the advent of mobile devices came a new opportunity to develop applications for
the new and highly dynamic platform. The mobile applications share characteristics
of both Web-based and desktop applications.

102
A native mobile application is one which is designed specifically to run on the operating
system of mobile devices such as smart phones and tablets. These are different from
mobile web applications or mobile websites which are basically web applications or
websites which have been optimized for mobile view and run within a web browser on
the mobile device. The term mobile is used to indicate the type of device, but it also
means the context in which the user accesses the application i.e. in motion. This
understanding has consequences for the design of mobile applications. Native mobile
application (called ‘mobile app’ hereafter) development is an exciting but challenging
activity but there are several issues to consider in order to create applications that will
be useful to the end users and also efficient.

Today, mobile apps have become very popular important in the IT landscape as they are
being employed in increasingly in applications that cut across the whole spectra of
activities people engage in. The major platforms on which mobile apps run today are
Android, iOS, Windows Phone and Blackberry. Mobile app markets boasts of millions
of apps and continues to grow. As at May 2015, Statista.com reported that Google play
(the Android app market) had 1.5 million apps available for download, Apple’s app store
had 1.4 million, Amazon AppStore had 360 thousand, windows Phone store had 340
thousand and BlackBerry World had 130 thousand (Statista, 2015). Mobile app usage
continues to increase by leaps and bounds just as people continue to access the internet
more from mobile devices. It is therefore important to consider some of the issues related
to mobile app programming.

14.2 Mobile App Development Issues


(i) Platforms
The three major competing platforms for mobile app development are Apple’s iOS,
Google’s Android and Microsoft’s Windows Phone with Blackberry coming in closely
behind. Of the three major competitors, Android is the only open source platform as iOS
and Windows Phone remain proprietary.

Apple iOS
iOS is a proprietary operating system from Apple Inc. The current version of iOS is to
develop an iOS app, you need to use a machine running OS X. Apple provides an IDE
called Xcode that is used to develop the application. The iOS SDK provides extra
resources that are needed to complete the development. The programming language used
is objective-C.

Google Android
Developers can build Android apps on machines running windows or Linux. The latest
version of Android OS is Android 5.0 Lollipop as at 2015. Android Studio is the
propriety IDE from Google used for developing apps using Java programming language.
However, apps can also be created from the command line using the SDK provided.

Microsoft Windows Phone


Windows Phone is Microsoft proprietary OS for mobile devices. Currently at Windows
Phone 8 as at 2015. Apps are developed using Visual C# or Visual Basic.Net. Microsoft
also provides a supporting Windows Phone SDK and a power IDE, the Microsoft Visual
Studio.

103
Development Tools
OS Platform Current Programming IDE Others
OS language
version
1. Apple iOS Objective-C, Xcode iOS SDK
Ruby
2. Google Android Java Eclipse, Android
Android(Android 5.0 IntelliJ, APIs,
Developer, 2015) Lollipop Android SDK
Studio manager
3. Miscrosoft Windows Visual C#, Microsoft Windows
Windows Phone Phone 8 Visual Basic Visual Phone
.Net Studio SDK
2012
(ii) Design Patterns
Design patterns are solutions to design problems that occur over and over again in a
particular context. Design patterns describe the core solution without imposing a
particular sequence of implementation. Design patterns were first introduced by the
‘gang of four’ in their popular book ‘Design Patterns: Elements of Reusable Object-
Oriented Software’ which focused on object oriented development design patterns.

(a) Mobility Patterns

Jorg (2002) takes a leaf from the ‘gang of four’ and proposes a list of ‘mobility patterns’.
These are design patterns specially focused of problems that come up in mobile app
development. The mobility patterns are grouped into five classes, four sub-classes and
a total of twenty-one (21) patterns. The figure bellow shows the mobility patterns. Grey
boxes are classes while the white boxes are patterns.

104
Mobility Patterns (Jorg, 2002)
These patterns are described following the example of Gamma et al.(1995). The table below
gives a brief description of a few.

Table 14.1: List of some mobility patterns (Jorg, 2002)

105
(b) Mobile Interface Design Patterns

As discussed by Tranfici (2013, 2014), there are design patterns for mobile interface
design. The size of the mobile device is a major challenge that requires careful thought.
Common problems that developers often have to tackle are outlined along with
solutions.

Table 1: Mobile Interface Design Patterns

Design Pattern Description Solutions


1. Forms Forms are used to accept data 1. Keep the forms
from the user usually for login or elements to a minimum.
registration. 2. Allow users to use
existing profile
information e.g. from
social media accounts.
3. Keep form visible on
one page.
2. Searches Finding needed
information/items within the
app.
a. Scoped Users are provided the ability 1. Use easily recognizable
search to select categories within icons to depict categories.
which to perform their search.
b. Search The system provides
with auto- automatic suggestions as the
complete user begins to type a search
term
c. Saved and The system gives the user the
recent option of repeating a recent or
searches saved search term
3. Galleries Used to display items that are 1. Grids: arranged in table
frequently updated but mostly format. They help save
images/media. space.
2. Carousels &
Slideshows: images are
displayed one after the
other in a time controlled
display
4. Invitations They are used to explain the
features on an app to the user.
a. Tours Is similar to a demo that shows
the features of the app.
b. Persistent Messages that remain on the
Invitation screen telling users what to do in
s the current context.
c. discovera These are invitations that are
ble triggered bu a gesture such as a
Invitation swipe of the screen
s

106
d.Transpare These look like tours but they are
nt over laid on the users’ current
Invitations screen not in a separate demo.
5. Feedbacks Give information to a user on the
status of the application.
a. Error When there has been a problem 1. Should be clear and
messages visible.
2. Add a solution to the
problem
b. Confirmat Message of a completed action. 1. The message should
ion appear seamlessly in the
messages context not obstructively.
c. System Tells the current status of the 1. Use progress bars
status system , animated icon or
text messages
2.
6. Notifications Used to inform user of recent 1. Should be easy to
activity and new information. notice and understand.
7. Pop ups Can be used to display extra
information to the user. They
cover the current screen without
opening a new window. They are
popularly used for advertising.
It’s useful when you don’t want
the user to lose his current context
and it catches the user’s attention.
8. Contents Updates This pattern is used to show items Swipe to update is the
that are dynamic in nature such as most common solution.
news feeds. No button needed.
9. User Interactions Provide ways for users to 1. taps
communicate with your app 2. Swipes
3. pull downs

(iii) User Interface Design


Just as interface is important for any application, Mobile apps are no different. The
design of the user interface challenges the developer to make maximum use of the small
screen size in presenting the application.

The design of the interface is affected by the purpose of the application. With the screen
size being small, every part of the screen is potentially in front of the users gaze. While
this is an advantage for some types of mobile application, it might pose a negative point
in applications where the user needs to concentrate. The developer thus, must adapt the
design of his mobile app to fit the context of its use Apple Inc. (2013). Castledine et al.
(2011 pg.13) put it well by saying “Design is the process of organizing the information
we want to present so that its structure is meaningful and instantly understandable”.
Some ideas to consider are discussed in Apple Inc. (2013):

1. Aesthetic Integrity: The appearance of the app should be in consonance with its
purpose.

107
2. Consistency: Keep the user interface design internally consistent from page to page
and also externally consistent with what is ‘acceptable’ and ‘expected’ by the users.
This means sticking to general conventional standards/expectations of layout and
effect of gestures for example.

3. Direct Manipulation: Use direct manipulation of the device rather than separate
buttons to interact with the app. e.g. rotating the device to change screen orientation
instead of a menu/button.

4. Feedback: Give appropriate feedback for all actions and situations. Several
feedback methods are available, such as text, sound, highlights etc. the most
appropriate for the context should be chosen.

5. Metaphors: Metaphors use familiar knowledge from another domain to depict how
to interact with an app. For example, presenting app pages is a layered format to
signal swiping through as when flicking through a book.

6. User Control: Allow users to be in control of how and what the app does. The app
should not go out of control.

14.3 Challenges
König-Ries (2009) classifies the challenges of developing mobile apps into three categories:
architecture, data and context management and user interface. Jorg(2002) and Joorabchi et
al.(2013) cite issues such as multiple platforms, low computational power, low bandwidth,
small storage, wireless communication with other devices, security and heterogeneity of the
environment. These items can equally be mapped to the three categories above. The work
of Joorabchi et al. (2013) is particularly helpful in outlining some challenges faced by
mobile app developer viz:

1. Fragmentation: The variety of platforms pose challenges in the effort needed to


serve the same app to the different platforms. The platforms are sufficiently different
such that code can hardly be ported across platform for reuse and mostly have to be
recoded from scratch for each platform to ensure quality. The characteristics of
platforms that contribute to the fragmentation challenge include operating system
version, screen size. Developers face the challenge of maintaining several versions
of one app even on the same OS platform simply because of differences in OS
versions and screen sizes. Developers tend to do testing and maintenance for the
most popular devices.

2. Supporting tools for testing and analysis: Limited to no automated testing tools
and support team, hence testing is mostly manually and by the developer.

3. Open/Closed Platforms: having to work with propriety operating system platforms


such as iOS and Windows Phone is challenging as the access granted is not sufficient
at times. As for open source platforms like Android, which are open to modification
by everyone, challenges are faced when the set standards are not adhered to by, for
example, original equipment manufacturers.

108
4. Data management: When building data intensive apps the availability of storage
space poses a challenge as mobile devices have limited space and at the same time,
synchronizing data to an external data source is not very effective.

5. Frequent SDK updates: Mobile developers always have a lot of catching up do to


as there are frequent SDK and OS updates across all platforms to keep up with.
Therefore it is more realistic for companies to hire experts per the different platforms
which increases cost.

109
REFERENCES
Accenture. (2015). Mobile Application Development : Challenges and Best Practices.
Retrieved May 21, 2015, from
http://www.accenture.com/sitecollectiondocuments/pdf/accenture-mobile-
application-development-challenges-best-practices.pdf
Android Developer. (2015). Creating an Andriod Project. Retrieved from
htps://developer.android.com/trainings/basics/firstapp/creating-projectt.html
Allen Tucker and Robert Noonan (2002). Programming Languages Priciples and
Paradigms, McGraw-Hill Higher Education International Edition
Andrei Milea (2019). Operator Overloading in C++,
https://www.cprogramming.com/tutorial/operator_overloading.html
Apple Inc. (2013). iOS Human Interface Guidelines: Human Interface Principles.
Retrieved from
http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/mo
bilehig/Principles/Principles.html
Apple Inc. (2015). Start Developing ioS Apps Today. Retrieved June 16, 2015, from
https://developer.apple.com/library/GettingStarted/RoadmapiOS
Castledine, E., Eftos, M., & Wheeler, M. (2011). Build Mobile Websites and Apps for
Smart Devices. Collingwood: SitePoint Pty Ltd.
Clark, J. F. (2012). History of Mobile Applications. Retrieved from
www.uky.edu/~jclark/mas490apps/lectures.html
Didier R´emy (2019). Type systems for programming languages,
http://gallium.inria.fr/~remy/mpri/cours1.pdf
Functional Programming: ideal for algorithms,
https://www.ionos.com/digitalguide/websites/web-development/functional-
programming/
Gamma, E., Richard, H., Johnson, R., & Vlissides, J. (1995). Design Patterns: Elements of
Reusable Object-Oriented Software. Addison-Wesley Publishing.
Imperative programming: Overview of the oldest programming paradigm,
https://www.ionos.com/digitalguide/websites/web-development/imperative-
programming/
Java Polymorphism, https://www.programiz.com/java-programming/polymorphism
JAFFA Inc. Computer Learning Center, Where to type SQL statements in Microsoft
Access "2007", "2010", "2013" or Access
"2016" http://www.jaffainc.com/SQLStatementsInAccess.htm#Access2007, Accessed
June 2020
Joorabchi, M. E., Mesbah, A., & Kruchten, P. (2013). Real challenges in mobile app
development. In International Symposium on Empirical Software Engineering and
Measurement (pp. 15–24). doi:10.1109/ESEM.2013.9
Jorg, R. (2002). Patterns of Mobile Interaction. Personal and Ubiquitous Computing, 6(4),
282–289.
Kent D. Lee, Foundations of Programming Languages, 2nd Edition, Springer International
Publishing AG 2017.
König-Ries, B. (2009). Challenges in Mobile Application Development. It - Information
Technology, 51(2), 69–71. doi:10.1524/itit.2009.9055
Michelle Knight (2017). What is Structured Query Language (SQL)?
https://www.dataversity.net/structured-query-language-sql/#, Retrieved June 2020
Microsoft Developer Network. (2015). How to create your first app for Windows Phone 8.

110
MSDN. (2015). Moblie App Achetype. Retrieved from
blogs.msdn.com/b/jmeier/archiv/2008/11/24/application-architecture-diagrams-
added-to-codeplex.aspx
Microsoft Docs. https://docs.microsoft.com/en-us/previous-
versions/office/developer/office-
2007/bb208934(v=office.12)?redirectedfrom=MSDN, Accessed June 2020
Statista. (2015). Number of apps available in leading app stores as of may 2015. Retrieved
June 5, 2015, from www.statista.com/statistics/276623/number-of-apps-avaiable-in-
leading-apps-stores
Toal, R. (2015). what is Systems Programming? Retrieved February 11, 2015, from
cs.lmu.edu/~ray/notes/sysprog/
Tranfici, A. (2013). Examples of Mobile Design Patterns Part 1 and 2. Retrieved from
http://www.sitepoint.com/examples-mobile-design-patterns/
Tranfici, A. (2014). 5 Mobile Design Patterns for a Successful App. Retrieved May 21,
2015, from http://www.sitepoint.com/series/mobile-design-patterns/
Tutorial Point. C++ Overloading (Operator and Function)
https://www.tutorialspoint.com/cplusplus/cpp_overloading.htm
Tutorial Point. Why is operator overloading not supported by java?
https://www.tutorialspoint.com/why-is-operator-overloading-not-supported-by-java
W3Schools.com, SQL Tutorial, https://www.w3schools.com/sql/default.asp, Accessed
June 2020
Wikipedia https://en.wikipedia.org/wiki/Type_system
Zack Grossbart (2013). An Introduction To Programming Type Systems
https://www.smashingmagazine.com/2013/04/introduction-to-programming-type-
systems/

111

You might also like