Project 2

Written By ChaoMing Amy Chiang, Chi Huynh, Wei Lu,
XiaoMei Yao.
More Part I is available at Wei's website.

History and Overview

Simple Procedural

Simple procedural languages were the first set of languages designed to allow programming at a higher level of abstraction than that of assembly languages. Initially, they were developed for use exclusively on systems with specific hardware configurations, but later were developed to be used on a multitude of platforms. Fortran (Formula Translator) was developed in 1957 by John Backus at IBM to be used on the IBM704 for the development of scientific applications. Shortly after, BASIC (Beginner’s All Purpose Symbolic Instruction Code) was created by John Kemeny and Thomas Kurtz at Portmouth College in 1964 for use on the G.E. 225. The original version of BASIC was very simple and had few control statements. However, because of its simplicity, it was very popular for use with personal computers in the 70s and 80s. In 1970, the language B was developed at Bell Laboratories, Inc. by K. C. Thompson. This, of course, evolved into the C programming language. One of the first cross-platform languages was ALGOL 58 (later ALGOL 60), which was developed by the Association for Computing Machinery and the Society for Applied Mathematics and Mechanics.

Simple procedural languages have a variety of uses, including simple scientific functions. BASIC and Visual Basic are used for everyday programs such as calculators, calendars, and even games. Fortran, on the other hand, is more suited for scientific purposes or mathematics. Fortran was a significant step towards all the programming languages we have today. C was a vast improvement over Fortran as it incorporated features from ALGOL and the CPL/BCPL/B languages. Programmers could still control hardware, but they had new tools like libraries of functions, powerful operators, and an elegant syntax.

Simple procedural languages first came to be in 1957 with FORTRAN, developed for scientific applications (numerical computing). FORTRAN designed by IBM for use on the IBM 704 systems. B is another simple procedural language. It was developed in 1970 by K. L. Thompson of Bell Telephone Laboratories, Inc. B was implemented such as system and language work. After few years, C was developed and replaced B.

Block Structured, procedural languages were first introduced in the 1970's. The first language that introduced was PASCAL. BCPL is another Block Structure, procedural language. Martin Richards implemented a simplified version of CPL called Basic CPL or BCPL. BCPL was in use in Cambridge for years. Both simple procedural and block structured procedural languages have a similar "block" structure - a main program and subprograms.

B is a descendant of the programming language BCPL. B was first designed and implemented by D. W. Ritchie and K. L. Thompson of Bell Telephone Laboratories, Inc., Murray Hill, N.J.  S.C. Johnson, also of Bell Labs, did the original implementation of the run-time package.

The development of B began in the late 1960s. It was to be used in conjunction with the UNIX operating system. The goal was to use a higher-level language, B, to build UNIX. PL/I was rejected for this purpose because it was deemed too cumbersome. Thompson had some previous experience with the BCPL systems language. He ruled out BCPL for use in UNIX development because he considered the language too low level and because it lacked run-time support. Thompson designed the language B as a minimal subset of BCPL for systems programming. The small space in which a compiler had to fit influenced the formation of B, and B was considered "BCPL squeezed into 8K bytes of memory." It is hard today to realize how strong a constraint limited memory size was only a few years ago. 

The Simple Procedural Block Structured Languages (SPBSLs) began with Pascal, invented by Niklaus Wirth. The SPLs, while inelegant, were popular due to run-time efficiency. Call-by-name parameters used by the SPLs were hard to implement, there was no input-output statement, since those were considered "implementation dependent" at the time, and own static storage was also difficult to implement. In addition, more modern practices like data types and structured programming were developing during the 1960s. 

Wirth's goal was to design a language that could be compiled in one pass, and a recursive descent parsing algorithm was used to develop the initial Pascal compiler. Pascal’s block structure was able to utilize sub-programs, enabling programs to run in a non-linear order. Wirth also later invented the MODULA series of programming languages, the next step in block-structured languages.

SPLs were designed to execute programs efficiently. Computers, costing in the millions of dollars, were the critical resource, whereas programmers, earning perhaps $10,000 annually, were a minor cost. Any high-level language had to be competitive with the execution behavior of hand-coded assembly language. They attempted to optimize the object program, the running time, because most people at that time believed you really couldn't do that kind of thing. They believed that machine-coded programs would be so terribly inefficient that it would be impractical for vary many applications.

SPBSLs were designed more for programmer flexibility than absolute run-time performance. These languages have activation records, but employ scope rules and nested block structure for storing and accessing data. In the SPLs, activation  records and scope rules are minimal, and run-time descriptors for structured data are not necessary. SPBSLs may require partial run-time descriptors for structured data. While SPBSLs execute efficiently, there is some run-time penalty for using these languages. 

