CS441 - Group Project #2
Comparison of
Simple Procedural Languages to
- Block Structured Procedural
- Object-oriented, and
- Logic based Languages
Marcus Garrett
Jeff Heckathorn
Tom Heffron
Sedric Hibler
Ali Wajid
Due Date:
November 18, 2002
History
Comparison
Marcus Garrett
versus Block-structured
Procedural
Simple, procedural languages were created for people who didn’t have a
background in Computer Science but needed a way to program and
work on computers. Simple, procedural languages were easy to learn
and program. With this simplicity came their shortcomings. Simple,
procedural languages do not provide methods to handle complexity.
They were created and designed to be short programs that could run
on the less powerful computers of the time. Simple, procedural
languages were created to act as a stepping stone for novice
programmers. Later, with knowledge of simple, procedural languages,
programmers could progress to more complex and powerful languages.
Many people who began programming in simple, procedural languages
found that as they did progress to more complex languages, the
fundamentals of programming were inadequate. This served as a
major blemish for programming with simple, procedural languages.
Block-structured languages were originally designed for Computer
Science education. They got their name for their functionality
since the code could be broken up into blocks of program
statements. Over the 1970s and
1980s, block-structured languages became widely used, especially
in the early days of the IBM PC and the Apple Macintosh systems. In their
design, block-structured languages added the capability to define
new data types out of simpler existing ones. They supported
dynamic data structures - or data structures which can grow and
shrink while a program is running. This also added to the language
portability. Block-structured languages also didn't require a
large and expensive mainframe computer to run them. A major step
in the evolution of programming language was Pascal’s ability to
run on the then new Apple II personal computers.
versus
Object-based
Object-Oriented
programming began in the form of Simula 67, and later became the class
of programming language to which Java and C++ belong. SIMULA I and
Simula 67 were the two first object-oriented languages. The Simula
set of
languages were developed at the Norwegian Computing Center in Oslo,
Norway by Ole-Johan Dahl and Kristen Nygaard. Simula 67 created
the concept of a class, so that it would have the capability for
concurrency of objects rather than of tasks. It introduced most of
the main concepts of object-oriented programming - classes,
inheritance, and virtual procedures. These features, combined with
safe referencing and mechanisms for bringing into a program
collections of program structures described under a common class
heading, marked the semblance of Object-Oriented programming. Simula 67
is still being used today, but its main impact has been
in its introduction of one of the main categories of programming -
Object-Oriented programming.
Bjarne Stroustrup started his development of C++ (in the 1980s) by
bringing the key concepts of data abstraction found in Simula into the C programming
language. Simula has also inspired much of the work in the area of
program component reuse and the construction of program libraries.
Object-Oriented programming is today (as of the late 1990s) becoming
the dominant style for implementing complex programs with large
numbers of interacting components.
versus
Logic-based
Logic-based
programming is an approach to Computer Science in which first-order predicate logic is used as a high level programming
language. The history of logic-based programming started with symbolic
logic, and then First Order Predicate Logic emerged from symbolic
logic to form the base for logic-based programming. Prolog is the most
viable and widely used logic-based language. Prolog - short for PROgramming LOGic
-
was designed within the realm of Artificial Intelligence (AI). It
originally became popular with AI researchers, who are more
interested about
"what" and "how" intelligent behavior is achieved. The philosophy
behind it deals with the logical and declarative aspects. Prolog
represents a fundamentally new approach to computing and became a
serious competitor to LISP.
Overview Comparison
Marcus Garrett
versus Block-structured
Procedural
Simple, procedural languages were used
to create simple programs. As the programs got more complex it got
harder to program with these languages. Simple, procedural languages were the first languages to be
programmed at terminal displays, and not by punch cards. Early in
their inception,
operating systems had simple, procedural languages as its base code
(BASIC was used for a lot of O/S code in the 70’s). Simple, procedural languages were also used on the first smaller computers
its code structures were small in nature. As computers got more
powerful, programs that were written got more complex. Block-structured
languages were able to handle this complexity.
Application areas for block-structured languages took over any
programming projects started since their inception. All modern
programming languages use some form of a block structure. The
best known of the block-structured languages is Pascal and it served as a
teaching language to new Computer Science students at most
universities.. Some of the features of block-structured languages
are strong type checking, simple I/O facilities, a good set of
primitive data types, arrays, fixed and variant records,
conventional control structures, and simple dynamic memory
management. Block-structured languages were initially created to
handle complexity in larger programs that were being produced at
the time, and were also created to run on the
new microcomputers being built at the time. The similarity
between simple, procedural and block-structured languages are that
they were both designed to run on the early PCs.
Block-structured references (for Sections 1 and 2):
1)
http://home.cfl.rr.com/eaa/Languages.htm
2)
http://www.cs.uah.edu/~thinke/Cs524/Cs524slides/blockstructured.ppt
3)
http://www.daimi.aau.dk/~eernst/gbeta/tut15.html
4)
http://www.oberon.ch/docu/history.html#Pascal
versus Object-based
Simple, procedural languages and OO
languages have similarities in their design. The biggest difference is
that OO languages place more of an emphasis on encapsulation and
abstraction, and can be seen as more of an advanced typed
language. OO features that distinguish them from simple, procedural
languages are:
• Abstraction - Each object in the system serves as a model of an
abstract "actor" that can perform work, report on and change its
state, and 'communicate' with other objects in the system, without
revealing how these features are implemented. Processes, functions
or methods may also be so abstracted, and when they are, a variety
of techniques are required to extend an abstraction.
• Encapsulation - Also called "information hiding", this ensures
that objects cannot change the internal state of other objects in
unexpected ways; only the object's own internal methods are
allowed to access its state. Each type of object exposes an
interface to other objects that specifies how other objects may
interact with it.
• Polymorphism - References to and collections of objects may
contain objects of different types, and invoking a behavior on a
reference will produce the correct behavior for the actual type of
the referent. When it occurs at "run time", this latter feature is
called late binding or dynamic binding.
• Inheritance - Organizes and facilitates polymorphism and
encapsulation by permitting objects to be defined and created that
are specialized types of already-existing objects. This is
typically done by grouping objects into classes, and classes into
trees or lattices reflecting common behavior.
Object-based references (for Sections
1 and 2):
1)
http://www.wikipedia.org/wiki/Object-oriented_programming_language
2)
http://www.ifi.uio.no/~kristen/FORSKNINGSDOK_MAPPE/F_OO_start.html
3)
http://www.levenez.com/lang/
versus Logic-based
The simple, procedural languages came
about with the need to be able to handle simple mathematical
functions. Logic-based languages were designed to be able to handle
complex functions, but where not limited to only mathematical
expressions. Prolog is the highest level logic-based language
widely used today. It is taught with an emphasis on thinking of
the logical relationships between objects or entities relevant to
a given problem, rather than on procedural steps necessary to
solve it. The system in which it is programmed decides the way to
solve the problem, including the sequences of instructions that
the computer must go through to solve it. It is easier to say what
we want done and leave it to the computer to do it for us. Prolog
serves as an ideal prototyping language. It solves problems by
searching a knowledge base (or more correctly a database) which
can be greatly improved if several processors are made to search
different parts of the database.
Logic-based references (for Sections 1
and 2):
1)
http://www.research.avayalabs.com/user/wadler/topics/history.html
2)
http://www.csee.umbc.edu/331/resources/
3)
http://www.cs.iastate.edu/~leavens/ComS541.html
4)
http://www.site.uottawa.ca/~szpak/teaching/3125/handouts/03_History.ppt
Handling of
Data Objects
Sedric
Hibler
versus Block-structured
Procedural
Simple, procedural and block-structured
languages have many similar simple data types to go along
with their similar handling of data objects. Although some of these
types are referred to with different names, their functionality
remains the same. These generally
include integer, string, Boolean, real, character, pointers,
record, and some variations on these data type objects. Arrays of
these types are also supported. Variable types are labeled with
reserved keywords. In the first version of BASIC, the only data
type available was the floating point because they thought that
the users would only need numbers. In Modula-2, programmers were
allowed to define their own data types.
Both language classes require statically typed data, which means
that they must remain the same type that they are declared when
the program is executed. One exception that I found to this
generality was the fact that Pascal allows variant records. There
is no type checking done on this type because the variant part can be
omitted. Although the type cannot be changed in most cases, in
both language families the values may be modified during it execution.
Some block-structured languages, such as Pascal, use both static
and dynamic variable allocation while some simple, procedural
languages, such as FORTRAN only use static variable allocation.
versus Object-based
These two language classes handle data
objects similarly. The simple, procedural and object-based
languages use the following data types - integer, floating point, double
precision, real constants, characters, pointers, complex types,
logical types, and arrays. There are several simple, procedural
languages and (almost all) object-based languages include some
sort of user defined types. Generally, in both language classes,
only typed data is allowed, so that the type may not change after
it has been executed. Dynamic binding is also allowed in both
families - meaning variable definitions can be changed while a program is
running.
A higher level of objects is supported by the object-based
languages than the block-structured ones. One major characteristic
of object-based programming is its support for classes. Classes
can contain a list of variables of various types, which can be
used to model real "objects", with a type-description of its
attributes. Its support for inheritance will allow a new abstract
data type to inherit its properties from another defined data
type.
versus Logic-based
In general, these languages
support integers, floating points, characters, strings, real,
pointers, arrays and Boolean types. These variables can be
represented as character strings in both language classes. In
simple, procedural and logic-based languages, we find that they
both allow dynamic binding (where data definitions can be changed during program execution). One
exception noted was that Prolog's 'constants' values cannot change
during program execution, which is what their name means. We also
find that both languages can create dynamic structures.
In the logic-based programming family, we have found that they have strong
type checking at run time, yet they are better compared to those
of non-typed languages. In Eqlog, a logic-based language, subtypes
are allowed. This language is based on order sorted algebra, which allows
multiple data representations and automatic coercions between
them. Prolog is the most popular of logic-based languages. 'Terms' are
used to represent Prolog's data objects, which are comprised of
constants, variables, and other complex terms.
References:
1) http://www.afm.sbu.ac.uk/logic-prog/
2)
http://www.cs.ucsd.edu/users/goguen/sys/eqlog.html
3)
http://www.aquaphoenix.com/research/oop/lecture17.html
4)
http://m.students.umkc.edu/mkb5e9/CS441/project1.htm
5)
http://k.students.umkc.edu/kmtvd3/CS441/CS441_PROJECT1.doc
6)
http://y.students.umkc.edu/yl7e4/cs441/SIMULA.doc
7)
http://www.cs.indiana.edu/chezscheme/tspl2d/index.html
Handling of
Sequence Control
Jeff Heckathorn
versus
Block-structured Procedural
In general the
simple, procedural programming languages execute from the first
line of program code sequentially to the last. The simple,
procedural languages - as example FORTRAN and BASIC - both make
provisions for the sequence of code execution to be altered to
facilitate programming requirements that need to be fulfilled by
loops and the
GOTO branching statement. They both also support
functions - or subroutines that allow the program to return to the
point that called it.
The block-structured, procedural programming languages are
designed to execute in separate program blocks. In both the
example languages used in Project 1
(Modula-2 and C) the separate
blocks of program code can be separately compiled and used interchangeably.
So, the different program blocks can be used
by and in different programs over and over. Within these different
blocks the sequence control operates essentially the same as in
the simple, procedural languages.
Both language types treat the general mathematical operations in
essentially the same way, but with some minor differences in keywords
and syntax. Both types also support
if-then-else statements for
branching and logical flow of control. They also have looping
statements for repetition. The simple, procedural languages of
FORTRAN and BASIC have more of a semantic design for the use of
the GOTO branching statement to allow the flow of control
flexibility needed for many programming applications. The two
block-structured languages do not have the same acceptance of the
controversial GOTO statement. In Modula-2 the statement does not
exist and in C it is in the syntax but is not preferred. In
general the block-structured procedural languages are designed to use the
separate programming blocks - or procedures - to handle the same
sequence control issues that may be handled with the
GOTO
statement and function calls in simple, procedural language groups.
The simple, procedural and block-structured procedural language
types have most of their semantic properties in common - except for
the block-structured programming family’s use of separately compliable
program segments that make calls to each other during execution.
versus
Object-based
The
object-based programming language family handles sequence control
semantics in the same general way as simple, procedural languages.
The object-based languages are differentiated by their design to
allow the programming to declare user-defined variable types. This language
semantic has very little to do with the semantics of sequence
control.
versus
Logic-based
The logic-based
programming languages such as Prolog and Mercury have their
program execution based on first order predicate calculus. The
program execution is much different than the simple, procedural
language family. At face value both language types when the syntax
is compared have no recognizable sequence control constructs in
common. Prolog, as an example of the logic-based programming
style, uses
predicate statements and most sequence control is used with
recursive predicate statements.
References:
1)
http://t.students.umkc.edu/tehqnf/CS441/cs441proj1.htm
2)
http://m.students.umkc.edu/mkb5e9/CS441/project1.htm
3)
http://y.students.umkc.edu/yl7e4/cs441/SIMULA.doc
4)
http://k.students.umkc.edu/kmtvd3/CS441/CS441_PROJECT1.doc
5)
Luger, George. “Artificial Intelligence Structures and Strategies
for Complex Problem Solving” 4th edition 2002.
Handling of
Subprograms & Storage Management
Ali Wajid
versus
Block-structured Procedural
Looking at the
web pages created by other groups and ours, it appears that simple, procedural and block-structured
procedural languages both allow users to use subprograms to avoid
writing the same code again and again. Both families appear to
have built-in functions that programmer can make use of when
writing programs - they have to include the library in which those
built-in functions are defined and then the functions already
defined in the library can be easily use.
Both families seem to have languages that have different types of
subprograms. Subroutines are subprograms use to return more than
one value. According to our understanding, in addition to
functions, simple, procedural languages allow subroutines to be
written. On the other hand, block-structured procedural languages
seem to have subprograms that are similar to functions - which
can only return one value on each call made or not return a value
at all depending on return type.
Both families allow parameters to be passed as call-by-reference and
call-by-value. Parameters can be of any type that is already
defined either in the language of that group or by the programmer.
For example, parameters of type integer, char, string, etc are
allowed to be passed to functions or subroutines.
The user is not required to implement any storage management
techniques themselves in
simple, procedural language family. Simple, procedural language, such
as FORTRAN, only support
static allocation of variables. On the other hand, some of the
block-structured procedural
languages, such as Modula-2 and Pascal, allow dynamic allocation
and de-allocation of memory.
Modula-2 and Pascal use keywords
new and
dispose to allocate
and de-allocate memory.
When they are available, they are simply translated internally
into calls to allocate and
de-allocate.
versus
Object-based
Both functions
and procedures are supported in simple, procedural language family.
As
mentioned above, subroutines are also allowed in simple, procedural
languages. Similar to the
simple, procedural languages, the object-based languages
also have functions and
procedures in it. The object-based language group, however, is
much more advanced when it comes
to functions. Functions in object-based language group can be
defined as
public,
private, and
protected. Object-based language group also allows functions to be
overloaded. So, functions
can have same name but work on different data types depending on
the arguments passed to
the functions and their return type.
Both simple, procedural and object-based language groups have
built-in mathematical functions, and allow parameters
to be passed as call-by-reference and call-by-value. Parameters
can be of any type that is either language-defined or user-defined. For example, parameters of
type integer, char, string, etc are allowed to be passed to
both functions and subroutines.
Storage management for simple, procedural languages are
discussed above. Object-based languages give more flexibility to the programmer.
Some of the languages in this
group, such as Simula, tends to support automatic memory
management by implementing a garbage
collector that automatically frees the memory that has been allocated.
C++ on the other hand, which
also belongs to object-based language group does not support
automatic garbage collection, so
the programmer has to de-allocate memory using the keyword
delete.
versus
Logic-based
Simple,
procedural languages have two types of variables - namely
global and local. In Prolog, which belongs to logic-based language
family,
variables are visible everywhere in
the program. It does not matter where we declare variables in
Prolog, all variables work as global variables. Our understanding
is that all
variables can be seen and
changed by the code in the main program or by the subprograms.
Just like some of the simple,
procedural languages, such as FORTRAN, Prolog does not allow
recursion. So, in both languages
subprograms are not allowed to call themselves.
Logic-based languages also allow dynamic allocation of memory.
Garbage collection is also used in this language to handle storage management
automatically. Garbage
collection gives programmer more flexibility and decreases the
chances of memory leaks.
References:
1)
http://m.students.umkc.edu/mkb5e9/CS441/project1.htm
2)
http://usuarios.lycos.es/ncabanes/modula2n.htm
3)
http://t.students.umkc.edu/tehqnf/CS441/cs441proj1.htm
4)
http://y.students.umkc.edu/yl7e4/cs441/SIMULA.doc
5)
http://k.students.umkc.edu/kmtvd3/CS441/CS441_PROJECT1.doc
Handling of Abstraction and
Encapsulation
Tom Heffron
It is rather difficult to compare the
family of simple, procedural languages to any other family of
languages when it comes to abstraction and encapsulation. This is
because simple, procedural languages - as a family – generally do
not include support for compound statements. As the Sebesta text
discusses in Chapter 8, “Compound statements allow a collection of
statements to be abstracted to a single statement.” We could
extend this statement to say that “compound statements are
required for a collection of statements to be abstracted.” Without
these structures, particularly blocks to define different
execution scopes, there can be no hiding of data elements. All
data declarations must be in a single, large scope – and, thus,
seen throughout the program’s execution.
Encapsulation also largely depends on the use of compound
statements. Without code blocks and scope definitions, any
encapsulations would simply be like an automatic ‘cut-and-paste’
by the compiler. Even then, any call to code in the main program
must include a ‘GOTO’ statement in order to return to the calling
program. Also, variable names must be known by both the calling
program and the called code section – essentially, nullifying any
practical use of separate code segments.
versus Block-Structured Procedural
Most block-structured languages contain the basic structures
needed for encapsulation and data abstraction – code blocks. As
mentioned above, code blocks aid the programmer in organizing code
segments into reusable sections and allow a process – or group of
statements – to be represented as one call from the main program.
However, there are varying levels of abstraction and encapsulation
even among the block-structured family. For example, Pascal and
ALGOL60 allow for compound statements, but are not able to declare
new data elements within the statement group.
Also, different levels of data abstraction exits among the
block-structured languages. While some simply hide the
implementation details of subprograms in separately compiled code
sets, others actually have keyword that identify and enforce the
security of data variables. Some languages even take this one step
further by allowing for generic data types where an object is
instantiated with a particular subtype sent as a parameter during
object creation. Many students are familiar with this
functionality when programming a stack that can take any data type
during instantiation.
Also, some implementations of this family strictly limit the use
of data abstraction to pointer types. This allows changes to be
made to the encapsulated data type without requiring a recompile
of the calling program.
versus Object-based
The object-based language family offers examples of the best
usages of data abstraction and encapsulation into units called
classes. Most OOP languages incorporate all data types as ADTs.
Therefore, all data declarations are object instantiations.
Along with the full capabilities of encapsulation and data
abstraction, OO languages add the ability of inheritance from one
class to another – a requirement for a language to be categorized
as OO. Another ability of most OO languages is to create
polymorphic procedures. This allows a named procedure to behave
differently when different amounts and types of variables are
passed to it.
versus Logic-based
The logic programming family has many different levels of data
abstraction and encapsulation. Some, such as Prolog, were designed
and written at a time when the pure mathematical logic was the
focus in programming. Therefore, very large scale programming
projects and shareable, reusable code was not the focus of the
design.
In another design, Mercury seems to be designed specifically for
today’s very large scale programming projects. It includes the
ability to create ADTs. ADTs are implemented as modules in Mercury
and include only the ability to present data declarations and
predicates (procedures) to the calling module or hide them from
the calling program.
There does not seem to be an implementation of generic data types
in any of the logic family of languages.
References:
1)
http://m.students.umkc.edu/mkb5e9/CS441/project1.htm
2)
http://t.students.umkc.edu/tehqnf/CS441/cs441proj1.htm
3)
http://r.students.umkc.edu/rjjkr7/CS 441/project_1.htm
4)
http://y.students.umkc.edu/yl7e4/cs441/SIMULA.doc
5)
http://k.students.umkc.edu/kmtvd3/CS441/CS441_PROJECT1.doc
6) Louden, Kenneth C. Programming Languages Principles and
Practice. Boston: PWS Publishing Company, 1993.
7) Sebesta,
Robert. Concepts of Programming Languages, Fourth Edition.
Reading, Massachusetts: Addison-Wesley, 1999.