A recent article in ACM Inroads caught my attention after it was posted and discussed on the Computer Science Education: Research & Practitioners Facebook page. The article, which is quite a long read, discusses a paper published back in 2014 about an fMIR study that showed when students were trying to understand a piece of code, the parts of their brain that activated were the parts of the brain associated with language, not the parts of the brain associated with math and logic. The author of the Inroads article, a high school computer science teacher by the name of Scott Portnoff, takes aim at computing education and holds no punches in attacking the historical teaching practices as well as current efforts to broaden exposure to CS in secondary education through survey courses that don’t actually teach programming skills. It’s an interesting read.
What really got my attention though, was this main idea that learning to program is like learning a second language. As I read through the article, I saw a lot of parallels between what is considered best practice in second language acquisition, and what we have done with our fully flipped, lightweight teams, active learning intro programming classes. Here I’m going to highlight four findings from the article and how they fit with what we are doing in remaking our programming courses.
- The traditional prescriptive linguistics approach to teaching a second language (by teaching the grammatical structure) was abandoned decades ago because it is less effective than implicit, immersive approaches. In our media computation-based CS1 class, we spend the first month leading students through engaging programming labs with very detailed instructions on how to make Turtles draw fun pictures on screen. We don’t mention objects, classes, methods, variables or any other programming constructs, but we get students to learn how to make the turtles do fun stuff and increasingly encourage them to play with the code to make the turtles draw more interesting pictures. After the first month, we start explaining the concepts behind the code. By then students have already been programming, but they aren’t bored or turned off. They’ve been immersed in something enjoyable, and as we explain what a method is, they have a non-abstract example (turtle draws hexagon with these separated 6 lines of code) that helps them to understand the concept and it’s usefulness.
- Learning a second language takes time. Our students come in with widely varying backgrounds in terms of how much programming they have previously done and the students who have more experience fare better (this has been empirically demonstrated with a lot of studies as well). So, it’s really important to set appropriate expectations for students who haven’t programmed before – we tell them repeatedly that learning this simply takes time, and they shouldn’t expect to be able to be awesome programmers after a single semester. This is also why I consider the Data Structures course (which is the third course taken by our majors) to be a continuation of intro programming. If you study a second language at university as your major, you have to take four semesters of that language before you are considered to have achieved some level of competency and fluency.
- Learn a second language deeply before trying to learn a third. Students who gain full competency and fluency in a second language can pick up a third language more easily than students who try to pick up a third language when they only have minimal acquisition of a second language. Similarly, it doesn’t make sense to change programming languages in the middle of learning to program. When I arrived at UNCC, the standard programming sequence taught was a first course in procedural C++ followed immediately by a second course in object-oriented Java, after which students are expected to be able to do basic programming. This is like thinking a student should study a semester of French (an indo-european language) and then a semester of Mandarin (a sino-tibetan language) and have proficiency in speaking foreign languages. Moving from procedural programming to object-oriented programming is hard. Moving from one programming language to a second programming language, when you haven’t had time to master the first one, is confusing. Combining these two things together is a disaster. Of course we want our students to be able to learn other programming languages, but this is likely to be easier if they have acquired deep competency in their first programming language. What that language should be is an entirely different discussion. When we developed our flipped, lightweight teams series of courses, they have all been taught as objects-first Java.
- Practice. This is an element of secondary language acquisition that is really important. Students need to practice using the language frequently in order to gain competency. The flipped, active learning approach involves in class activities (peer instruction quizzes, parsons problems, etc.) that give students small bits of practice looking at code (reading), talking about code (listening and speaking), and producing code (writing). In a traditional lecture and lab class, students only get practice with the reading and writing part in the lab. They may get some practice listening to one person (the instructor) while in the lecture. With our team-based version of the class, where they spend 3 hours a week in class talking with others about programming, and reading and writing programs plus 3 hours a week in lab doing pair programming exercises, they are doing all of these fundamental practice activities (reading, writing, listening and speaking) much more frequently.
One aspect of the article that I found really interesting was that the author claims to have had good success in getting students to learn programming by forcing them to memorize small programs or code segments. The idea is that by memorizing these, students internalize the structure. He says that after doing this, the number of syntactic errors students make is greatly reduced, and presumably this means that they can then focus more on understanding the semantic meaning of programs. This is not something that we have tried. I have to admit, forcing memorization doesn’t sound fun. So, I’m going to think of a way to implement this so that it is fun. Perhaps this is a good candidate for gamification.