Simple Procedural Languages were used for mathematics, by researchers, and by mathematicians. FORTRAN utilized the IBM 704’s floating-point hardware, which increased the speed of these operations dramatically. Before the development of FORTRAN,  floating-point operations  had to be simulated in software. Algol60 became the standard for the publication of algorithms in written text. SPLs such as B and FORTRAN, were originally designed to handle complex mathematical functions and arrays and were targeted primarily to the scientific and developer community. 

Because SPBSLs emphasize good and verifiable programming structure and reliability of algorithms, the SPBSLs are widely used in business applications. COBAL was designed specifically for the business community.  Additionally, SPBSLs like Pascal and Modula have been extensively used in the area of teaching computer science and programming. Pascal was the preferred language in the academic world, and was the most widely used language for teaching programming until recently. 

Like SPLs, SPBSLs have an overall “block” structure with subprograms to extend a main program. SPBSLs were introduced as an attempt to extend the SPL standard during the 1960s when computer hardware was increasing in speed and decreasing in cost.

SPLs and SPBSLs are generally implemented using traditional compiler technology. A text editor is used to create the program, a compiler translates the program into executable form, a linker is used to merge subprograms, the main program, and run-time library routines into one executable program, and an execution step executes the translated program. 

Block Structured, Procedural

Block structured, procedural languages were an extension of simple procedural languages. Whereas simple procedural languages were originally designed in the 1950's for scientific and business-based applications, block structured languages, such as Pascal, were developed later and used for programming in education and related areas. In 1971, Nicklaus Wirth combined the tools from the most powerful languages of the time and combined them to create Pascal, which was primarily a modified version of ALGOL 60. Wirth created this language with the intent of providing a language that was easy to teach and practical for writing system and application programs. His objective was to take some of the fundamental programming concepts that would be suitable for teaching programming and that would also be capable of efficient implementation on most computers. And because it followed the ANSI standards, it provided portability between platforms. The block-structured class of languages perpetuated the rise of sub-programs. That is, the class construct allowed for the execution of code in non-linear fashion.

Simple procedural languages were developed earlier than block structured languages and therefore took into consideration slow computers, high cost, and unreliable existing languages. Block structured procedural languages, however, were developed in the environment of existing, proven, high-level languages such as FORTRAN and ALGOL. This provided for more power and flexibility in developing the languages because of advancements in technology. However, the format of the two language groups is very similar. Both provide for a main program and subprograms.

Simple procedural languages first came to be in 1957 with FORTRAN, developed for scientific applications (numerical computing). FORTRAN designed by IBM for use on the IBM 704 system. B is another simple procedural language. It was developed in 1970 by  K. L. Thompson of Bell Telephone Laboratories, Inc. B was implemented such as system and language work. After few years, C developed and replaced B.

Object-based programming languages came much later than the earliest Simple Procedural languages. They were developed to exploit the object-based/object-oriented paradigm. They made their appearance around 1970 in the form of CLU. The first CLU implementation was done by Russ, Craig, and Alan. CLU provides linguistic support for data abstraction; it was the first implemented language to do so.

FORTRAN is still being used today. This is because it is still incredibly useful. FORTRAN has taken a back seat to a new generation of BASIC, and most people are using BASIC for creating easy to code, visual interfaces, where FORTRAN is best known for its scientific and mathematic uses. Fortran 66, a derivation of the original Fortran, boasts as the first language officially standardized by the American National Standards Institute (ANSI). Updated in the late 1970's, the international community adapted Fortran 77 as the International Standard of the International Standards Organization (ISO).

The American National Standards Institute continues to updates and coordinates the standards for Fortran, the latest version being called Fortran 95.

Developed in 1972 by a Dennis Ritchie at Bell Laboratories, C is a descendant of the CPL, BCPL, and B languages, as well as part of the ALGOL family of languages, which are of course descendants of Fortran.

C solved the typing problem of the UNIX based BCPL and B languages. During its initial 18-year evolution, many different implementers added new features as necessary to their particular application. In 1989, ANSI took all these features and produced an official description of C. Around the same time C was being developed as an improvement of a couple of languages.

C was a vast improvement over Fortran as it incorporated features from ALGOL and the CPL/BCPL/B languages. It is a procedural language meaning its programs are an ordered sequence of statements and procedure calls that are sequentially evaluated.

Programmers had new tools like libraries of functions, powerful operators, and an elegant syntax to control hardware. As the use of computers increased worldwide the demand for easier coding became inevitable and thus Object based Programming was developed.

