CS441 - Group Project #3
Comparison of
Block-Structured Procedural Languages to
- Object-oriented
- Functional
- Logic-based Languages
Marcus Garrett
Jeff Heckathorn
Tom Heffron
Sedric Hibler
Ali Wajid
Due Date:
November 25, 2002
History
Comparison
Marcus Garrett
versus Object-based
Block-structured, procedural languages were first established in
languages like ALGOL, and later evolved into Pascal. Block-structured, procedural languages are descendants of simple
procedural languages. Pascal introduced many advances to the block
structure style including the capability to define new data types
out of simpler, existing ones and dynamic data structures. Block-structured, procedural programming came from the concept of blocks
in a program. This concept allowed new static scopes to be defined
within executable codes. A major step in the evolution of
programming language was Pascal’s ability to run on the then new
Apple II personal computers. Upon creation, Pascal was to be used
primarily to teach programming in universities.
Bjarne Stroustrop created the language at Bell Laboratories in
1980 known as C++ whose predecessor is C. Although it is not an
entirely new language, C++ represents a significant extension of C's
abilities. C++ supports every wanted aspect and a significant
amount of the unwanted aspects of its predecessor. In general, the
language is a vast improvement on C and adds to its object-oriented programming capability. Because of the need for code
reusability, object-oriented languages have become some of the most commonly
used practical programming languages today. Although many today
attribute object-oriented programming with C++, many ideas of
object oriented programming were taken from Simula-67.
versus
Functional
Functional
programming language came from the need for a language which could
handle artificial intelligence. John McCarthy first developed the
first functional language LISP in the late 1950s at the
Massachusetts Institute of Technology. LISP programming systems
are interpreters. The Lisp language is rooted on the
representational power of "S-expressions" and use of functional
composition and recursion. LISP is a weakly-typed language which
is ideal for on-the-fly code generation and interpreting. Its
extreme flexibility, power, and its ability to treat code as data,
made it the ideal of Artificial Intelligence research during 1970s
and 1980s. Dozens of LISP implementations have been built over the
years, many of them were inspired by MacLISP. Eventually the
designers of the descendants of MacLISP convened and developed a
standard for LISP systems called Common LISP.
versus
Logic-based
Logic
programming is an approach to Computer Science in which the first
order predicate logic is used as a high level programming
language. The history of logic programming started with symbolic
logic, and then First Order Predicate Logic emerged from symbolic
logic to form the base for Logic Programming. Prolog is the most
viable and widely used Logic Language. Prolog (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.
Both the procedural, block-structured language and logic language
groups were developed in the late 1960's. Procedural,
block-structured languages were popular both the commercial
community and the scientific community. The languages where
designed to enhance productivity among programmers by reducing the
valuable and costly time required to write, test and debug
programs. An example of a block-structured, procedural language is
PASCAL. Logic languages were developed for AI (artificial
intelligence).
Overview Comparison
Marcus Garrett
versus Object-based
Block-structured, procedural languages
are designed more for programmer flexibility than absolute
run-time performance. They are widely used in business
applications. They possess activation records but employ scope
rules and nested block structures for structured data. Block
structured procedural programming uses the principles of
generality and orthogonality in its language design optimizing
good, verifiable programming structure and reliability of
algorithms. Pascal is the best representative of block-structured,
procedural language. Pascal added features that helped structure
code that improved the writing, reading, and maintenance of
programs.
The creators of C++ wanted to add object-oriented mechanisms
without sacrificing the efficiency and simplicity that made C so
popular. One of the driving principles for the language designers
was to hide complexity from the programmer, allowing them to focus
on the program’s abstraction. Because C++ retains C as a subset,
it gains many of the desired features of the C language such as
efficiency, closeness to the underlying machine hardware, and a
variety of built-in types. As new features such as constants,
inline expansion, references, declaration statements, user-defined
types, overloading, and the free store were added to C++ to make
the language more robust. Most of these features can be summarized
by two design goals: strong compiler type checking and a
user-extensible language. By implementing stricter type-checking,
the C++ compiler makes the programmer aware of data types in the
expressions. Stronger type checking is provided through several
mechanisms including function argument type checking, conversions,
and a few other features we will examine below.
C++ also allows programmers to create new types through the use of
classes. A class is a user-defined type that the compiler can
treat new types as if they are one of the built-in types. This is
one of the most powerful features of the language. The class also
provides data abstraction and encapsulation, which are the keys to
object-oriented programming.
Block structured and object-oriented programming languages are two
commonly used programming paradigms. Pascal and C++ have been used
extensively in educational institutions which emphasizes their
importance. Over the 1970s and 1980s, block-structured languages
became widely used, especially in the early days of the IBM PC and
the Macintosh. Presently, the significance of block-structured
style has been replaced by object-oriented languages because it make
allowances for all of the semantics found in block-structured
programs and offers greater control over the program.
Object-based references (for Sections 1 and 2):
1)
http://www.dacs.dtic.mil/databases/url/key.hts?keycode=237:267&islowerlevel=1
2)
http://diwww.epfl.ch/w3lco/pub/Newton/article.html
3)
http://www.cs.bsu.edu/homepages/dmz/cs335/ppt/pascal/ppframe.htm
4)
http://cgibin.erols.com/ziring/cgi-bin/cep/cep.pl?_get=epl_masterlist.phtml
5)
http://www.cs.bsu.edu/homepages/dmz/cs335/ppt/pascal/ppframe.htm
versus Functional
In the narrow sense, functional
languages are ones that operate by use of higher-order functions,
building operators that manipulate functions directly without ever
appearing to manipulate data. A functional language is a language
that supports and encourages programming in a functional sense.
Functional languages filled the need for use of algebraic
expressions through the use of programming languages for
artificial intelligence programming. The expressions in these
languages are formed by using functions to combine basic values.
The functional programming language style describes inputs and
outputs rather than the detail of algorithms. This feature is
great value when trying to run programs using parallel computing
architectures. Although functional languages originated to fill
need for an artificial intelligence programming, functional
languages have been introduced into other areas of application and
are now thought of as a general purpose programming language. The
power of the functional languages makes them ideal for writing
editing commands.
Functional languages address the programming constraints placed on
procedural block-structured languages by computer architecture.
Functional languages were designed on the model of mathematical
functions. All computation in a functional program is accomplished
by applying functions to arguments. Functional languages rely on
the relationship between components of a program, as well as
external libraries, subprograms, and functions. There is no
top-down sequence of commands in a functional language, but rather
a number of independent functions operate together to produce a
desired result.
Functional references (for Sections
1 and 2):
1)
http://www.cs.northwestern.edu/academics/courses/c25/readings/lisp-history.html
2)
http://www8.informatik.uni-erlangen.de/html/lisp-enter.html
3)
http://www.elwoodcorp.com/alu/table/history.htm
versus Logic-based
Logic 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 relations 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 would be greatly improved if several processors
are made to search different parts of the database.
Where logic languages were used to create innovative computer
systems, procedural, block-structured languages were used in the
academic realm. The structure of these languages provided for a
good learning base. There where some sacrifices that where made in
the development of these languages to make them easier to use and
understand, as well as learn. Because of this, these languages
where not at the same level of ability found in the logic
languages. Block-structured languages are sometimes thought of as
teachers' aids, where logic languages are sometimes thought of as
an intelligent assistant.
Logic-based references (for Sections 1
and 2):
1)
http://diwww.epfl.ch/w3lco/pub/Newton/article.html
2)
http://cgibin.erols.com/ziring/cgi-bin/cep/cep.pl?_get=epl_masterlist.phtml
3)
http://kti.ms.mff.cuni.cz/~bartak/prolog/intro.html
Handling of
Data Objects
Sedric
Hibler
versus Object-based
Block-structured and object-based
languages appear to have the same primitive data types.
Block-structured data types include integer, Boolean, string,
character,
real, array, record, and pointer variables. Object-based languages
carry the same
types with the exception of records and the addition of class
objects. There is strong
type checking in both languages. Both languages allow dynamic
binding. These languages also allow for static typing. One
difference in block-structured languages and object-based
languages is the fact that object-oriented languages support
inheritance. Exception handling is also a part of object-oriented
languages, but not in block-structured languages. A feature found
in some block-structured languages that is different from
object-based languages is how the array bounds are declared as
part of the type. Another notable detail is how object-based
languages use free unions. In comparison with block-structured
languages, discriminated unions are used. These unions can have
different types during the program execution.
versus Functional
Most older functional languages do not
use assignment statements or variables. There is more weight on
using lists, as used in artificial intelligence. Functional
languages are weakly-typed when compared to the strongly-typed
block-structured languages, yet these functional languages also
have better exception handling than those of block-structured. In
comparison to the block-structured languages, the, the data types
for functional languages are built from numbers, characters,
symbols and strings.
versus Logic-based
We find that both language
families allow dynamic binding (where data definitions can be
changed during program execution). Logic languages have strong
type checking at run time. Both languages can create dynamic
structures. A few of these logic-based languages carry data types
such as numbers, lists, and characters, Block-structured languages
are a strongly typed language, in contrast to logic-based
languages, which only have type checking at run time.
References:
1)
http://www.cs.bsu.edu/homepages/dmz/cs335/ppt/pascal/
2)
http://www.amzi.com/AdventureInProlog/advfrtop.htm
3)
http://t.students.umkc.edu/tehqnf/CS441/cs441proj1.htm
4)
http://t.students.umkc.edu/tehqnf/CS441/cs441proj2.htm
5)
http://y.students.umkc.edu/yl7e4/cs441/SIMULA.doc
6) Sebesta,
Robert. Concepts of Programming Languages, Sixth Edition.
Reading, Massachusetts: Addison-Wesley, 2001.
Handling of
Sequence Control
Jeff Heckathorn
versus
Object-based
The
block-structured, programming language semantics are based on
allowing data abstraction with separate blocks of program code
that can be accessed by other program blocks. Block-structured,
programming languages are in the larger class of procedural
languages, so that they have a great deal in common in their
sequence control semantics. Likewise the block-structured and
object-based languages have most of their sequence control
semantics in common, because they are both procedural language
types.
The languages used as examples from
Project 1 for block-structured (Modula-2, C), and object-based
(SIMULA, Smalltalk) all have some allowances for looping control
statements, with For and While loops. If-Then branching statements
and function calls.
versus
Functional
The functional
programming languages have their sequence control designed around
mathematical functions. These functions use recursion and
conditional expressions for control of flow. The example languages
of Scheme, and LISP have two basic sequence control elements. One
element controls two-way branching that includes If or For
selections. The second is a multiple selector COND function
allowing for multiple path function. The Functional language
semantics are different enough from the Block structured to make
direct comparison difficult.
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 block-structured,
procedural language family. At face value both families, when the
syntax is compared, have no recognizable sequence control
constructs in common. Prolog as an example of the logic-based
programming languages 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
Object-based
Looking at the
web pages created by other groups and ours, it appears that
block-structured procedural and object-based 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.
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. Block-structured languages, such as Modula-2, do not allow
functions to be overloaded. 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. Most object-based languages allow
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 language groups seem to
have strong support for recursion because sometimes problems can
be solved easily using recursion than using other method.
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.
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. On
the other hand, most 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
Functional
Block-structured, procedural and functional languages both support
subprograms. Block-structured procedural and functional languages
group both allow recursion for programmers. Functional languages,
such as scheme and lisp, allow complex functions to be constructed
by using set of primitive functions and functional forms. To
create subprograms in scheme, which is a functional language,
lambda syntactic form is used. Subprograms in functional languages
may include other subprograms. Subprograms in block-structured
procedural languages always have a name, but subprograms in
functional languages may or may not have a name.
As mentioned above, programmers have to free memory in
block-structured, procedural languages using keywords. Functional
languages, however, give more freedom to programmers as far as
memory management is concerned. In functional languages, such as
scheme, programmers do not have to explicitly deallocate objects.
Storage management system automatically takes care of freeing the
space once it determines that the object is no longer being used
in the program.
versus
Logic-based
Block-structured. procedural languages and logic-based languages
differ from each other when it comes to subprograms. In
logic-based languages, such as Prolog, subprograms are used to
describe logical relationships between facts. According to our
understanding, block-structured languages allow recursion in
subprograms. So, subprograms in block-structured languages are
allowed to call themselves. On the other hand, logic-based
languages have no support for recursion what so ever. So,
subprograms are not allowed to call themselves in logic-based
languages.
Block-structured 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.
Block-structured and logic-based languages both allow dynamic
allocation of memory. In block-structured languages, the
programmer has to take care of allocating memory and deallocating
it when it’s no longer in use. For example, Modula-2 and Pascal - from block-structured procedural group
- use keywords
new
and
delete
to allocate and deallocate memory. Logic-based languages use
garbage collection to handle storage management automatically.
Garbage collection gives programmer more flexibility and decreases
the chances of memory leaks.
References:
1)
http://t.students.umkc.edu/tehqnf/CS441/cs441proj1.htm
2)
http://t.students.umkc.edu/tehqnf/CS441/cs441proj2.htm
3)
http://www.scheme.com/csug/smgmt.html
4)
http://usuarios.lycos.es/ncabanes/modula2n.htm
5)
http://y.students.umkc.edu/yl7e4/cs441/SIMULA.doc
6)
http://k.students.umkc.edu/kmtvd3/CS441/CS441_PROJECT1.doc
7)
http://c.students.umkc.edu/cbdn92/REVISEDproject1.doc
8) Sebesta,
Robert. Concepts of Programming Languages, Sixth Edition.
Reading, Massachusetts: Addison-Wesley, 2001.
Handling of Abstraction and
Encapsulation
Tom Heffron
As described in
projects 1 and
2, block-structured, procedural
languages have the basic elements needed for data abstraction and
encapsulation – the ability to organize groups of statements into
a single compound statement – or code blocks. In project #2, we
saw how difficult it was to compare abstraction in simple,
procedural languages that, as a family, do not define support for
compound statements.
While the block-structured family includes support for compound
statements, not all languages in this family have all the
capabilities of full data abstraction. Some, such as Pascal and
ALGOL60, do not allow for new data elements to be declared within
a code block – effectively eliminating the scopes needed to hide
data. Also, as mentioned in project 2,
some languages in the block-structured family use static linking
to the encapsulated structure. This means that any change in data
declarations in the encapsulation requires a full recompile of all
linked libraries.
versus Object-based
The object-based family of languages seems to have learned from
the shortfalls of abstraction and encapsulation found in the
block-structured family. Although many of the object-based
languages get their roots from block-structured, procedural
languages and have an imperative design (Smalltalk being a notable
exception), this family incorporates much more robust methods of
data abstraction. This additional functionality includes:
Inheritance – the ability for a new ADT (derived class) to be
based upon an existing one (parent class) with a few
modifications.
• Overriding – the ability to create procedures with the same name
and protocol as existing methods. Thus, the derived class can
modify the parent’s method to be more appropriate for its objects.
• Polymorphism – the ability to create generic classes with
different attributes depending on the data type to be manipulated.
An example of this would be the generic stacks and list classes
created to handle any data type from the main program (integers,
floats, etc.).
Of course, encapsulation is an integral part of object-based data
abstraction. Most (all) object-based languages allow for
separately written, compiled, and linked files in order to keep
very large-scale projects organized.
versus Functional
One of the problems with comparing abstraction and encapsulation
in block-structured, procedural with that of functional languages
is that the power of abstraction in block-structured comes in its
ability to hide associated data and procedure declarations in to a
new, user-defined data type. By contrast, functional languages
focus more on the functions used to solve a problem. Therefore,
this family concentrates on the abstraction of its procedures.
Since functional languages are designed to mimic mathematical
functions, they are less concerned with the underlying
architecture of the hardware. They do not worry about abstracting
the individual tasks to abstract memory cell and register
movement. Most functional languages give a programmer the ability
to abstract some complex functions by defining a ‘feeder function’
that will redirect the data types passed to the function into
other detailed functions to perform the work.
Encapsulation is a bit of a non-issue in functional programming.
There is a logical organizational break between functions and each
is relatively self-contained. A programmer need only ensure that
any call to an ‘external’ function can be accessed by the program.
versus Logic-based
As with functional languages, it is difficult to directly compare
data abstraction in block-structured languages to logic-based
languages. Encapsulation in the logic-based family is simply a way
to expand its ‘world of knowledge’. This means that new
declarations and statements can be seen by a calling program in
order to solve a new problem. A programmer must be concerned that
any call to ‘external knowledge’ must be preceded with the name of
that module in which it resides – and the predicates will then
have direct access to the data in that module. Therefore, the
programmer must have direct access to the declarations of that
module – and data hiding becomes difficult.
References:
1)
http://c.students.umkc.edu/cbdn92/REVISEDproject1.doc
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.