Children generally learn to speak their mother tongue by the age of three without explicit teaching from their parents. Is it possible for our computing students to acquire a programming language in the same way that children acquire their first natural language? This paper explores such a possibility and presents an approach to teaching a programming language that does not involve explicitly teaching the syntax of the language. The students learn by examples and by active participation.
Many educators in computer science would agree that CS1 should not simply teach programming in a specific language. In particular, instructors should not just teach one syntactic feature after another to the students. However, many instructors may still teach in that fashion because they feel that students cannot write programs without a discussion of syntax. The non-teaching approach proposed in this paper frees up valuable class time because we use no explicit presentation of syntax in our approach (NEPSA). As a result, students have time to improve their problem solving skills, learn program design, develop an appreciation for the aesthetics of programming, and be given an overview of some of the areas of computer science.
This method was first put into practice in the fall of 1992, teaching Pascal in a CS1 course. Later the method was used to teach Modula-2, and then C++. Students who have completed CS1 generally gave positive feedback regarding the teaching methodology. However, this method of instruction may not work for all students. Section 3 of this paper discusses students' success with regard to this pedagogy.
Keywords: NEPSA(no explicit presentation of syntax approach), programming language, CS1, programming, syntax, teaching, learning.
Day to day we are faced with new computing technologies, and rapid change in the field of computer science compels us to have a dynamic instead of static curriculum. However, the way in which computing is taught has not changed quite as rapidly as its underlying technology. In particular, the teaching of programming in a particular language is still the focus of CS1 at many institutions. Almost twenty years ago CS1 was a course in programming in Pascal, and even now for some of us it still is.
The report Computing as a Discipline [1] promotes a breadth-first approach for introductory courses in computing. The report identifies nine subject areas in the field of computing as crucial to the discipline and delineates the three processes of theory, abstraction, and design that are inherent in the nine subject areas. With a breadth-first approach, beginning students in the discipline can discern the misunderstanding that computer science is simply programming. The ACM/IEEE-CS Computing Curricula 1991 report [2] further expands on the Computing as a Discipline report and presents a complete set of recommendations for the entire undergraduate curriculum. It is worth noting that programming occurs in all nine subject areas, and thus has a major role in the curriculum.
We do not want to focus on just programming in CS1, and we certainly do not want to simply teach the syntax of a language when we teach programming. Some of us have already started to teach CS1 differently [3, 4, 5]. But, quite often when the teaching of programming happens in a course, it is hard to avoid spending significant time presenting syntax. Instead, one would rather spend time teaching important programming concepts such as abstraction and design. If we choose t o use Scheme in CS1, there is less syntax to teach, but what if we are teaching C++? Regardless of which programming language is taught, the majority of textbooks still present programming in very much the same way, i.e. learn the syntax, and write some little programs.
We seem to be at an impasse in wanting the students to master programming, and yet not wanting to spend a lot of time discussing the syntactic features of a programming language. Our approach to this problem is to let the students learn a programming language in much the same way that they learned their mother tongue. After all, our parents never taught us the syntax of a language and yet we have all managed to learn how to speak.
First of all, let us take a brief look at how children learn to speak their mother tongue. From the day a child is born, he is bombarded by language all around him. The child may be spoken to directly, or he may simply be listening to conversations that happen around him. As the child's vocal cords develop, he is first capable of imitating sounds that adults make, and from that he quickly progresses from uttering phonemes to babbling words. By the age of three, most can form complete sentences. Although the child's grammar may not be one hundred percent correct, he soon corrects himself without any interference from his parents. It is interesting to note that attempts to correct a child's grammar do not accelerate a child's learning. A child will correct the grammatical rules that are forming in his mind when enough evidence has been presented to him to support such a change [6].
Many studies have been done to investigate the process of language acquisition. It seems that humans have an innate ability to learn languages, and yet one must nurture a child in a suitable environment before a language can be acquired [7]. The educator, John Holt [8, 9, 10], who taught and observed children for his entire career believes that children are research scientists, that they learn by observations and experiments, and then they formulate hypotheses and rules, and update them as new information presents itself. He discovered the simple truth that children want to make sense of the world that they are in, and with that curiosity, they can learn anything as long as they are exposed to it. A provocative observation made by Mr. Holt is that "Learning is not the product of teaching" [8].
In fact, not just children, but all humans are constantly learning from everything around them. So, a student should be able to learn a programming language just by being exposed to a lot of examples of programs and be given many opportunities to write programs, make mistakes, and interact with others who either know or are learning the same programming language. This is the theme of the no explicit presentation of syntax approach (NEPSA) that is presented in this paper. In the next section, we discuss how to conduct classes that follow this approach. After all, there are quite a few hurdles to overcome. A child has a few years to learn a language, whereas a CS1 student only has a semester. In addition, a child learns because he is curious about the world around him and really wants to learn, but not all students are motivated and want to learn just for the sake of learning. And last but not least, a child usually has loving parents who are constantly paying attention to him and have infinite patience with him. Can instructors treat their stu dents the same way? We discuss these issues in subsequent sections of this paper.
NEPSA was first put into practice in the fall of 1992 in a CS1 course that taught programming in Pascal. Subsequently, it has been used to teach Modula-2, and then C++. In the Pascal case, the students had no previous programming experience, but since then, the students have had some small prior exposure to programming. In this section, we discuss how the course is taught using this approach without reference to a particular programming language since it works in much the same way regardless of which programming language is chosen.
As mentioned in the last section, one of the problems we have to face is a time constraint. The students do not have the luxury that children have, that is, they do not have unlimited time to learn the programming language, but just thirteen or fourteen weeks. This is not sufficient time to expose them to enough programs and practice for them to formulate the grammatical rules of a language all by themselves. Thus, there are some pedagogical components without which NEPSA would not function very well:
In NEPSA, the students are often actively participating, either in teams, in labs, or together with the laptop computer. This is quite different from the traditional lecturing style where students remain passive, and according to one of the studies on students' attention span quoted by Meyers and Jones, "students are not attending to what is being said 40% of the time" when the instructor is lecturing [12].
Having listed the basic components, we now give an overview of how the approach is applied to the day to day classes in CS1. In particular, we discuss the contents of the first week of classes as we consider this to be a very crucial week of the course in NEPSA.
Unlike little children who are very curious to learn, many students may be quite used to being spoon-fed, and expect to sit passively in class everyday and diligently transfer materials from the blackboard or overhead transparencies to their notebooks. For this reason, NEPSA is explained to them on the first day of classes so that they know what to expect from the course. They are told that they will learn the programming language under study in much the same way that they have learned to speak their mother tongue, so many examples will be shown with the use of the laptop computer and the LCD projector, and much interaction is required of them. In addition, the students are told that they will be shown programs that use almost all the syntactic features and programming concepts that they need to learn in the course right from the start. After all, a child does not learn to speak by hearing simple sentences first before he hears adult conversation. By the same token, programs that are shown to the students would not be trivialised and would not just show one syntactic feature at a time. Thus, there may be much confusion for the students in the beginning, but the grammatical rules of the programming language will soon become clear as more examples are seen and written. The students are made to realise that learning will not happen if they do not participate actively, and most important of all, they need to have the curiosity to learn like little children do.
After the explanation of the teaching methodology, the rest of the first day of classes is spent on demonstrating the software life cycle through an example. The final programming assignment from the same course in the previous term is usually chosen as the example. This allows the students to have an idea of what they are expected to know by the end of the course. First of all, the students are shown the solution to the programming problem on the LCD projector. Next, the program specification, analysis and design of the chosen problem are presented on prepared overhead transparencies. Then the completed code is shown on the LCD projector and briefly discussed. Sometimes alterations are made to the code to demonstrate different kinds of errors and the process of debugging. The students are not expected to understand all the materials that are presented, but rather, develop some knowledge of the process that will happen each time they write a program.
The second class of the week is spent on a new problem. Since this is the first programming problem for the students, it is usually a simple one that requires no more than a page of code. The class is divided into teams at this point so that students can help each other. The program specification is given to them, and then the teams are given half an hour to analyse the problem and design a solution in terms of an algorithm. Again, this is the students' first attempt to formulate an algorithm, so quite often their algorithms are not very well-defined. This also improves over time. Next, the designs from each team are placed on the blackboard and the whole class would discuss the correctness of each. We then translate the correct algorithm into code and debug together on the computer. Finally, prepared overhead transparencies are shown to the students that present the programming concepts that were encountered as well as the syntactic features of the programming language under study that we have used. The summary is intended to be brief, so the students are given a copy of the overhead transparencies and no note taking is necessary.
Each subsequent class follows pretty much the same pattern. We first clearly state the requirements specification of a programming problem, and then we spend quite some time on analysis and design. In the beginning of the course, we would spend time on writing detailed algorithms step by step. Further on in the course, we would still spend time on designing a solution but will not be writing the algorithmic details of each module that is designed. The coding and debugging are always done on the laptop computer together, and the students can see the ongoing process on the screen via the use of the LCD projector. All this is followed by a summary given on overhead transparencies a copy of which are given to the students.
The process that we have described is very time-consuming. Since time is so limited already in the course, we do not always write every single line of code together. There are many variations to the coding portion of the process. Sometimes the students are shown the completed program after their analysis and design phase. If the problem is large, then we show multiple versions of the program as it was developed, so that the students can see the development of the code but without wasting class time to write it. The students may be asked to expand or update the program. Sometimes the students are asked to complete a partially written program. This again has many variations; different teams may be asked to complete different stubs, and then we piece everyone's contributions together, or everyone tries to complete the same stub and the best one is entered for debugging. Other times the students are shown a program that has bugs and are asked to correct it.
When a program is coded from scratch, we always follow good programming style and write the documentation together as well. As children learn from copying what their parents do and not what they say, students too learn from copying what their instructors do. So it is not enough to verbally stress the importance of good programming style and of documenting one's code as one is programming, but actually religiously follow one's own advice as one is coding in class. In fact, after NEPSA has been adopted, we have noticed more students coding in a top-down, modular fashion, with proper style, and actually making use of stubs and drivers as well as writing comments as they code.
Thus, this approach of letting the students learn by their own initiatives and by seeing many examples is one that requires much planning on the instructor's part. First of all, one should choose interesting problems for the students to solve. Secondly, one must be aware of how much time should be allowed to solve a particular problem, and plan the best way to allow the completion of the program in the given time frame. Thirdly, the class must always be directed as they work; otherwise, the whole process would take too long to complete. And lastly, the summary that is presented on overhead transparencies must be done ahead of time so that all the students can have a printed copy as the materials are reviewed.
Many students find that the course is going too fast at the beginning, and indeed they should! After all, to be introduced to procedures, functions, parameters, repetitions, conditional constructs and input/output all at the same time right at the start of the course is likely to be quite a shock to most students. However, the students are reassured that confusion is normal at the beginning as it would be for a child who learns a language for the first time. Also, it is natural to feel confused if one is used to learning through listening to lectures instead of participating actively; studies have shown that "change required by learning something new is profoundly unsettling for many people" [13]. Those students who want to learn programming and who are willing to work hard always find the course rewarding, and NEPSA effective as they have mentioned in their evaluations of the course. In fact, some students even express joy and feelings of success in class when they have finally understood or mastered some programming concept after it has been introduced and used for a while. For both the instructor and the students, it is certainly a fulfilling moment when one realises that learning is truly happening.
The use of NEPSA has not changed the attrition rate in CS1, but instead of having students dropping the course every now and then throughout the course until the last withdrawal date, we found that most of the withdrawals happen within the first two weeks of classes. Those students who want to take the course for an easy credit but are not interested in computer science, or those who do not want to think for themselves but rather be spoon-fed quite often drop the course within the first week. This is advantageous to both the instructor and the students. For the instructor, it is certainly much more pleasant to teach only students who are dedicated and interested in the course. And for the students, they can find another course to take right at the beginning of the term instead of dropping half way through the course and having no other alternatives. When this approach was first introduced, the programming language that was taught was Pascal, and usually a handful of students have already learned Pascal from high school. This approach managed to keep those students interested in the course material whereas previously these students find the material at the beginning of the course too trivial and do not pay attention or even come to class.
When comparing examination results of students who learn under NEPSA to those who do not, there does not seem to be a discernible difference in their performance. In fact, we have noticed that under the new approach students rarely fail the course if they have applied themselves throughout. Those who do not would have already withdrawn at the beginning of the course.
NEPSA has worked well in teaching different programming languages in CS1. However, a programming language with more complex syntax would require more time for students to learn. In the fall of 1995, C++ was taught, and we introduced object-oriented design and programming to the students, and because of the extra materials involved, we found that the students need more help to learn the syntax of C++.
In the last couple of years, we have also tried to expose the students to other areas of computer science besides programming. Since class time is not used on explaining syntax, we find time to have interesting discussions on different areas of computer science such as artificial intelligence, numerical computation, database, analysis of algorithms, etc. In fact, NEPSA allows us to choose problems in the different areas to discuss and solve. When the problem is to write a little game, we would discuss the field of artificial intelligence. When the problem is to solve equations, we would discuss the field of numerical computation, and so on. The students can obtain a wider view of computer science which is not possible if only the syntax of a language is taught.
In summary, the emphasis of NEPSA is on motivating and inspiring a student to learn computer science for the sake of learning alone. The computing materials are presented as a unified whole with many practical examples right from the start. We expect the students to acquire a programming language in a manner similar to how they have acquired their native natural language. We try to create a classroom environment that immerses the students in the creation of programs. Much of this is done through group work and we place heavy emphasis on problem analysis, program design, maintenance, proper documentation, as well as good programming style. NEPSA does not work for students who do not wish to learn programming, who do not wish to think for themselves or are unwilling to apply themselves through ha rd work. As pointed out earlier, these students usually drop the course at the beginning of the term. And for those students who want to learn, this approach allows them to learn under the guidance of the instructor rather than through explicit teaching, and we believe that techniques learned this way are likely to sta y with the students instead of being forgotten after the examination is over.
We have mentioned that the instructor must plan each class quite well for this method to reach its full potential. In addition, it is quite important that the instructor have a passion for teaching, loves his students, and is eager for the students to learn. We know that the seemingly invisible components of love and attention really play an important role in a young child's learning process, so too this same component is vital to students who learn by a non-teaching approach.
Eliza Kuttner
Department of Computing Science
Capilano College
N. Vancouver, B.C., Canada V7J 3H5
ekuttner@capcollege.bc.ca