CSC 332 NOTE A.pdf
Document Details
Uploaded by PermissibleMachuPicchu8645
Air Force Institute of Technology
2023
Tags
Full Transcript
SURVEY OF PROGRAMMING LANGUAGES CSC 332 (3-UNITS) MO ALIMI AND RO IBRAHIM DEPARTMENT OF COMPUTER SCIENCE FACULTY OF COMPUTING AFIT, KADUNA 2023/2024 SESSION 1 Introduction Languages generally can either be natural or art...
SURVEY OF PROGRAMMING LANGUAGES CSC 332 (3-UNITS) MO ALIMI AND RO IBRAHIM DEPARTMENT OF COMPUTER SCIENCE FACULTY OF COMPUTING AFIT, KADUNA 2023/2024 SESSION 1 Introduction Languages generally can either be natural or artificial. Every human being must be born with a language that does not require special teacher before you speak such language. E.g. Arabic, Yoruba, Hausa, Igbo, English, French, etc. But on the other hand we have some languages that are formed with defined words, structure, construct, etc. These are artificial and must be learned with all its rules before it could be useful and meaningful in life. These are mostly computer programming languages. E.g. Java, C++, C, C#, Basic, Fortran, Php, Ada, Perl, LISP, Scheme, Prolog, etc. Students are to be grouped and present on the following: Java, C#, Php, Python, C++, C, Ruby, Groovy, Java Script, XSLT, Scala, Clojure, COBOL, Fortran, Pascal, VB, Ada, Perl, Scheme, Prolog, go, etc. A programming language is an artificial language designed for expressing algorithms on a computer: – Need to express an infinite number of algorithms (Turing complete). – Requires an unambiguous syntax, specified by a finite context free grammar. – Should have a well defined compositional semantics for each syntactic construct: operational vs. axiomatic vs. denotational. – Often requires a practical implementation i.e. pragmatics: i.e. Implementation on a real machine vs. virtual machine translation vs. compilation vs. interpretation. “a language intended for use by a person to express a process by which a computer can solve a problem” -Hope and Jipping Learning Objectives Increase capacity to express ideas and programming concepts. Improve background for choosing appropriate programming languages for certain classes of programming problems. 2 Improve ability to learn new programming languages. Improve ability to choose among alternative ways to write programs/solutions. Simulate useful features in languages that lack such features. Understand the significance of a programming language implementation via a compiler, interpreter, or hybrid. Be able to design and develop a syntax analyzer for a programming language. Become familiar with imperative, object-oriented, functional, and logic programming paradigms and features of their representative programming languages. Improve knowledge of object-oriented programming language such as C++. Learn imperative features of programming language such as Perl. Learn functional programming language such as Scheme. Learn logic programming language such as Prolog. Obtain programming skills in different languages such as C++, Perl, Scheme, and Prolog. Become familiar with IDEs, debuggers and related tools for selected programming languages. Why we need to Study Organisation of Programming Languages Reasons why computer science students and professional software developers should study general concepts of language design and evaluation is because some believe that a working knowledge of one or two programming languages is sufficient for computer scientists. The more the number of languages you know the better. Among the reasons are: 1. Increased capacity to express ideas. It is widely believed that the depth at which people can think is influenced by the expressive power of the language in which they communicate their thoughts. Those with only a weak understanding of natural language are limited in the complexity of their thoughts, particularly in depth of abstraction. In other words, it is difficult for people to conceptualize structures they cannot describe, verbally or in writing. Programmers, in the process of developing software, are similarly constrained. The language in which they develop software places limits on the kinds of control structures, data structures, and abstractions they can use; thus, the forms of algorithms 3 they can construct are likewise limited. Awareness of a wider variety of programming language features can reduce such limitations in software development. Programmers can increase the range of their software development thought processes by learning new language constructs. The study of programming language concepts builds an appreciation for valuable language features and constructs and encourages programmers to use them, even when the language they are using does not directly support such features and constructs. 2. Improved background for choosing appropriate languages. Many professional programmers have had little formal education in computer science; rather, they have developed their programming skills independently or through in-house training programs. Such training programs often limit instruction to one or two languages that are directly relevant to the current projects of the organization. Many other programmers received their formal training years ago. The languages they learned then are no longer used, and many features now available in programming languages were not widely known at the time. The result is that many programmers, when given a choice of languages for a new project, use the language with which they are most familiar, even if it is poorly suited for the project at hand. If these programmers were familiar with a wider range of languages and language constructs, they would be better able to choose the language with the features that best address the problem. Some of the features of one language often can be simulated in another language. However, it is preferable to use a feature whose design has been integrated into a language than to use a simulation of that feature, which is often less elegant, more cumbersome, and less safe. 3. Increased ability to learn new languages. Computer programming design methodologies, software development tools, and programming languages are still in a state of continuous evolution. This makes software development an exciting profession, but it also means that continuous learning is essential. The process of learning a new programming language can be lengthy and difficult, especially for someone who is comfortable with only one or two languages and has never examined programming language 4 concepts in general. Once a thorough understanding of the fundamental concepts of languages is acquired, it becomes far easier to see how these concepts are incorporated into the design of the language being learned. For example, programmers who understand the concepts of object- oriented programming will have a much easier time learning Java than those who have never used those concepts. Furthermore, learning a second language has the benefit of teaching you more about your first language. The index data also show that the distribution of usage of programming languages is always changing. The number of languages in use and the dynamic nature of the statistics imply that every software developer must be prepared to learn different languages. 4. Better understanding of the significance of implementation. In learning the concepts of programming languages, it is both interesting and necessary to touch on the implementation issues that affect those concepts. In some cases, an understanding of implementation issues leads to an understanding of why languages are designed the way they are. In turn, this knowledge leads to the ability to use a language more intelligently, as it was designed to be used. We can become better programmers by understanding the choices among programming language constructs and the consequences of those choices. Certain kinds of program bugs can be found and fixed only by a programmer who knows some related implementation details. Another benefit of understanding implementation issues is that it allows us to visualize how a computer executes various language constructs. In some cases, some knowledge of implementation issues provides hints about the relative efficiency of alternative constructs that may be chosen for a program. For example, programmers who know little about the complexity of the implementation of subprogram calls often do not realize that a small subprogram that is frequently called can be a highly inefficient design choice. 5. Better use of languages that are already known. Many contemporary programming languages are large and complex. Accordingly, it is uncommon for a programmer to be familiar with and use all of the features of a language he or she uses. By studying the concepts of programming languages, programmers can learn about 5 previously unknown and unused parts of the languages they already use and begin to use those features. 6. Overall advancement of computing. Finally, there is a global view of computing that can justify the study of programming language concepts. Although it is usually possible to determine why a particular programming language became popular, many believe, at least in retrospect, that the most popular languages are not always the best available. In some cases, it might be concluded that a language became widely used, at least in part, because those in positions to choose languages were not sufficiently familiar with programming language concepts. For example, many people believe it would have been better if ALGOL 60 had displaced Fortran in the early 1960s, because it was more elegant and had much better control statements, among other reasons. That it did not, is due partly to the programmers and software development managers of that time, many of whom did not clearly understand the conceptual design of ALGOL 60. They found its description difficult to read (which it was) and even more difficult to understand. They did not appreciate the benefits of block structure, recursion, and well-structured control statements, so they failed to see the benefits of ALGOL 60 over Fortran. However, the fact that computer users were generally unaware of the benefits of the language played a significant role. In general, if those who choose languages were well informed, perhaps better languages would eventually squeeze out poorer ones. Programming Domains Computers have been applied to a myriad ( countless /innumerable) of different areas, from controlling nuclear power plants to providing video games in mobile phones. Because of this great diversity in computer use, programming languages with very different goals have been developed. In this section, we briefly discuss a few of the areas of computer applications and their associated languages. 6 (a) Scientific Applications The first digital computers, which appeared in the late 1940s and early 1950s, were invented and used for scientific applications. Typically, the scientific applications of that time used relatively simple data structures, but required large numbers of floating-point arithmetic computations. The most common data structures were arrays and matrices; the most common control structures were counting loops and selections. The early high-level programming languages invented for scientific applications were designed to provide for those needs. Their competition was assembly language, so efficiency was a primary concern. The first language for scientific applications was Fortran. ALGOL 60 and most of its descendants were also intended to be used in this area, although they were designed to be used in related areas as well. For some scientific applications where efficiency is the primary concern, such as those that were common in the 1950s and 1960s, no subsequent language is significantly better than Fortran, which explains why Fortran is still used. (b) Business Applications The use of computers for business applications began in the 1950s. Special computers were developed for this purpose, along with special languages. The first successful high-level language for business was COBOL, the initial version of which appeared in 1960. It is still the most commonly used language for these applications. Business languages are characterized by facilities for producing elaborate reports, precise ways of describing and storing decimal numbers and character data, and the ability to specify decimal arithmetic operations. There have been few developments in business application languages outside the development and evolution of COBOL. (c) Artificial Intelligence Artificial intelligence (AI) is a broad area of computer applications characterized by the use of symbolic rather than numeric computations. Symbolic computation means that symbols, consisting of names rather than numbers, are manipulated. Also, symbolic computation is more conveniently done with linked lists of data rather than arrays. This kind of programming 7 sometimes requires more flexibility than other programming domains. For example, in some AI applications the ability to create and execute code segments during execution is convenient. The first widely used programming language developed for AI applications was the functional language LISP, which appeared in 1959. Most AI applications developed prior to 1990 were written in LISP or one of its close relatives. During the early 1970s, however, an alternative approach to some of these applications appeared—logic programming using the Prolog language. More recently, some AI applications have been written in systems languages such as C and Scheme, a dialect of LISP, and Prolog. (d) Systems Programming The operating system and the programming support tools of a computer system are collectively known as its systems software. Systems software is used almost continuously and so it must be efficient. Furthermore, it must have low-level features that allow the software interfaces to external devices to be written. In the 1960s and 1970s, some computer manufacturers, such as IBM, Digital, and Burroughs (now UNISYS), developed special machine-oriented high-level languages for systems software on their machines. For IBM mainframe computers, the language was PL/S, a dialect of PL/I; for Digital, it was BLISS, a language at a level just above assembly language; for Burroughs, it was Extended ALGOL. However, most system software is now written in more general programming languages, such as C and C++. The UNIX operating system is written almost entirely in C, which has made it relatively easy to port, or move, to different machines. Some of the characteristics of C make it a good choice for systems programming. It is low level, execution efficient, and does not burden the user with many safety restrictions. Systems programmers are often excellent programmers who believe they do not need such restrictions. Some non-systems programmers, however, find C to be too dangerous to use on large, important software systems. 8 (e) Web Software The World Wide Web is supported by an eclectic collection of languages, ranging from markup languages, such as HTML, which is not a programming language, to general-purpose programming languages, such as Java. Because of the pervasive need for dynamic Web content, some computation capability is often included in the technology of content presentation. This functionality can be provided by embedding programming code in an HTML document. Such code is often in the form of a scripting language, such as JavaScript or PHP. There are also some markup-like languages that have been extended to include constructs that control document processing. (f) Mobile Software The world is changing on daily basis as mobile software is taking its turn in coding with many programming languages now raining in developing mobile applications. Xamarin, Android studio, Flutter, etc LISP Elements of Programming A powerful programming language is more than just a means for instructing a computer to perform tasks. The language also serves as a framework within which we organize our ideas about processes. Thus, when we describe a language, we should pay particular attention to the means that the language provides for combining simple ideas to form more complex ideas. Every powerful language has three mechanisms for accomplishing this: primitive expressions, which represent the simplest entities the language is concerned with, means of combination, by which compound elements are built from simpler ones, and 9 means of abstraction, by which compound elements can be named and manipulated as units. In programming, we deal with two kinds of elements: procedures and data. Informally, data is ``stuff'' that we want to manipulate, and procedures are descriptions of the rules for manipulating the data. Thus, any powerful programming language should be able to describe primitive data and primitive procedures and should have methods for combining and abstracting procedures and data. In this, we will deal with simple numerical data so that we can focus on the rules for building procedures.4 We will see that these same rules allow us to build procedures to manipulate compound data as well. LISP Expressions When you start up the Common LISP environment, you should see a prompt, which means that LISP is waiting for you to enter a LISP expression. The environment looks like the following: USER(1): The Common LISP environment follows the algorithm below when interacting with users: loop read in an expression from the console; evaluate the expression; print the result of evaluation to the console; end loop. Common LISP reads in an expression, evaluates it, and then prints out the result. For example, if you want to compute the value of (2 * cos(0) * (4 + 6)), you type in: USER(1): (* 2 (cos 0) (+ 4 6)) 10 Common LISP replies: 20.0 before prompting you to enter the next expression. Several things are worth noting: LISP expressions are composed of forms. The most common LISP form is function application. LISP represents a function call f(x) as (f x). For example, cos(0) is written as (cos 0). LISP expressions are case-insensitive. It makes no difference whether we type (cos 0) or (COS 0). Similarly, "+" is the name of the addition function that returns the sum of its arguments. Some functions, like "+" and "*", could take an arbitrary number of arguments. In our example, "*" took three arguments. It could as well take 2 arguments, as in "(* 2 3)", or 4 arguments, as in "(* 2 3 4 5)". In general, a function application form looks like (function argument1 argument2... argumentn). As in many programming languages (e.g. C/C++), LISP evaluates function calls in applicative order, which means that all the argument forms are evaluated before the function is invoked. That is to say, the argument forms (cos 0) and (+ 4 6) are respectively evaluated to the values 1 and 10 before they are passed as arguments to the * function. Some other forms, like the conditionals we will see later, are not evaluated in applicative order. Numeric values like 4 and 6 are called self-evaluating forms: they evaluate to themselves. To evaluate (+ 4 6) in applicative order, the forms 4 and 6 are respectively evaluated to the values 4 and 6 before they are passed as arguments to the + function. 11 Complex arithmetic expressions can be constructed from built-in functions like the following: Numeric Functions Meaning (+ x1 x2... xn) The sum of x1, x2,..., xn (* x1 x2... xn) The product of x1, x2,..., xn (- x y) Subtract y from x (/ x y) Divide x by y (rem x y) The remainder of dividing x by y (abs x) The absolute value of x (max x1 x2... xn) The maximum of x1, x2,..., xn (min x1 x2... xn) The minimum of x1, x2,..., xn Common LISP has a rich set of pre-defined numerical functions. Relational operators include the following: Relational Operators Meaning (= x y) x is equal to y (/= x y) x is not equal to y (< x y) x is less than y (> x y) x is greater than y (= x y) x is no less than y 12 Examples Expressions such as these, formed by delimiting a list of expressions within parentheses in order to denote procedure application, are called combinations. The leftmost element in the list is called the operator, and the other elements are called operands. The value of a combination is obtained by applying the procedure specified by the operator to the arguments that are the values of the operands. The convention of placing the operator to the left of the operands is known as prefix notation, and it may be somewhat confusing at first because it departs significantly from the customary mathematical convention. Prefix notation has several advantages, however. One of them is that it can accommodate procedures that may take an arbitrary number of arguments. E.g. (+ 21 35 12 7) 75 (* 25 4 12) 1200 A second advantage of prefix notation is that it extends in a straightforward way to allow combinations to be nested, that is, to have combinations whose elements are themselves combinations: (+ (* 3 5) (- 10 6)) 19 There is no limit (in principle) to the depth of such nesting and to the overall complexity of the expressions that the Lisp interpreter can evaluate. It is we humans who get confused by still relatively simple expressions such as (+ (* 3 (+ (* 2 4) (+ 3 5))) (+ (- 10 7) 6)) 13 which the interpreter would readily evaluate to be 57. 1.1.2 Naming and the Environment A critical aspect of a programming language is the means it provides for using names to refer to computational objects. We say that the name identifies a variable whose value is the object. In the Scheme dialect of Lisp, we name things with define. Typing (define size 2) causes the interpreter to associate the value 2 with the name size. Once the name size has been associated with the number 2, we can refer to the value 2 by name: size 2 (* 5 size) 10 Here are further examples of the use of define: (define pi 3.14159) (define radius 10) (* pi (* radius radius)) 314.159 (define circumference (* 2 pi radius)) circumference 62.8318 1.1.3 Evaluating Combinations One of our goals in this chapter is to isolate issues about thinking procedurally. As a case in point, let us consider that, in evaluating combinations, the interpreter is itself following a procedure. 14 To evaluate a combination, 1. Evaluate the subexpressions of the combination. 2. Apply the procedure that is the value of the leftmost subexpression (the operator) to the arguments ents that are the values of the other subexpressions (the operands). Thus, the evaluation rule is recursive in nature; that is, it includes, as one of its steps, the need to invoke the rule itself. E.g (* (+ 2 (* 4 6)) (+ 3 5 7)) requires that the evaluation luation rule be applied to four different combinations. We can obtain a picture of this process by representing the combination in the form of a tree, as shown below: Viewing evaluation in terms of the tree, we can imagine that the values of the operands percolate p upward, starting from the terminal nodes and then combining at higher and higher levels. In general, we shall see that recursion is a very powerful technique for dealing with hierarchical, treelike objects. In fact, the ``percolate values upward'' form of the evaluation rule is an example of a general kind of process known as tree accumulation. Figure 1.1: Tree representation, showing the value of each subcombination. 15 Next, observe that the repeated application of the first step brings us to the point where we need to evaluate, not combinations, but primitive expressions such as numerals, built-in operators, or other names. We take care of the primitive cases by stipulating that the values of numerals are the numbers that they name, the values of built-in operators are the machine instruction sequences that carry out the corresponding operations, and the values of other names are the objects associated with those names in the environment. Such exceptions to the general evaluation rule are called special forms. Define is the only example of a special form that we have seen so far, but we will meet others shortly. Each special form has its own evaluation rule. The various kinds of expressions (each with its associated evaluation rule) constitute the syntax of the programming language. In comparison with most other programming languages, Lisp has a very simple syntax; that is, the evaluation rule for expressions can be described by a simple general rule together with specialized rules for a small number of special forms.11 1.1.4 Compound Procedures Identify in Lisp some of the elements that must appear in any powerful programming language: Numbers and arithmetic operations are primitive data and procedures. Nesting of combinations provides a means of combining operations. Definitions that associate names with values provide a limited means of abstraction. Now procedure definitions: a much more powerful abstraction technique by which a compound operation can be given a name and then referred to as a unit. To express the idea of ``squaring.'' ``To square something, multiply it by itself.'' This is expressed as follows: (define (square x) (* x x)) We can understand this in the following way: 16 (define (square x) (* x x)) To square something, multiply it by itself. The compound procedure,, name is square.. The procedure represents the operation of multiplying something by itself. The general form of a procedure definition is (define ( ) ) Having defined square,, we can now use it: (square 21) 441 (square (+ 2 5)) 49 (square (square 3)) 81 We can also use square as a building block in defining other procedures. For example, x2 + y2 can be expressed as (+ (square x) (square y)) We can easily define a procedure dure sum-of-squares that, given any two numbers as arguments, produces the sum of their squares: (define (sum-of-squares x y) (+ (square x) (square y))) (sum-of-squares 3 4) 25 History of programming languages Prehistory – 300 B.C. Greece, Euclid invented the greatest common divisor algorithm - oldest known algorithm – ~1820-1850 1850 England, Charles Babbage invented two mechanical computational devices difference engine 17 analytical engine Countess Ada Augusta of Lovelace, first computer programmer – Precursors to modern machines 1940’s United States, ENIAC developed to calculate trajectories ***** The 1940s: Von Neumann and Zuse Von Neumann led a team that built computers with stored programs and a central processor ENIAC was programmed with patch cords. Machine Codes: 1940’s Initial computers were programmed in raw machine codes. These were entirely numeric. What was wrong with using machine code? Everything! Poor readability Poor modifiability Expression coding was tedious Inherit deficiencies of hardware, e.g., no indexing or floating point numbers ** 1950’s United States, first high-level PLs invented – Fortran (FORmula TRANslator) 1954-57, John Backus (IBM on 704) designed for numerical scientific computation.The first higher level programming language fixed format for punched cards implicit typing only counting loops, if test versus zero only numerical data 18 1957 optimizing Fortran compiler translates into code as efficient as hand-coded ***** – Algol60 1958-60, designed by international committee for numerical scientific computation. block structure with lexical scope free format, reserved words while loops, recursion explicit types BNF developed for formal syntax definition – Cobol 1959-60, designed by committee in US, manufacturers and for business data processing The first business oriented language records focus on file handling English-like syntax ***** APL 1956-60 Ken Iverson, (IBM on 360, Harvard) designed for array processing functional programming style – LISP 1956-62, John McCarthy (MIT on IBM704, Stanford) designed for non-numerical computation The first language outside the von Neumann model uniform notation for program and data recursion as main control structure garbage collection – Snobol 1962-66, Farber, Griswold, Polansky (Bell Labs) designed for string processing powerful pattern matching ******* PL/I 1963-66, IBM designed for general purpose computing [Fortran, Algol60, Cobol] 19 user controlled exceptions multi-tasking – Simula67 1967, Dahl and Nygaard (Norway) designed as a simulation language. data abstraction inheritance of properties – Algol68 1963-68, designed for general purpose computing after [Algol60] orthogonal language design interesting user defined types **** BASIC 1964 Beginner's All purpose Symbolic Instruction Code Designed by Kemeny & Kurtz at Dartmouth for the GE 225 with the goals: Easy to learn and use for non-science students and as a path to Fortran and Algol Must be “pleasant and friendly” Fast turnaround for homework Free and private access User time is more important than computer time Well suited for implementation on first PCs (e.g., Gates and Allen’s 4K Basic interpreter for the MITS Altair personal computer (circa 1975) Current popular dialects: Visual BASIC ********* Pascal 1969, N. Wirth(ETH) designed for teaching programming. 1 pass compiler call-by-value semantics 20 – Prolog 1972, Colmerauer and Kowalski designed for Artificial Intelligence applications theorem proving with unification as basic operation logic programming – C 1974, D. Ritchie (Bell Labs) designed for systems programming allows access to machine level within high-level PL efficient code generated ***** Clu 1974-77, B. Liskov (MIT) designed for simulation. supports data abstraction and exceptions precise algebraic language semantics attempt to enable verification of programs – Smalltalk mid-1970s, Alan Kay (Xerox Parc), considered first real object-oriented PL. encapsulation, inheritance easy to prototype applications hides details of underlying machine – Scheme mid-1970s, Guy Steele, Gerald Sussman (MIT) Static scoping and first-class functions ****** Concurrent Pascal 1976 Per Brinch Hansen (U Syracuse) designed for asynchronous concurrent processing after [Pascal] monitors for safe data sharing – Modula 1977 N. Wirth (ETH), designed language for large software development [Pascal] to control interfaces between sets of procedures or modules real-time programming – Ada 1979, US Department of Defense (DoD) committee designed as general purpose PL 21 explicit parallelism - rendezvous exception handling and generics (packages) *** C++ 1985, Bjorne Stroustrup (Bell Labs) general purpose goal of type-safe object-oriented PL compile-time type checking templates In 1988, Alan Cooper created a visual programming language (code-named “Ruby”) that allowed Windows users to build “Finder”-like shells. He called it “a shell construction set." After he demonstrated Ruby to Bill Gates, Microsoft purchased it. Visual Basic was first introduced in 1991; it is considered the third generation of event-driven programming languages. Various Windows programs were developed throughout the 1990s using VB. VB continued to evolve throughout the 1990s until Visual Basic 6 was released in 1998, which was replaced by VB.NET found under Visual Studio. VB.NET, is a multi-paradigm, object-oriented programming language, implemented on. NET, Mono, and the.NET Framework. These software tools not only create Windows programs, but they also take full advantage of the graphical way that Windows works by letting programmers "draw" their systems with a mouse on the computer. – Java ~1995, J. Gosling (SUN) aimed at portability across platform through use of JVM - abstract machine to implement the PL aimed to fix some problems with previous OOPLs ¨ multiple inheritance ¨ static and dynamic objects 22 ubiquitous exceptions thread objects Python was invented in the late 1980s by Guido van Rossum at Centrum Wiskunde & Informatica (CWI) in the Netherlands as a successor to the ABC programming language, which was inspired by SETL, capable of exception handling and interfacing with the Amoeba operating system. It was first released on February 20, 1991. While you may know the python as a large snake, the name of the Python programming language comes from an old BBC television comedy sketch series called Monty Python's Flying Circus. **************** 23