The Object-Based languages came much later than the earliest Simple Procedural languages. They were developed to exploit the object-based/object-oriented paradigm. The need for an object-based language arose from the need for reuse and need for software to run large and complex systems on many different platforms. OOP(Object Oriented Programming) is a new development compared to simple procedural languages and for now, seems to be the most popular. Object based programs are best used when the programmer needs to create their own data type.

The object based programming languages Include languages such as Ada, C++, and Smalltalk. Smalltalk arose from the language SIMULA 67. 
 

The main aspect of simple procedural programming languages is the blocks. Every program written in a procedural programming languages must obey to the format of a main program and subprograms. In addition, some of the features of the procedural language are the use of block structure, passing of parameters by value and name, recursion, and stack-dynamic arrays. These are functions that have been adopted by several other languages and language families. Simple procedural languages have been mainly used for scientific computations and business purposes.

Object Based

Object based languages first came around in the form of SIMULA 67 (1977) but reached a more mature development in the Smalltalk language. Smalltalk is considered to be the purest object-based language of them all. The need for an object-based language arose from the need for reuse that programmers started to notice in the 1980s. It became clear that the best way to facilitate reuse was to use abstract data types and inheritance and Smalltalk was created to meet those objectives. Object-based languages became popular with CLU and C++, an object-oriented version of C developed in the late eighties. More recent object-based languages are Java and Delphi. The Eiffel programming language was created by Bertrand Meyer and developed by his company, Interactive Software Engineering (ISE) of Goleta, CA in 1985.

The progression of these languages has been very successful because of the re-usability of its code and the power of these languages. A major difference in the separation of simple procedural languages and object-based languages is the fact that the simple procedural languages were developed to be used in scientific applications and the object based languages were driven by both business and the Internet or the World Wide Web. Another major cause of the increased use of these languages is the ability to write procedures into separate modules and to re-use these libraries over and over again. This capability makes these languages increasingly more powerful.

Object-based languages are relatively new while procedural languages were the first high-level languages to be developed. While simple procedural languages were developed for mainly scientific and business purposes on slow machines, object-based languages seem to have been developed out of the need for the same software to run well on many different platforms and on relatively fast machines. This can be seen in Ada's development as the department of defense's universal language and Java's development for the purpose of networking and platform independence.

Logical

Early attempts at logic-based languages in the United States included Micro-Planner and Conniver. Both attempts failed to replace LISP as an artificial intelligence programming language because they were extremely inefficient. Prolog grew out of work on natural language processing done by Alain Colmerauer in Montréal and later in Marseille, and separate work on the use of logic for programming by Robert Kowalski at Imperial College, London. It was first implemented 1972 in ALGOL-W. Early collaboration between The University of Aix-Marseille and Kowalski (who had moved to the University of Edinburgh) continued until about 1975. The fact that Prolog overcame the problems that bedeviled Micro-Planner and Conniver is due to Kowalski’s work on the efficient implementation of Prolog.

Unlike the simple procedural languages, these languages are not used to write applications. Logical languages were developed with applications in artificial intelligence in mind. In order to make a computer capable of decisions based on given rules and the implications of those rules required a method to state and evaluate logical hypothesis and constructs. In other words, the goal of the program is defined and based on a set of given data and relationships the result is inferred. In a purely logical language no method to achieving the goal is inferred. This methodology is based on a form of logic called predicate calculus.

Simple procedural languages first came to be in 1957 with FORTRAN, developed for scientific applications (numerical computing). FORTRAN designed by IBM for use on the IBM 704 systems. B is another simple procedural language. It was developed in 1970 by K. L. Thompson of Bell Telephone Laboratories, Inc. B was implemented such as system and language work. After few years, C was developed and replaced B.

Logic programming began in the early 1970's as a direct outgrowth of earlier work in automatic theorem proving and artificial intelligence. The credit for the introduction of logic programming goes mainly to Kowaslski and Colmerauer, although Green and Hayes should be mentioned in this regard. In 1972, Kowalski and Colmerauer were led to the fundamental idea that logic can be used as a programming language. The acronym PROLOG (PROgramming in LOGic) was conceived and the first PROLOG interpreter was implemented in the language ALGOL-W by Roussel at Marseille in 1972.

Logic Programming is a paradigm in Computer Science, which originates from research on automatic theorem providing in the first half of this century. Robinson's (1965) Resolution Principle provides a firm basis for its development and the paradigm of Logic Programming is generally considered to be first proposed in (Kowalski 1974).

The term "Logic Programming" may refer to the programming in any logic, but conventionally it refers to programming in the Horn clause subset of first-order logic using the SLD-resolution, which was once called the LUSH-resolution (Hill 1974).

