Programming Paradigms via Mathematica: Preface
Programming Paradigms via Mathematica introduces both the major concepts of introductory programming as well as the various programming styles, or paradigms, found in current programming languages. We consider programming in a variety of contexts and at a variety of levels---from short questions to large group projects---in order to present a broad picture of programming as a versatile tool. The text provides a solid foundation for later courses, including Data Structures, Algorithms, and Comparative Programming Languages, while at the same time leading toward courses which develop the skills of the programmer in a particular programming language, be it C++ or Pascal, list-based, functional, object-oriented or procedural. The language Mathematica is the means to these ends, providing a context for the introduction of practical techniques while avoiding the necessity of devoting the first half of an introductory course in computer science to the specific details of a specialized computer language. This text begins with powerful intrinsic (pre-defined) functions and quickly progresses to significant list-based programming. Interesting problems employ new concepts and technical details as they are developed. In this spirit, we do not emphasize the specialized techniques of a Mathematica programmer but instead highlight within Mathematica the various programming styles of a list-based, procedural, or object-oriented programming environment. Our treatment enables an understanding of, and easy adaptation to, the approach of such a specialized programmer in a wide array of languages, with Mathematica and C++ being conscious instances.
Our text is appropriate for a beginning course in computer programming, without prerequisites. The text covers much of what is known as CS1 in the current curriculum standards for computer science. It is to be expected that the programming experience of students for this course will vary from absolutely none to considerable practice in some language, though probably other than Mathematica. Students should be comfortable with mathematics and computer usage, to the extent that basic ideas from each are introduced throughout the course; a good background in high school mathematics coupled with experience using a mouse and keyboard with computer software is sufficient. Any student who has completed a CS1 course---regardless of language---or who has extensive algorithmic programming experience should step beyond this book to a course with
One example of our approach is found in a central theme of the text, the juxtaposition of three alternative approaches to repetition: list-based operations, recursion, and iterative loops. Each is important in modern programming in its own right, and our text considers each in detail. The three methods are first compared as solutions to factorial programming at the beginning of Section 5. List-based programming is then developed first, in Chapter II. Functions are applied to lists in many different ways, represented by several higher-order functions. In Chapter V we emphasize recursion as a more universal technique to accomplish repetition, providing many problems involving lists in order to encourage comparisons with list-based programming. Finally, in Chapter VI we discuss iteration in the classic context of procedural programming and explore the advantages and disadvantages of such a style. Implementing higher-order list functions from Chapter II as procedural functions encourages still more comparison while providing excellent exercises in the understanding of basic algorithms.
In exploring repetition in these ways, the advantages to instructor and student of using Mathematica are brought into clear focus. By considering list-based programming first, we can avoid the crutch of understanding iteration only in procedural programming. And since list manipulation is natural to Mathematica, we can quickly enable students to accomplish significant tasks with a small amount of thought-provoking code. Even further, in list-based programming we are able to encourage students to think of functions and higher-order functions separately, using for instance the grammatical interpretation in which functions are verbs and higher-order functions adverbs, as emphasized in Ken Iverson's language J. When we reach the recursive approach, Mathematica provides advantages over traditional programming languages, easily allowing multiple definitions for the same function with different arguments: the general case ``doItTo[n\_]'' can reduce to the base case ``doItTo''. In this way we easily introduce the concept of pattern-matching in symbolic programming. Finally, in the procedural approach to repetition, we find that many of the syntactic structures in Mathematica are much like C, paving the road to future programming in C or C++.
In having students avoid the syntactical and structural considerations of a specialized programming
language---as well as the time such considerations require---we allow time to consider a wide variety of important programming concepts. Modular programming, with local and global scope considerations, is placed front-and-center in Chapter III. Bottom-up and top-down analysis, string type, and ASCII codes are all covered near the beginning of the text; various conditional execution structures, call-by-reference, and call-by-value nearer the end. At several places we consider the tradeoffs between time and space in order to lay a framework for algorithmic analysis in later courses. In particular, compilation is one minor theme of the course, reaching full expression in one of the later sections. Pascal-style records have an analogy in the structured patterns of Section 12, and a programming style similar to pure functional programming is enabled by a discussion of anonymous functions. We note that some of the code we provide mimics rather than fully implements certain topics; for instance, we discuss call-by-value and call-by-reference and ``interpret'' Mathematica constructs in this fashion, ignoring the fact that Mathematica is more precisely a large rewriting engine.
A course that fulfills the intention of this text should cover most of each section through Section 17 or 18 on iterative programming. If time is available, the syllabus could complete additional sections through Section 20 on function calls. At this point, three distinctly different ways to continue in the text present themselves: (1) The remainder of Chapter VII covers more valuable general programming topics such as object-oriented programming and file manipulation; (2) Chapter VIII bridges the gap to other languages by lessons in reading actual code from these languages; finally, (3) Chapter IX covers special topics for the Mathematica user. In particular, graphics (and even animation) is a fun reward to students who have completed the heart of the course. While there are many texts on Mathematica that seek to impress students with gee-whiz-bang graphics at the beginning, we find that student exploration at the end is more appropriate, as well as more informative. For some audiences, the section on substitution and rewrite rules fills a gap in the understanding and use of Mathematica-specific techniques.
Our text ends with a summary section, which we find is a valuable way to reflect on the many alternative approaches that have been developed and how they fit into several different paradigms or modes of programming, including functional, procedural, array-oriented, logic, symbolic, and
object-oriented. Using it as a point of reference, we are able to stress to students that most languages tend to encourage one paradigm over another; Mathematica itself was designed with ideas from sources as diverse as the procedural language C and the array-oriented (list-based, in our terminology) language APL. Once these various paradigms are explored, we return to a brief consideration of Mathematica, ultimately an example of the less common paradigm of symbolic programming. One useful way to broaden the scope of the course further is to consider how one might apply list-based concepts to parallel programming, treating the ways in which algorithms might be implemented more efficiently depending on the array of computing processors available.
Davidson, North Carolina