Audience: This was sent to a list of people familiar with the pedagogy of the TeachScheme! project, most of whom plan to start with one term of Scheme and move on to one term of Java.
I've just turned in grades for my first-term intro course, the first I taught under the influence of HtDCH. It's not the straight-up HtDCH plan, because I didn't start in Scheme; that meant some things went slower, and I had to cover things that graduates of HtDP could be expected to know. However, I think it went well enough to pronounce it an overall success; I have a lot of notes about things that worked well, things I screwed up, and so on, that I thought might be helpful to the readers of this list. Most of the comments apply to HtDCH teachers in general, but some are more applicable to those of you that (for whatever reason) start right out in Java. I have a course pack that I'm writing for this starting-in-Java version of the HtDCH pedagogy, which is kind of like a textbook except that it's light on exercises and solutions, and it's not finished yet, but if you're in the same situation you're welcome to look at it.
The inventory system (which in the HtDP design recipes is called a "template") was a huge, huge win. Early on it seemed like overkill, and I was starting to doubt myself on whether it was worth it. Some students even commented on it; they kind of saw the point of some of the other things, but why the inventory?
Then, a week or two later, when we hit recursion, the payoff came. I was able to have them "take inventory" when they ran into the brick wall; and they all knew how to do it! Not all of them believed that it would work, of course. The carefully-written method descriptions ("*determines whether* the *given String* is contained in *this* StringList") helped there. (This is exactly what HtDCH taught, of course. I'm just warning you, if you've never done it before, to teach them and hold your ground. :)
The reason I didn't call it a template is twofold. First of all, it's not really a template, because it's not like a form where you fill in the blanks. The listing of fields is not necessarily in the order it eventually will be, and you cross off a whole bunch of stuff. Also, as time goes by you won't be listing *all* possible field accesses. The second reason is, Java being somewhat more syntaxful than Scheme, I've provided my students with actual templates for writing the code for classes and methods, and I wanted "template" to only mean one thing. Besides, I think "inventory", as in "taking inventory of the available tools", is a much better word for what you're doing in step 4.
Even if you don't believe deeply in functional programming, delaying mutation as long as possible is a good idea. The folks coming from Scheme don't need convincing there, I'm sure, but even if you start right out in Java, there is a huge advantage to using mutation-free code: you don't need to talk about reference semantics! The idea of multiple arrows pointing to the exact same object is one it took me the better part of a term to hammer in, before, and it distracted from other, more fundamental things. But if you can't ever change an object once it's created, it doesn't matter. They can think of one object with multiple references, or multiple objects, and either will serve as an adequate mental model.
I do wish I hadn't deferred mutation quite as long as I did, though. For various reasons not under my control, I do need to cover it at *some* point in the first term. It ended up falling late enough that I couldn't squeeze it into the last homework, and so they didn't get any practice with the idea of reference semantics. I slipped a box-and-arrow diagram problem onto the final, and it is clear in retrospect that about half the class just didn't get that (say) the back half of a list returned by append is *exactly* the list that was passed in to append.
I still can't decide whether it was worth it to slip in interfaces when I did. I don't think I was able to really motivate them as distinct from wholly-abstract classes; indeed, until you get to the idea of implementing multiple interfaces (which I sure don't, not in the first intro class!), you don't need interfaces. I think this confused some people. On the other hand, I feel that implementing an API interface such as State (about which more later) is different philosophically from extending an abstract superclass like Shape; I suspect this nuance may be too sophisticated for the students, though. I think I may skip interfaces next time and put them in my last day "Java syntactic sugar we haven't covered yet" lecture.
An idea I kind of stumbled onto but will choose consciously next time: don't bother explaining the distinction between "program-based" and "event-based" programming (or whatever you want to call them). Program-based coding doesn't make sense outside of a terminal window, and they don't really see it in an HtDCH-style System.out-free intro course. They go straight from making objects and calling their methods directly to writing event-based stuff---writing onTick and onKeyEvent methods and letting the library run the event queue. Again, I think this is more of a pedagogical trap for the people starting out in Java, especially if they have taught a different style before, and/or if they are using some other book.
More on the event model I used. The draw.World system is okay for the people who started out in HtDP and Scheme, for whom the Java version of draw.World is just a new syntax for a system they already understand. There were a number of things I didn't like about it, however, which caused me to write my own library on top of it for my students to use. The chief differences from the stock draw.World library are:
There are others, but those are the main ones. I also implemented the library over both ProfJ and AWT, so it can be used in BlueJ or anything else, if that works better for you. (I believe Viera has a draft version of draw.World in AWT or Swing, so if you just want the portability you could probably use that.) My library is about to undergo some revisions to reflect what I learned this term, but once that's done, y'all are welcome to use it. Drop me an email.
The biggest problems I ran into were towards the end of the course, as I introduced without good motivation some of the concepts that I'm expected to cover in my intro class. Access control was one of them, and there I think I can get by with less next time---I was still under the impression that "public" was required in certain places that it actually isn't, so I can just sort of gloss the software engineering ideas and ease them into using public/private/protected a bit more gradually.
Another was "static", and this was mostly just my own bungling. I tried to be clever and say that "static" could be used on any method that never made reference to "this." (since I had been requiring the use of "this." wherever possible). Unfortunately, this rule is neat, simple, and wrong, because of recursion. :P I then amended it to "other than for recursive calls", but even that ran into problems: in fact, in a recursive method, you have to remove the "this." if you make it static. So I need a better way to approach this.
Mostly, I just need to think about better ways to weave various ideas in.
The only feature I slightly wish I could have covered earlier, but ProfJ
prevented it, was exceptions. All through the class I had to keep
deferring questions about "what if the user gives bad input?". I told
them to assume that wouldn't happen, but it's good that they're thinking
about it, and there is an elegant solution, but we haven't seen it yet.
(On the other hand, I can certainly appreciate that they're a very
complicated concept that one might want to defer for a long time.) Hm,
I wonder if I could/should include a class and method in my library that
would let them do
Error.abortWithMessage("This method can't deal with negative numbers.");
Ew, but not until after they've seen void methods. Well, maybe I can somehow make it work. Maybe I'll just drop it and keep deferring them; it just grates a bit to take such a good learning moment and keep passing it by.
For ProfessorJ, I have mostly praise. The comfortable straitjacket it provides for the beginner programmer has caused a sea change in how the students progress. They get past their syntactic problems a lot faster when there are less ways to get stuff silently wrong, and I think requiring the use of "this" was singlehandedly responsible for keeping at least a quarter of my class afloat in the first weeks. The ease of writing examples and test cases meant that my students actually did so (mostly), and this too was a big help. The only thing that really holds me back from wholeheartedly recommending it for use isn't even really its fault: it is still, fundamentally, alpha software. Kathy is really responsive at fixing things, and it's way better than it was three months ago, but still, if you use it you should be prepared to work around at least one or two bugs at some point. (For instance, in my String lab my students hit a bug (since fixed) where String's indexOf just didn't work!) If you do decide to use it, have a backup plan; I had a full lab install of BlueJ waiting in the wings, and when there was a wonky, unfixable interaction between my library and ProfessorJ, I was able to slide in my "intro to BlueJ" lab and move on from there. Again, this is not at all meant as a slight on Kathy or ProfessorJ---I knew what I was getting into when I picked alpha software for my IDE. :) Indeed, if you can be moderately flexible and have a backup plan, I think ProfessorJ is an amazing tool. Its Beginner level in particular seems quite solid. I know I'll be using it again next term.
One change I'm sure to make is that I'll be way more draconian about coding conventions. Uppercase classes, lowercase everything else. Indentation. Sensible naming. I saw so many people having a hard time debugging their mixed-case code, or forgetting a close-curly in their left-justified code, that I'm _positive_ it will help them overall, even if they claim that it's not the important thing and why can't they just focus on the other stuff.
Sorry that turned out to be so long. Hope it's helpful for someone out there.