Logic Programs were first used for representing and analyzing subsets of natural language. It was this application which largely motivated Colmerauer and Roussel to develop the first PROLOG implementation. Soon afterward, other researchers in artificial intelligence readily found applications of their own, early examples of which were plan formation and compiler writing by Warren (1977), geometrical proofs by Welham (1976) and problem solving in mechanics by Bundy et al. (1979). In what follows, the programmers concentrate upon a selection of important classes of application: intelligent knowledge-based systems, database systems, expert systems and natural language processing systems. The reason for emphasizing these is that they are widely predicted to be the principal new applications of computers during next decade.

Intelligent Knowledge-Based System (IKBS) is systems, which apply intelligent reasoning mechanisms to explicit representations of knowledge. The IKBS fields have been identified by some applied artificial intelligence. Database systems, rule-based systems and expert system are distinct but overlapping examples of IKBS.

Conventional DBS have traditionally treated data as collections of relations stored extensionally in the form of tables. The relational model of databases has led to implementation of many queries systems through relational calculi providing standard relational operators such as joins and projections. The potential of logic programming for representing and querying databases was investigated in early studies by van Emden (1978), Kowalski (1978) and Tarnlund (1978), all of whom established the fundamental point that data retrireview in the conventional DBS model is intrinsic within the standard inference mechanisms of logic interpreters.

An expert system is a form of IKBS specially designed to emulate human expertise in some specific domain. Typically it will possess a rich knowledge base of facts, rules and heuristics about that domain, together with a capability for engaging in an interactive consultation with its user much as a human expert might. In additional it should be able to account to the user for any advices or decisions which it gives, and may also be able to improve its own skill through the experience of such interaction.

Natural language (NL) processing is of major importance to the development of tools for man - machine interfacing and to the construction of outer layers for IKBS in particular. It is therefore an important application area for logic programming. Computer implementation of natural language requires formalization of both its syntax and semantics. The use of Horn-clause logic for this purpose was first studied by Alain Colmerauer and subsequently in collaboration with Kowalski (1974).               
 

Handling Of Data Objects

Simple procedural, block structured and object based languages handle basic data objects in similar ways. All three language types generally support basic data types such as integers, reals, characters, Boolean, etc. Variables are declared using a reserved keyword that defines the type of data declared, followed by a variable name chosen by the programmer. Some later generations of simple procedural and block structured languages also feature more advanced predefined data types such as arrays, strings, and pointers. Object based languages are relatively new and have benefited from the knowledge gained through the development of other languages. Therefore, object based languages have supported these more advanced data types from their inception. The main advantage of object based languages over the other two is the ability of the programmer to define complex abstract data types, with characteristics and operations of their own design. However, the differences between these three languages become less distinct when more recent versions of simple procedural and block-structured languages are considered. For example, some simple procedural languages, such as ALGOL 60, and some block-structured languages, such as Modula 2, allow programmers to define their own data types. Additionally, the block-structure was first introduced in some simple procedural languages , such as part of ALGOL 60.

Also, most of the languages in all three categories support static typing, where a variable declared as a certain data type must remain of that type throughout the program’s execution, but most also allow for dynamic binding, meaning variable values can be changed during run time.

Simple procedural and block structured procedural languages are similar in that they use the same basic data types and operations.  These data types include integers, floating points, characters, and booleans.  The difference comes from the fact that block structured languages allow their sub-programs to have their own variables available in the limited scope of that sub-program.
 

Object based languages support a higher level of data objects than do simple procedural and block structured procedural languages. They are able to overlap simple procedural data types as well as heavily extend the lists and abilities of ADTs. This extension is implemented by the concept of classes. Classes extend the built-in capabilities of the languages to assist in the representation and solving complex, real-world problems. Inheritance (and multiple inheritance) is also used extensively in object-based languages. It allows a new abstract data type to inherit all the data and functionality of some already existing type. In this way, the programmer has the ability to add, delete or modify an existing type over and over again in a program. This greatly facilitates reuse in programs and makes coding easier and quicker.

Although the handling of data objects in simple procedural, block-structured procedural and object-based languages are similar, logical languages handle data objects very differently. Objects in logic programming propositions are represented by simple terms, which are either constants or variables. A constant is a symbol that represents an object. A variable is a symbol that can represent different objects at different times, although in a sense that is far closer to mathematics than the variables in an imperative programming language. Logical languages do not allow for the manipulation of data. To do so could invalidate the assumption that the given data is true. Instead they use the data and rules defined in their knowledge base to derive or verify other assumptions. Once proven true this new data can become a part of the library of facts allowing the program to "learn". Data in logical languages can be divided into facts and rules. Facts (or atoms) are statements or relationships that are assumed to be true. For example:

