I’ve been thinking a lot lately about the process of learning to program. I’m currently teaching an introductory level programming course using C# at ASU. In order to prepare for this course I’ve read quite a few introductory texts using C#, not for myself but in order to find the perfect text for my students. The conclusion is simple. There is no perfect text.
Teaching an object-oriented language like C# or Java is difficult. The biggest problem I see is in the nature of the languages themselves. There is quite a bit of “advanced” syntax that must be used even to create a simple “Hello World!” program. For example, a simple C# command line hello world includes the using directive, the public keyword, the class keyword, the static keyword, a void return type, and an array before anything is even printed to the screen. This is just to define the basic structure of a class with a main method. Then there is a call to a static method and the passing of a string literal. So before hello world can be fully comprehended by the student they must understand scoping and visibility, classes, the difference between static methods and instance methods, the concept of a return and worse returning void which is different than returning null, the concept of passing arguments, and what an array is. This is quite a laundry list of concepts when you are new to this whole computer thing.
The complexity of these simple hello world examples in combination with texts that say “Ignore the public, static, void, string[], etc., etc. for now and just assume they are needed” is what leads to students who say “I’m just typing this stuff and I don’t know what it means.” As far as I can tell there are two possible solutions to this problem. First, we could stop teaching these types of languages in introductory classes. Second, we could stop using the “that is beyond the scope of the current example” excuse, in other words explain what needs to be explained as it is needed. Unfortunately, explanation as needed does not seem to fit in with the traditional text book, I guess it would make for a messy table of contents.
The first option has been a long time favorite in some settings. Some students complain that they don’t want to take a course that uses Pascal, or Scheme because they will never use these languages in industry. Some universities respond by saying we are not a trade school. Some respond by consistently switching the preferred language based on industry trends. Both types of schools produce solid engineers, but the best in both worlds take it upon themselves to learn more than one language. From conversations I have had with other programming language learners throughout the years, it seems that for every language that might be used as the “ideal” there are issues. For example, say you use a language with garbage collection. Students then learn to depend on garbage collection without an appreciation for what it really means. A language with only references and no pointer arithmetic is certainly less prone to errors, but the student likely learns much less about the intricacies of how the language represents things in memory.
The second option requires that many “boring” details be explained for even trivial examples. I say boring because whenever I begin discussing the details I find that my class starts to look sleepy, or at least the average sleepiness increases. However, I believe this is a more honest approach to the problem. Programming in fact requires a detail oriented mentality. I believe that students that are new to the subject are done a sever disservice by those who believe that the details should be glossed over. This robs the student of a deeper understanding of the subject. Additionally, it fails to account for one reason a student would take an introductory class, to try it out. In other words the student is testing their fit with the subject, a dishonest representation only hurts the student long term. If they cannot deal with such detailed analysis they will likely be unhappy with a career in software engineering.
The other thing I noted in my search of introductory texts is that some texts give many examples, and some give very few. The better texts give the right amount of examples. The right amount is enough to demonstrate the principle that is being presented in as real a situation as possible ideally in an ongoing series that establishes a continuous example that is not a toy. In other words, the examples should build on each other and there should be a fairly obvious link to reality in the form of a solution to a nontrivial problem from a well known domain. These types of examples provide the impetus for student interest, and a feeling of real accomplishment when learning is achieved.