Example: Invasion of S. Vietnam by the North is an "objective fact." Two different paradigms interpreted these facts differently. One paradigm said the soviets are trying to take over the world and the U.S. should stop them, the other said the U.S. had no business being there- it was a local problem. From the same facts, two different interpretations were drawn.
Paradigms can create very strange iterpretations of facts, but this does not make them "wrong." Think about the "facts" that were available in the 16th century regarding the Earth and the Sun:
Consider the "celestial spheres" interpretation of the Copernican model of the universe. The backers of celestial spheres proposal considered the Copernican approach a mathematical "hack" to make the calculations easier.
Copernicus also had trouble explaining why we did not observe the violent rotation of the earth; his paradigm chose to ignore this issue. Paradigms in the sciences can dictate what a scientist (you!) think is important, unimportant, interesting, boring, and (more generally) how you interpret "facts" you are given. The danger here is not understand that what appear to be "facts" are generally filtered through some paradigm; sometimes old paradigms have to be exchanged for new ones.
Procedural Object-Oriented Functional FORTRAN (V, 90) Simula (68) Lisp Cobol Smalltalk ML Algol (Algol-68) C++ FP Pascal Self Scheme Modula (2, 2+, 3) Modula 3 Prolog Ada (9X) Emerald (Dylan?) Basic (Visual) C (C++)It should be noted that it is not the case that one can't program procedurally in Lisp, or O-O in C, it is just that a language which is designed for a particular programming paradigm makes (at least in theory) doing that type of programming easier.
We aren't going to dwell here on the relative strengths and weaknesses of the paradigms- that's the subject of 3410. We are going to focus on functional programming throughout this course.
Why would we want to program this way? Here are some reasons:
The catch is that functional programming can be difficult (especially at first) for people who were originally trained in one (or two) of the other paradigms. Functional programming (in a strict sense) doesn't permit global variables, local variables, assignment, and iteration. It is true that not all problems can be simply and/or easily expressed without constructs of this sort, so towards the end of the quarter we'll be talking about ways that functional programming can be used without the strict requirements of no globals, no locals, no assignment, no iteration, etc. However, towards the beginning of the course those that stray from the path of functional programming and try to use these constructs will be punished....
The granddaddy of all programmer efficiency trade-offs is Lisp. Programmer efficiency is the effective use of programmer time. This "time" should be taken as whole though, not simply just the time to write the code. Don't forget to the time to debug the code, understand and (re)use other people's code, and maintain/update old code that has to be changed to reflect new circumstances/applications. Having said all of this about programmer time, probably the single most important factor in the time it takes to code, debug, and maintain software is the complexity of the system being worked on. One can apply both the general features of good software design as well as some of the particular properties of functional programming towards reducing software complexity.
For the purposes of this course, you can be sure that we will not encourage to think about thinks like, "How do I make my programmer smaller?" "How do I make my program run faster?" or "How does the system really implement this function?" We are expecting to you maximize the programmer efficiency in your programs and in their associated designs. Abelson and Sussman say it pretty well when they say, "... programs must be written for people to read, and only incidentally for machines to execute." But the number one line on this subject comes from probably the most important computer scientist of all time, Donald Knuth, who said: "Premature optimization is the root of all evil."
You are going to learn a great many things about Lisp this quarter. I'm going to shamelessly steal some text from Kurt Eiselt's notes about lisp. Here it goes:[...In this course you'll be learing about] the Common LISP programming language. Well, everything was going along just fine until we mentioned LISP, eh? You may have heard ugly things about LISP: there are too many parentheses, it's only for artificial intelligence, it's hard to learn, and so on. If you heard these myths at Tech, you probably heard them from people who had the language jammed down their throats in one or two weeks after having studied Pascal for two years. But these are in fact just myths, as we hope you'll see by the end of the quarter. LISP will be the language used in this course, and there are lots of good reasons for doing so:
1. LISP started out as a purely functional programming language, and still retains much of that flavor. At the very least, it still encourages a functional programming style, and that's going to help us in this course.
2. LISP is especially good for processing complex hierarchical data structures using recursion. In fact, it is so surprisingly good that those of you who have learned something about processing these sorts of data structures using pointers will find it hard to believe that it could be so easy (LISP does all the pointer management for you).
3. LISP is the second oldest general purpose programming language in use today (FORTRAN is the oldest). As such, LISP has the benefit of lots of people who have devoted lots of years to making it better. This shows up in the form of some of the most sophisticated programming tools (editors, debuggers, etc.) in existence.
4. Most programming languages are designed so that compilation is efficient, often at the expense of things like consistency and usability. LISP on the other hand was designed (and continues to evolve) to maintain mathematical consistency and usability, sometimes at the expense of making the computer work a little harder.
5. Because of its age, LISP is incredibly well documented.
6. LISP has a uniform simple syntax, and there is no distinction between program and data.
7. In its "normal" state, LISP is an interpreted language. That is, code is executed immediately, and no separate compile stage is necessary (although compiling LISP code is both possible and desirable). Interpreted languages are highly interactive and give immediate feedback, making LISP an increasingly popular tool for the rapid prototyping of complex software systems such as new language compilers, graphics systems, and user interfaces.
8. LISP is highly extensible. In other words, it's very easy to build new languages on top of LISP by adding functions. This feature is in large part responsible for LISP's longevity. As new programming paradigms emerged over time, many programming languages fell by the wayside, while LISP was extended to accommodate the new paradigms.
9. The Common LISP standard makes LISP programs very portable. Portability lets you migrate an application from one platform to another without having to rewrite bunches of code. This is an important thing for you budding software entrepreneurs to remember.
10. LISP has automatic storage management. Memory is allocated as it's needed on the fly, and memory that is no longer needed is "garbage collected" dynamically as well. There's seldom a need to "declare" data structures in advance.
11. LISP also has dynamic typing, which means you no longer have to make data type declarations. LISP does type-checking and necessary conversions at run-time.
12. Finally, LISP is the favored language for artificial intelligence work, at least in the United States, so if you're interested in AI, this is the language to know. And even if you're not interested, AI is a required course for CS majors at Tech, and it's taught using LISP, so LISP is still the language to know.