parent (cynthia, tom)
parent (jake, cynthia)

Rules describe new relationships that can be determined based on the facts already assumed. For example

grandparent (X, Z) :- parent (X, Y), parent (Y, Z)

This can be read "If X is parent Y and Y is parent Z, then X is grandparent Z". The right-hand-side of this expression is called the antecedent, and the left, the consequence. Typically the form of rules is limited in logical languages to HORN clauses where the consequence is limited to one term, but the antecedent can contain multiple terms that have a logical AND relationship. In this context X, Y, and Z are variables. The meaning of variables in a logical language is far different that in an interpretive language. Variable values are not directly assigned by the programmer. Instead they are deduced from the defined facts or inferred from other rules. This process is called instantiation. From the above data and rule, a logical language could infer the truth of grandparent (jake, tom).

It is important to note that there is no implied semantic meaning between the relationships parent or grandparent. Cynthia could be tom's parent, visa versa, or cynthia and tom could be a list of parents. The interpretation of these statements is left entirely up to the programmer. Lists are also supported in logical languages. Elements of lists can be atoms, rules, or other lists. Functions for creating, sampling, and dismantling lists are necessarily provided.

The simplest propositions, which are called atomic propositions, consist of compound terms. A compound term is one element of a mathematical relation, written in a form that has the appearance of mathematical function notation. A mathematical function is a mapping, which can be represented either as an expression or as a table or list of tuples. So compound terms are elements of the tabular definition of a function. A compound term is composed of two parts: a functor, which is the function symbol that names the relation, and an ordered list of parameters. A compound term with a single parameter is a 1-tuple; one with two parameters is a 2-tuple, and so forth.

Propositions can be stated in two modes: one in which the proposition is defined to be true, and one in which the truth of the proposition is something that is to be determined. IOW, stated facts or queries.

Simple procedural and object-based languages both use similar basic data types, but object based languages generally use more than just the basic ones offered in simple procedural languages.  On top of the extensive data types object-based languages allow for complex user defined data types typically called classes.  These classes each have there own operations defined within and other user defined methods.  These classes can be defined externally and reused in different programs.

Since object-based languages treat each data object basically the same this allows for increased readability and increased reliability.

 

Programming in logic programming languages is nonprocedural. Programs do not state exactly how a result is to be computed but rather describe the form of the result. The difference is that we assume the computer system can somehow determine how the result is to be gotten. What is needed to provide this capability for logic programming languages is a concise means of supplying the computer with both the relevant information and a method of inference for computing desirable results. Predicate calculus supplies the basic form of communication to the computer, and a proof method provides the inference technique.

Simple procedural and logic languages both us similar simple data objects.  These languages typically supported integers, floating points, characters, and strings.  Both language types can represent data objects variables as a string of characters.
 

 Handling of Sequence Control
 

Simple procedural languages execute statements sequentially as they are encountered in the program in a "top-down" manner. Block structured languages proceed in the same fashion, except they incorporate additional functionality that allows for interrupts in sequence control so that blocks of code stored outside of the primary block, or even in separate files, may be executed. The ability to execute different modules of code at various points in a program enhances the reliability and readability of a language but the sacrifice is the speed of execution. Both families provide looping mechanisms (while, for, do, etc..) and conditional branching (if, case, switch.). Unconditional branching (GOTO) is supported in both language types, but is discouraged in block structured.

As a general rule in block structured languages, anywhere one can use a simple statement, one can use a compound statement, which is just a number of simple or compound ones enclosed in some pair of block identifiers. The ability to replace single statements by complex ones at will is one thing that makes block structured languages much more versatile than simple procedural languages. Logic that requires several GOTOs and labels in simple procedural can be done in a simple, clear, natural way using the compound statements of block structured languages.

Simple procedural and block structured procedural languages both execute statements from top to bottom in the order that they are encountered.  They both allow for certain control statements like IF… THEN … ELSE and FOR loops.  Except block structured procedural languages allow for “jumps” to separate blocks of code which allows for an increased readability.
 

Object oriented languages also include all the traditional forms of sequence control statements as in simple procedural languages, such as loops and if-then-else statements. Though the language types are also similar the main difference is the handling of data. Simple procedural languages store all data inside global or local variables, which are manipulated at will. Object based languages branch control to a structure called a class that encapsulates many different types and methods, and jumps control around in this structure. This uses the idea of data encapsulation to allow the programmer to use code without actually knowing how it is implemented. These cohesive objects have little or no external dependence. Data stored inside the object is only changed through the interface methods provided by the object. This takes direct manipulation of the data away from the main program and gives that responsibility to the object.

