Like many computer science departments, the languages we teach our students vary over time. When I was hired, we taught Java in Intro and C++ in Data Structures (our CS 2 course). The year I started, we moved to teaching Java in both Intro and Data Structures. (Thank god, because my C++ was pretty rusty at that point.) When I returned from maternity leave in 2008, we switched to Python in both Intro and Data Structures. This was absolutely the right move for Intro, as it’s much easier to get up and get going in Python than it is in Java, but proved a bit problematic for Data Structures—not right away, but down the road, as we found that our majors were less willing to learn new languages since Python was so easy and familiar to them, which in some cases really hurt their Comps (capstone) projects. (Image and sound processing in Python? Bad idea!)
A few years ago, we decided to keep Python in Intro, but switch Data Structures to Java. The switch had the intended effect—our majors are more comfortable learning new languages on the fly, because by the time they’ve finished their first 2 CS courses they’ve programmed in 2 languages. But of course we originally switched from Java for a reason—its steeper learning curve. (public static void main(String args), anyone?) And so we still run into the issue: how do you successfully introduce Java, or any new language, in an early CS course, when the language itself is secondary to the course?
I’ve taught the course twice now under this “new” format, and I think this time around things with the language transition went much, much better. There’s still a lot I can improve, for sure (more coding in front of the class instead of just giving them some code and setting them loose, more small examples at the beginning), but there were a few things that definitely went better this time around:
- I spent a full 2 weeks just on Java. Even though this meant I had to cut down on some things I would normally cover (like my beloved Dijkstra’s algorithm, and some of the finer points of hash tables), I felt it was important to give the students enough time to become comfortable, or at least familiar, with the new language before asking them to dive into the course concepts AND implement them in the new language.
- I started the language transition by providing examples in both Python and Java. I wanted my students to come away from the experience realizing that Python and Java really aren’t so different, and while Java definitely has more overhead, it also has a lot in common with Python. Showing the same code in both languages, and giving them both versions of the code to play with and modify, helped them be comfortable with thinking in the new language. In fact, in many of the early exercises, I encouraged students to write the code in Python first if they were confused, and then translate it into Java. (I also relied on readings that introduced Java syntax and principles in relation to Python: Brad Miller’s Java for Python Programmers, and Ken Lambert’s From Python to Java. The latter is great because it has the same concept presented with side-by-side code examples.)
- I approached inheritance differently. Inheritance is a topic we all agree that students should be familiar with by the time they finish Data Structures. I used to stress inheritance quite a bit early on, having students write subclasses and interfaces and so on in an early project. This time around, we did some straightforward inheritance examples late in Week 2, with subclasses and superclasses, and discussed a bit about abstract classes, but I limited this largely to in-class exercises. Related to this…
- I incorporated interfaces throughout the course, as “code templates”. Students find the idea of interfaces confusing, and rightly so. I decided this time around that I was ok if they didn’t fully understand what an interface was or the instances in which we might use one, as long as they could use and incorporate interfaces somewhat competently in their code. So for every ADT we studied, I gave them an interface for that ADT. I “sold” it as a template for what their methods should look like and how they should behave. I used it to illustrate that we can implement ADTs quite differently and they can still function the same way (and that the end user doesn’t have to and shouldn’t know anything about the inner workings of the resulting data structure). I don’t know how much students really understood about interfaces by the end of the term, but at least they were able to competently integrate them into their code. (Bonus: they made grading the projects much, much easier—everyone’s methods had the same signatures!)
There are still challenges when teaching the course in Java: how and when to introduce generics (I tend to minimize these: students can use them, but I don’t require them to implement classes with generics), finding a textbook that I can live with (still searching), etc. And surely as I continue to reflect on Winter Term as I gear up for Spring Term, I’ll remember more of what worked and what didn’t. But overall I’m pretty pleased with the language-related stuff in the course this time around, and will probably use largely the same model the next time I teach the course. (Assuming, of course, we don’t decide on another language switch between now and then….)