My introductory programming courses always start with some loose definitions. I define an algorithm as an unambiguous process for solving a problem using a finite amount of resources, and a heuristic as a problem solving process that is not guaranteed to be perfect/exact or finite. I then explain that algorithms/heuristics written for a computer are commonly written in languages, called (high-level) programming languages, that are easily understood by humans, unambiguous, and easily converted into machine-readable form. I then point out that an algorithm/heuristic written in a programming language is a program (or code), and the process of doing so is called programming (or coding), which is what they will be studying for the remainder of the term.
As a practical matter, most introductory programming courses, mine included, use a single, specific programming language and, not surprisingly, there is considerable debate about which language is best for teaching beginning programmers (or whether it matters). However, there is, generally, consensus about the role that the programming language plays and the goals of such courses. Indeed, most introductory programming courses make claims like the following:
- The concepts covered using the particular programming language selected for the course are applicable across a wide variety of other programming languages.
- The course teaches algorithmic thinking more than the syntax of the language(s) being used.
In my experience, these claims are not completely justified. While the first is often true from a teaching perspective, it is not true from a learning perspective. In other words, students have enormous trouble taking what they have learned in one language and applying it in another. The second is an honest description of what the instructor wants to cover, but is a goal that is rarely achieved.
In the worst cases, instructors in introductory programming courses spend all of their time teaching students syntax and tools, and leave it to the students to figure out how to solve problems. Using concepts from Bloom’s taxonomy of the cognitive domain, such courses only teach “remembering” and “understanding”, and expect students to “analyze”, “evaluate”, “apply” and “create” on their own.
In the better cases, instructors in introductory programming courses expose students to well-written code containing good solutions to problems and explain why the code is good. However, they only hope that the students will internalize these solutions and be able to apply them in other contexts; they do not explicitly teach them to do so. In other words, these courses only teach “remembering”, “understanding”, “analyzing” and “evaluating”, but not “applying” and “creating”.
In the best cases, instructors in introductory programming courses teach “applying” and “creating” as well. That is, they teach problem solving as well as programming. This book is designed to make it easier to do so.
In the end, this approach provides students with two things: a library of solutions that they can use and an understanding of how to add to that library themselves. When faced with a new problem, their job is most frequently to recognize that they already have a solution. Less frequently, their job is to recognize that they don’t have a solution readily available and understand that they must develop alternative solutions, evaluate those solutions, and select the best alternative.