CS 441 Programming Languages: Design and Implementation |
Fall2003 |
|
|
||
Project #5 Group Members |
|
|
Name |
Personal Website |
|
Ahmad Ibrawish |
||
Afrazuddin Mohammad |
||
Neal Bellamy |
||
Nghi Phan |
Part #1: Simple Procedural and Functional |
History |
Simple Procedural Programming languages were first used to replace the machine code that was used at the time. Some of the languages in this group however were created much later. These programs like BASIC were created for non-Computer Science majors as a learning tool. Since the students using BASIC were not Computer Science majors the language was designed to be very simple. Functional programs were also created in early programming language history, although not quite as early as the first simple procedural language. The Functional language family takes a different approach to programming. The simple procedural languages are in general and imperative language whereas the Functional language group are functional.
|
Overview of Language (application areas, etc.) |
Simple procedural programming languages uses user defined data types and it also contains built-in data types and its application areas are more focus on the concept of doing a simple programming. Whereas the Functional languages make heavy use of recursion and it is based on the concept of mathematical functions. Because of its ability to do function argument statements and doesn’t use variables like in Simple procedural languages, its primary application area is in Artificial Intelligence (AI).
|
Handling of data objects |
Simple procedural languages has many data objects like integer, Float, ASCII, etc. Some of these languages have very strong typing, others are type-less. The type checking also varies in this language family some do no type checking at all, like Assembler, while others check and enforce all conversions, like C. Some languages do automatic conversions when 2 differing types are compared or have math applied to them like BASIC, others do no conversions at all leaving it to the programmer, like Assembler. Most simple procedural languages doe not use scope. In general the simple procedural languages use concepts like creating and assigning a value to variables, while a purely Functional language does not. The Functional language use data objects as well but in a different way. These languages tend to have only 2 data objects, an atom, and a list of atoms or other lists. An atom can contain any number of different values. Some allow any combination of numbers, letter, and special characters. Usually the atoms are used to find matches as in YACC, which looks for input from a lexical analyzer to decide what function(s) to perform. In General like Simple procedural languages, the functional languages do not use the idea of scope.
|
Handling of sequence control |
The handling of sequence control for the Functional language has a simple sequence control structure that is implicit to that of LISP and it does not use either assignment statements or variables unlike Simple procedural. The other differences between Functional and Simple procedural languages are that Functional doesn’t use repetition (such as while or for) but instead it uses recursion for doing repetition.
|
Handling of Subprograms and Storage Management |
Simple Procedural Languages use sub-programs or functions. In most they do not need to be declared before use. Most Simple procedural languages do not pass parameters to functions but have global variables to be accessed within the sub-programs. Recursive sub-programs are allowed but it is up to the programmer to ensure the variables are not overwritten by later or deeper calls. Simple procedural languages either do not implement garbage collection at all, like Assembler, or use it completely behind the scenes like BASIC. Some of these languages do not provide any built-in support for storage management, leaving all issues to the programmer. While others like BASIC perform all storage management features automatically and invisibly. Functional languages also use sub-programs, in fact most of the control flow of the functional program comes from the calls to sub-programs. Unlike simple procedural languages most functional language do use parameter passing. Recursion is one of the most used cases in functional language programs, and as such, is support directly by most of the languages. Functional languages perform garbage collection and memory management automatically with no user intervention needed. Because of the recursive nature of these programs, garbage collection is a very high need in the functional language groups.
|
Handling of abstraction and encapsulation |
Handling of abstraction and encapsulation for Functional languages is not possible due to the fact that it doesn’t support much data structure and also lack the objects for handling abstraction and encapsulation. Also, to be able to handle abstraction and encapsulation it has to have classes, which Functional languages is lack of. Simple procedural on the other hand has some ability to handle abstraction and encapsulation. One special feature of the Simple procedural language is that it can handle the variables from different memory location. Simple procedural can have its variables to be set to either from the global or to the local location.
|
Part #2: Functional and Logic Based |
History |
Functional: The first functional programming language was invented to provide language features for list processing, a need that grew out of the first applications of artificial intelligence (AI). Functional languages include languages such as YACC and LISP. The development of this language group was originally driven by its uses in Artificial Intelligence and in creating compilers. It is primarily list based and it was written so that it may make use of mathematical functions to the greatest extent possible. YACC was a functional language that was a major tool in the development of compilers. LISP on the other hand was considered the first functional programming language. It was originally developed to create a language that closely resembled English and that a computer could use to resolve problems and a self-reference, however its primary use now is in the field of Artificial Intelligence. 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. Logic programming is the use of a formal logic notation in attempt to communicate computational processes to a machine. Predicate calculus is the notation used in current logic programming. 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. Prolog (Logic Based) was developed some time later than LISP and was a huge competitor for LISP because it represented a new approach to programming. It soon became one of the most widely used languages for Artificial Intelligence. The early developments of the logic-based languages such as Micro-Planner and Conniver were unable to replace LISP as the major Artificial Intelligence language because they were extremely inefficient. Although these two language groups had different approaches in their developments, the reasons for their developments were very similar. Both of these languages now have a primary function centered on Artificial Intelligence. They are similar in the fact that they were created to apply to artificial intelligence. They both currently compete against each other in the realm of artificial intelligence. Functional programming languages are based on the lambda-calculus where as Logic programming is based in first order predicate logic. Alonzo Church and Stephen Kleene created lambda-calculus out of an attempt in the early 1930s to formalize the notion of computability. It is a formalization of the notion of functions as rules. As with mathematical expressions, it is characterized by the principle that the value of an expression depends only on the values of its sub expressions. It is a simple language with few constructs and simple semantics but is sufficiently powerful to express all computable function.
|
Overview of Language (application areas, etc.) |
Functional Languages coupled with the need of language features such as list processing, functional programming provides expressiveness, power, correctness proofs, rapid prototyping and symbolic applications. The objective of the design of a functional programming language is to mimic mathematical functions to the greatest extent possible. A functional language provides a set of primitive functions, a set of functional forms to construct complex functions from those primitive functions, a function application operation, and some structure(s) for storing data. This type of programming describes all computer operations as mathematical functions on inputs. A well-defined functional language requires only a small number of primitive functions. Primarily, these languages are used for artificial intelligence (AI) and list processing applications. 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. Logic based programming has been categorized as a declarative language. Its main objective in logic is to enhance the research and the development of artificial intelligence and manage database systems. It is being used in the Artificial Intelligence field because of its ability to use its processes to determine the most correct result. A logic programming language is a rule based language, where rules are specified in no particular order. Logic languages are called declarative because logic programs consist of declarations rather than assignments and flow control statements. Logic semantics are called declarative semantics. Their basic concept is that there is a simple way to determine the meaning of each statement, and it does not depend on how the statement might be used to solve a problem. Logic programs, based primarily on predicate calculus, state the specifications of desired results, not the process to obtain the results. Because of the ability to use its processes to determine the most correct result, logic programming is used in AI. Its main objective is to enhance research and development of AI and managing database systems. In Logic Programming, programs are theories and computation is deduction from the theory. The goals of programming in Logic are first obtaining a problem description. Next you define the intended model of interpretation (domains, symbols etc). Then you devise a suitable theory (the logic component) suitably restricted so as to have an efficient proof procedure. Thereafter describe the control component of the program. Lastly, you use declarative debugging to isolate errors in definitions. 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. Functional languages and Logic languages have also been developed for scientific computing applications. The main reason to use functional languages for this class of application is the very straightforward parallelization of functional programs, which outweighs the loss of efficiency that a functional program often experiences from their more costly evaluation mechanisms and memory requirements. Logic programming is one of the principal paradigms for declarative reasoning. This separates the specification of what has to be solved from the control information that aids the search for a solution. |
Handling of data objects |
As in most programming languages there exist the basic package of handling data. More specifically to Functional Programming there exist an approach of object-oriented proportions and maybe the user want to delay evaluations of certain objects and the user even has the options of using certain data specific methods provided via a language i.e. congruential methods. Similarly …… Pure functional languages do not use variables or assignment statements. The variable type is not determined at compile time but during evaluations of expressions, allowing the programmer to not be concerned with memory. Most do, however, retain some notion of variable and assignment, and so are “impure”, but it is still possible to program effectively using the pure approach. Functional language programs are function definitions and function application specifications, which support reusing code and come with a large number of predefined functions. Most of these languages are typeless (although ML is strongly typed). Traditional functional languages have two data types consisting of atoms, numeric identifiers or the symbols used in LISP, and lists. Symbols and vectors are also supported. Functional based languages generally use the following data types with their data objects: integer, real, characters, strings, doubles, and Boolean. From these types, arrays, user-defined types, records, sets, and hash tables can be used as well. Multi dimensional arrays, variant records and read tables are also visible on some functional languages. Functional languages are type-less (in general) and the value of an object is determined during the execution of the program. Lists are the primary structure of functional languages. Logic based Programming solves the task of handling data objects by using general-purpose set constructs and basic operations on sets which are inserted into some general logic-based framework: pure logic programming languages, equational logic languages, and Constraint Logic Programming (CLP) languages. Logic-based languages allow the use of terms constructed from constants, which are usually integers, variables, which are strings, and structures, which can be groups of both. Each term has different rules as to how characters are put together to form its name. The approach of logic programming is to use as a database a collection of facts and rules that state relationships between facts, and to use an automatic referencing process to check the validity of new propositions. Because of its area of applications and its basis in predicate calculus, a logic language’s data objects contain a database of predicates, rule statements and facts. They have few primitive data types, relying more on user defined data types. Logic languages such as PROLOG support data objects such as constants, logical variables, and lists grouped in what we call “facts”. Variables serve as a means of data compression. Logic languages also have the ability to assign dynamic values at run-time. logic based languages tend to support integers, real numbers, strings, pointers, records and some user defined types. Logic-based languages also allow dynamic binding (where data definitions can be changed during program execution), with the exception of the constants in Prolog. Logic languages can create dynamic structures. In the logic-based programming family, we have found that they have strong type checking at run time (unlike the Functional Languages), yet they are better compared to those of non-typed languages. In Eqlog, a logic-based language, subtypes are allowed. This language is based on order-sorted algebra, which allows multiple data representations and automatic coercions between them. Prolog is the most popular of logic-based languages. 'Terms' are used to represent Prolog's data objects, which are comprised of constants, variables, and other complex terms. |
Handling of sequence control |
Functional programming languages, which are based on mathematical functions, is the design basis for one of the most important non imperative styles of languages. Programming is supported by functional or applicative programming languages, therefore it is based on recursion and conditional expressions. Functional programming languages such as LISP use arrays and linked lists to handle sequence control. 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 Simple Procedural to make direct comparison difficult. The difference between functional programs and logic programs, logic programs should be nonprocedural, which means that the characteristics of the solution are given but the complete process of getting the solution is not. In logic languages such as Prolog, there are two opposite approaches to attempting to match a given goal to a fact in the database. The system can begin with the facts and rules of the database and attempt to find a sequence of matches that lead to the goal. This approach is called bottom-up resolution, or forward chaining. The alternative is to begin with the goal and attempt to find a sequence of matching propositions that lead to some set of original facts in the database. This approach is called top-down resolution, or backward chaining. Although these methods are more complex than functional languages, they have more efficiency than functional languages. The logic-based programming languages such as Prolog and Mercury have their program execution based on first order predicate calculus. Prolog, as an example of the logic-based programming style, uses predicate statements and most sequence control is done with recursive predicate statements. The functional based programming languages share much of the same sequence control semantics with the logic-based languages. Both use recursion for iterative control. Though the example languages of prolog and mercury do not have a multi path conditional such as in LISP. |
Handling of Subprograms and Storage Management |
Functional programs are essentially a collection of subprograms, both within a main program and stored in external libraries or files. Control passes between these subprograms and external modules throughout runtime. The functional language family supports subprograms in the form of both functions and procedures to perform instructions or to return values. The functional language family supports built in data types and programmer defined types as well as static and dynamic types. Since there are no subprograms in Logic-Based languages, it is difficult to create modular programs. The programmer must also be very affluent in all of the types of data structures available with the languages and how to use them properly. However, if the subprogram is defined as a programming segment that takes a parameter and returns a value to a return address, namely a predicate. Logic-based generally languages don't feature subprogram implementation because they are not developed algorithmically. Logic-Based languages do not allow for dynamic storage management at run-time. This might reduce the probability of making errors using pointers and other structures, but also limits the flexibility of memory management. In Functional languages memory management is done by the software language. This makes efficient memory management. One difference between the two is storage management. The functional language supports automatic garbage collection by the compiler. Once a pointer or other storage becomes deallocated then the data is automatically put back on the heap. In logic based the programmer does not need nor have the ability to implement any storage management techniques.Functional 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, functional languages allow recursion in subprograms. So, subprograms in functional 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. Functional 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. In functional languages, such as Scheme, programmers do not have to explicitly de-allocate 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. Similarly, logic-based languages also give just as much freedom to programmers as functional languages as far as memory management is concerned. Garbage collection is used in both language groups to handle storage management automatically. Garbage collection gives programmer more flexibility and decreases the chances of memory leaks.
|
Handling of abstraction and encapsulation |
Functional languages are heavily abstracted. Much of the code is stored in libraries and external functions. The function of those that are in the libraries is kept encapsulated, "hidden". Without this feature functional programs would not be manageable. Some data abstraction can be done in LISP using a list. This provides a method of procedural abstraction. LISP, as other functional languages, do not allow for encapsulation of data. Logic-based languages have a lot of information hiding. The "how" of the program is hidden away from the user. The desired results are what the user is supplied with. Encapsulation of data is most important. One logic-based language, Prolog, offers both abstraction and encapsulation, but in a different way as compared to LISP. Prolog uses what’s known a rule. A rule is nothing more than an encapsulation of data. A single rule may imply thousands or even millions of possible facts. These modules of facts and rules can then be encapsulated and imported into other programs. By design, implementation techniques are hidden from the programmer. It is not needed for the programmer to see how results are actually achieved. Therefore, these languages do not have the software principles for programmer-defined modules, types, and higher order programming and data abstraction. 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. Some logic-based programs were not designed for large-scale projects and do not include support for shareable, reusable code. Others, such as Mercury, do implement reusable code in modules - allowing data declarations and predicates to either be totally hidden or completely seen by the calling program. |
..:: References ::..
..:: Functional ::.. http://134.193.15.25/vu/course/cs441/exercises/2003p1/yacc.doc http://l.students.umkc.edu/lpec9z/proj1.htm
http://www.cs.cornell.edu/Info/Projects/NuPrl/book/node173.html http://en2.wikipedia.org/wiki/YACC http://www.gnu.org/software/bison/manual/html_mono/bison.html http://www.cs.man.ac.uk/~pjj/cs2121/ho/node5.html http://en2.wikipedia.org/wiki/Chomsky_hierarchy
Robert W Sebasta, Concepts of Programming Languages, 5th
Ed; Boston, 2002, Addison Wesley
..::Logic Based::.. http://134.193.15.25/vu/course/cs441/exercises/2003p1/prolog.doc “Abstract Data Types”. Department of Information and Computer Sciences. University of Hawai at Manoa. n. d. 9 Nov 2003. http://lilt.ics.hawaii.edu/classes/ICS313/313-Ch-11.ppt
Bowers, Shawn, Ph.D University of Oregon, www.capital.ous.edu/~bowerss/cst426/lecture4-2up.pdf, 2003
Chang Y. and Cox P. “Storage management in a Prolog Compiler”. New York: ACM Press, 1986. http://80-delivery.acm.org.ezproxy.mnl.umkc.edu/10.1145/330000/322747/p43-chang.pdf?key1=322747&key2=6457148601&coll=ACM&dl=ACM&CFID=13797352&CFTOKEN=37926521
Clocksin, W.F. & C.S. Mellish “Programming in Prolog”, Springer, 1985
Diaz, Daniel. “GNU PROLOG: A Native Prolog Compiler with Constraint Solving over Finite Domains.” 2002, Sept. 25. Edition 1.7 http://pauillac.inria.fr/~diaz/gnu-prolog/manual/index.html http://pauillac.inria.fr/~diaz/gnu-prolog/manual/manual022.html#toc41
Eadline, Douglas, “Making Prolog Parallel”, Paralogic, 1995
Hancox, Peter, Ph.D, University of Birmingham, www.cs.bham.ac.uk/~pjh/prolog_course/md1/md1_data_types.html, October 1998.
Huntbach Matthew. “Notes on Prolog”. Department of Computer Science. Queen Mary University. n. d. 6 Nov 2003. http://www.dcs.qmw.ac.uk/~mmh/AINotes/.
Luger, George. “Artificial Intelligence: Structures and Strategies for Complex Problem Solving.”. 4th ed. New York: Addson Wesley, 2002.
Massicotte, Pierre, Ph.D, Simon Fraser University, www.cs.sfu.ca/CC/SW/Prolog/Notes/syntax.html, 2003
Matuszek, David. “Programming Languages: The Beginning”. Department of Computing Sciences. Villanova University. n. d. 6 Nov 2003. http://www.csc.vill.edu/~dmatusze/resources/ general/beginning
Sebesta, Robert. “Concepts of Programming Languages”. 5th ed. New York: Addison Wesley, 2002
Wielemaker, Jan. “SWI-Prolog 5.2 Reference Manual”. Prolog. Oct 2003. 9 Nov 2003. http://www.swi-prolog.org/
“What is SWI-Prolog?” SWI-Prolog’s Home.
..:: Simple Procedural ::.. http://www.cs.sjsu.edu/~fecteau/cs140/SubroutinesI.html
http://www.cs.ucsd.edu/classes/fa02/cse150/lectures-pdf/lec7.pdf
http://www.docm.mmu.ac.uk/library/notes/ajt/chapter12.html
Luger, George. "Artificial Intelligence: Structures and Strategies for Complex Problem Solving.". 4th ed. New York: Addson Wesley, 2002.
http://www.ist.tugraz.at/files/pub/courses/oop03/vo/Slides/vo01.pdf
http://www.programmersheaven.com/zone5/index.htm
http://www.osdata.com/topic/language/asm/asmintro.htm
http://www.faqs.org/docs/learnc/
|