Simple procedural languages execute statements from top to bottom in the order that they are encountered, while object-based allow for dynamic use of functions while lightly holding on to the top to bottom execution of statements.  The functions allow for a message passing communication, which can slow down operations.  Both of the language types make use of control statements, which can control execution of statements and induce iterations. 
 

In logic languages, the approach to sequence control is different. The system begins from data collected from databases and then tries to find matches leading to a goal (Forward Chaining). It can also start from a goal and work toward some original facts or set of rules (Backward Chaining). If a goal has got more than one structure in the solution, a depth first search is done because it takes less memory than the breadth first search. In depth first, a complete sequence of propositions for the first sub-goal are done before going to the next one. Breadth first search works on all sub-goals in parallel. Sequence control in logic languages is more complicated than in procedural languages. But in terms of efficiency, logic languages have more advantages than procedural languages in handling the sequence of control. Logic languages don’t have an If-Then statement or the while statement or the For loop. The programmer has very little or no control when using a logical language. All he does is express the desired result. The program then queries to determine if the result is true or false. Logical programming also requires no control flow directions. The statements for a logical program are generally a sequence of queries on a database of rules determined by the programmer. Programs in logical languages are resolved rather than executed. Once the facts and rules of a logical program have been established, the programmer can create goals or queries based on that information. Of course, logical operators such as AND, OR, and NOT are available.

Variables in the antecedent of rules are instantiated with matching facts or consequences in an attempt to verify the truth of the query. Of course, if the instantiation is the consequence of another rule, then the variables in that rule will have to under go the same process. In other words, the resolution of a query may require resolution of other queries initiated by rules found in the assumed information. This recursive process continues until the query is proved true for at least one instantiation, or until all avenues of analysis are exhausted. In an antecedent with many terms it may be necessary backtrack or throw away the instantiations of some terms when verification of the end terms do not follow. New instantiations of the first terms must be found and the process continues. In a large database with many rules and queries made up of conjunctive terms, this process can be quite time consuming.

Arithmetic operations in simple procedural, block-structured and object-based languages have the following precedence. Multiplication and division have the most precedence, followed by addition and subtraction. When two values of the same precedence are being evaluated, the order is from left to right. In addition, () can be added around an operation, allowing the operation inside the () to be carried out before the information inside is used in other operations. Conversely, logical programming languages do not generally support mathematical operations and so have no such precedence concerns.

Simple procedural languages execute statements quite simply, from top to bottom.  On the other hand, logic languages do not execute statements from top to bottom.  Logic languages, technically, do not have a sequence of control.  Logic languages are pure declarative languages, which means that they should execute all resolution paths concurrently in parallel.  These paths are not explicitly defined and it is assumed that the computer system can determine how to get the desired result.

 

Handling of Subprograms

Simple procedural languages support both functions and procedures. By definition, purely simple procedural languages must be executed in a line-by-line fashion with jumps to standalone subroutines or functions only when conditionals or function calls are encountered. Because of their scientific application, many functions are already provided for in simple procedural languages. These include mathematical functions, trig functions, character operations, and operations for complex numbers. Programmers are also allowed to define their own functions. Parameters can be passed-by-reference or passed-by-value. Some languages in the family may or may not allow recursion. For example, early versions of simple procedural languages do not allow recursion while ALGOL does.

Like simple procedural languages, block structured languages include line-by-line execution, and also feature explicit sub-program branching. Both types of languages allow pass-by-value and pass-by-reference parameters by using pointers in memory. As an example, BASIC uses a series of subprograms, referenced with GOSUB statements, which make the program essentially one big group of programs, executed conditionally. Block structured languages are able to pass multiple fields as a single parameter to subprograms, and can call that subprogram as a result of multiple action codes. One example of block structured programming languages is Pascal where procedures are set up as small independent Pascal programs, with variables defined locally and used within the scope of the procedure. Block-structured subprograms often allow recursion while simple procedural languages do not. In general, block structured languages support subprograms better and allow many more kinds of subprograms than simple procedural languages.

Both language groups are very similar in their use of subprograms and storage management.
They both use pass by value when passing parameters. Block structured languages for the most part also allow pass by reference. In the simple procedural languages, pass by reference was not used until it's introduction with FORTRAN. Type checking is done by both families and variables are statically allocated. Heaps are used in allocating memory when a subprogram is called and deallocated when no longer being used.

 

