CS441 Group Home Page
Contents

Home
UMKC Links
   UMKC
   SICE
   VU Home
   CS 441

eMail the group

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.