The object based family supports functions and procedures like the simple procedural languages, but are much more advanced. These subprograms can be defined in different ways such as public, private and protected, which helps to define the scope of the subprograms. Unlike simple procedural languages, object-based languages are designed so that subroutines can be declared as independent objects, thereby allowing such subroutines to be used in multiple applications and with a variety of data types. By prototyping the input and output parameters of all functions, object-oriented programmers are easily able to re-use previously developed subroutines. Typically, independent subprograms are implemented through a function call and appropriate input parameters. The classes in the object-based family contains functions, procedures and methods that can be used to define ADTs. Object based languages also offer dynamic binding of functions in those classes. Each program is called from the 'root' subprogram. This allows for easy additions of modules to the program, increasing the ease of development.

Unlike functions is simple procedural languages, object-based functions are encapsulated within an object. The environment is always ensured to be the environment of the object in which the function is encapsulated. Therefore, the environment is always as secure as the one the programmer has constructed within the object.

Object based languages use methods and subclasses as opposed to subprograms. These can be independent objects for reuseability, whereas simple procedural subprograms are generally written specifically for the program which calls it. It would be possible to copy a subprogram to another
simple procedural program however the programmer would be very limited since data abstraction is not used in the simple procedural languages. Object based languages provide information hiding and inheritance, using access modifiers such as those in C++ and JAVA to determine who can access the method or subclass. Both language families for the most part have local and global variable scope. While simple procedural will allow for nested subprograms, object based doesn't per se. Instead languages such as JAVA support inner classes which provide similar results.
Storage management is more volatile in the object based families, in many cases allowing users to have a say in how memory is allocated and given the responsibility of deallocating memory and resources when finished.
 

Logical languages are very different from procedural languages in reference to the handling of subprograms and storage management. For example, logical languages do not use any real subprograms and work differently from the top-down style of simple procedural. In logical languages, it is not procedures that are defined, but relationships. A declaration and assignment in a procedural language could be read as "A variable named 'x' of type 'y' exists and has been assigned the value 'z'". A logical declaration has the context "Element 'y' has the relationship 'z' to 'x'". In a way, the rules of logical languages can be thought of as procedures. Just as a procedure may call another procedure to return a value necessary for evaluation, a query may find a condition in a rule whose antecedent requires another query to be performed for evaluation.

 

Handling of Storage Management

In simple procedural languages, a symbolic name maps to a location in memory. The value at this location can be reassigned, copied to another location, used and modified in a function, etc. The value is variable and can be manipulated. It is the manipulation of values in memory locations that is the basis for interpreted languages. Simple procedural languages often use stacks during non-recursive function calls for storage. Unredeemed storage areas in these programs can often lead to serious problems. However, the user is not required to implement any storage management techniques themselves. It is possible to manipulate storage at a low level with the right functions. For example, C uses pointers as identifiers for dynamic memory allocation in the heap and creating linked data structures and PASCAL supports static and dynamic binding.

The programmer can have greater flexibility in storage management when it comes to object-based languages. The programmer has more precise control over how the data gets stored and deleted and can define garbage collection routines and individual storage. Object-based languages have many different ways to deal with storage management than simple procedural languages. For example, object-based languages like Smalltalk utilize a significant amount of dynamic storage allocation at execution time. This is different than typical simple procedural languages. These languages constantly monitor available system memory by de-allocating memory when memory is scarce and finding available memory when needed. In terms of storage management, most simple procedural languages and most object-based languages allow for both locally and globally defined variables. Also, both language classes allow for variables to be passed by value or by name. In addition, some object-based languages, such as Eiffel, feature automated garbage collection that can reclaim memory lost though pointer de-referencing.

Logic languages attempt to isolate the programmer from direct memory access. However, some languages, like Mercury, permit pointers. This is similar to the situation found with simple procedural languages where some languages discourage direct memory access and others allow pointers.

Logic programming doesn't have subprograms. They are declarative and nonprocedural. This means that the user is to specify what a program is to do but not how it is to do it. Therefore subprograms are not needed. A subprogram is generally a way of doing a specific task, as stated logic languages do not specify how to do tasks. Logic languages and simple procedural languages are similar in how they dynamically allocate memory.
 

Handling of Abstractions and Encapsulation

Neither simple procedural nor block structured languages support abstract data types directly, but simulation through to use of modularization can be used to emulate both. Simple procedural type languages emulate encapsulation with the use of subprograms. Unfortunately, this method provides poor encapsulation constructs. Block structured procedural type languages emulate encapsulation with the use of procedures and functions where local data is not available to the global program. Pascal, for instance, includes records as a form of data abstraction. All components of records are visible within all procedures that have access to the type of the record.

Later languages such as FORTRAN 77 do allow subprograms to be compiled separately and stored into libraries. It is the responsibility of the programmer to use the information hiding rules appropriately, since the languages have no automatic checks on violation of these principles.

Some block structured languages, such as C and Pascal, allow for prototyping of subroutines. This means that subroutine input and output parameters can be conveyed separately from their actual implementations through the use of pre conditions and post conditions. This form of encapsulation frees a programmer to utilize a subroutine without having to know the specifics of its designs. Block structured procedural languages such as PASCAL were more advanced in the area of abstraction and encapsulation. PASCAL allows for procedural and data abstraction, such as records. PASCAL also allows for the encapsulation of subprograms and the data they manipulate. In general, block structured procedural languages support a much higher level of data abstraction and encapsulation than the earlier simple procedural languages.

Subprograms (subroutines, functions) are a form of process abstraction supported in Fortran 77, Fortran 90/95 added modules. Process abstraction is the essential ability to abstract, or hide the details of the subprograms from the calling routine. All of the built-in data types of Fortran are abstract data types, and provide a means of creating variables of a given type and provides a set of arithmetic operations for their manipulation. Common blocks may be used to isolate global data to just a few subprograms needing that data.

Block structured procedural languages

Block structured procedural languages provide for better encapsulation and abstraction handling than do simple procedural languages, yet less than object based languages. They allow for Abstract Data Types for data objects as well as isolation of data objects for different procedures.

 

Most object-based languages take abstraction to another level by incorporating separate header file and implementation structures that allow for function prototyping. Also, object-based languages typically permit abstract class declarations. Object-oriented classes can then be encapsulated into separate files that may be reused in future application developments. In object oriented languages you can use abstraction to combine different components. This can not be done in simple procedural languages. In C++ problems can occur in abstraction when more than one data type is used. This does not happen in simple procedural because the data types of the subprograms are the same as the main program. Object-based languages were developed primarily for better encapsulation and abstraction of data. C++ allows for objects called classes, which encapsulate abstract data types and functions. The idea behind the creation of these objects is the emulation of real-world scenarios and, therefore, the solving of complex problems. Anything in the real world can be represented as an object and the functions that can be performed on that thing can be encapsulated within that object. The programmer doesn't even have to know the code or methods within an object. He only needs to know how to interface with the object.

In logic programming it is not needed for the programmer to see actual implementation. Instead he or she can deal with the systems whose implementation methods are abstracted. Logic based languages do not have the software principles for modules, types, and higher order programming and data abstraction. However, logic based languages can be said to use a high level of process abstraction. In process abstraction the details of how a process is to perform are not provided. The programmer needs to supply information following a set of rules, and ask questions - not worrying about the ways the rules must be applied to answer these questions.

Although logic programming languages offer many novel programming possibilities, they do not incorporate software principles of modules, types, higher order programming and data abstraction. Whereas in procedural languages, the possibility of using modules allow the incorporation of the abstraction notion. However, as seen before, both kinds of programming languages allow encapsulation to some extent.

 

References

   Kernighan, B. W. "A Tutorial Introduction to the Language B."

  S. C. Johnson and B. W. Kernighan “The programming language B”

  Robert W. Sebesta, Concepts of Programming Languages

Object-Oriented Languages: A Comparison © 1993-2001 Interactive Software Engineering.
http://www.eiffel.com/doc/manuals/technology/oo_comparison/index.html

Dictionary of Programming Languages. ©1997-99 Neal Ziring
http://cgibin.erols.com/ziring/cgi-bin/cep/cep.pl?%20%20get=epl%20%20masterlist.phtml

Eiffel: The Eiffel Page.
http://www-staff.mcs.uts.edu.au/~rist/eiffel/book.html

Sedlick, D., 2000. Prolog Say What? Discussion.
http://www.franken.de/users/nicklas/das/papers/prolog_description/discussi.html

Thompson, Ken. User's Reference to B, Internet Source, http://cm.bell-labs.com/cm/cs/who/dmr/kbman.html, 10/20/2000.

Johnson, S.C. User's Reference to B on MH-TSS, Internet Source, http://cm.bell-labs.com/cm/cs/who/dmr/bref.html, 10/20/2000.

Thinkage, Ltd., Thinkage UW Tools Package, Internet Source, http://ww.thinkage.on.ca/uwtools.html, 10/26/2000.

Sebesta, Robert W. Concepts of Programming Languages, 4th Ed., Addison Wesley Longman Inc., 1999.

http://webopedia.internet.com/TERM/F/FORTRAN.html

The FORTRAN Programming Language, Internet Source, http//www.engin.umd.umich.edu/CIS/course.des/cis400/fortran/fortran.html, 10/31/2000

http://www.ibiblio.org/pub/languages/fortran/ch1-1.html

Brader, Mark. Newsgroups: comp.lang.c. BCPL to B to C, Internet Source, http://www.lysator.liu.se/c/msb-on-b.html, 10/26/2000.