Keep Working, Worker Bee!


Paul Graham seems to be slipping ... :)

Today I taught my last class of the quarter (Friday is the final), in which I gave a lecture introducing computer science, the whole discipline, starting with NAND gates and how you'd coax electricity to behave like boolean logic, and ending up with the P=NP question and the halting problem. I don't know whether my students cared about it, but for me it was great fun.


Well that sucks. We just couldn't get our multilanguage semantics paper together for the POPL deadline; we could've submitted a badly-written, unclear paper, but we talked about it and decided this work was strong enough that it should get a proper treatment. And with teaching and the programming contest and various other scheduling conflicts, I just haven't had time to give it what it deserved. That doesn't just mean that I didn't write it up clearly enough, but it also kept us from identifying a couple of good, small but significant extra pieces of research we should've done. Nothing major, just some extra systems we should've built that would strengthen the narrative.

I'm happy with that decision and I think it was the right decision, but it does create a problem: it doesn't look like there will be a suitable venue to publish this work until at least next year's ICFP, which is more than a year away, and this work is more suitable for POPL anyway (for one thing, it has nothing necessarily to do with functional programming but has a lot to do with the principles of programming languages in general). So I think I'll do the extra research we decided on and then write up a tech report. We'd need to do a tech report version of this paper anyway since at one level it's all about proving type-soundness of a whole bunch of multilanguage systems, and putting it out there as a tech report will finally give me something I can point people at when they ask me what I'm doing. Once a conference comes around that seems appropriate, we'll take the report out and submit it. Not ideal, but probably the best available option. And I'm really confident in the work itself; we continue to find more fertile areas to explore within the framework we've made. I think when we put the report out you'll agree that it was worth the wait for us to do it right.

Anyway, from other fronts: my class seems to be going well and we actually managed to go a little faster than they did during the regular year. I think they've been able to absorb things pretty well, though the stuff we did at the end (graph algorithms in various guises) is pretty tough for people with only five weeks' experience. We'll see how much they've retained on Friday when they have their final.


Been a little while since my last update. I've essentially been working on most everything I do, all in little bits.

The morning I spent dealing with a few different PLaneT issues. First, I fixed a bug in the webpage generation code that I swear I've fixed before; it was actually the confluence of two bugs, one of which was that "metaprogramming" was inadvertently left out of the list of possible categories and the other of which was that packages with no legal categories were inadvertently getting omitted from the web page entirely rather than being filed under "Misc" as they should've been. Both bugs are fixed now and a few packages that weren't getting listed before are showing up. I'm just about sure I fixed this exact bug long ago, so I have no idea why the problem re-emerged. Strange. The second bug was actually a bug in DrScheme; it turns out that you can't distribute a new language level using PLaneT because of an assumption DrScheme made that worked at the time but got invalidated when PLaneT came along. I'm not going to fix that one myself, but the proper people got notified so hopefully it'll be fixed soon.

On my class front: I taught accumulator-style recursion and generative recursion, capped off by teaching the topological sort and breadth-first search algorithms today. I don't know how well my students would do if I asked them to reconstruct those algorithms from memory, but they seemed to be able to follow along well enough during class so that's good.

I'm also writing a paper for POPL, and despite the full-time job of preparing for my class I've been able to make some decent progress on it. I've got a draft and I'm currently going over it again, revising prose and fiddling with formalisms and so on. I think it's pretty interesting stuff, though as with everything it's difficult for me to judge it having worked with it so closely for this long. And as with anything theoretical, I'm constantly in fear that everyone but me will think it's obvious and not worth spending a whole paper talking about. We'll find out what the editors think.


So if you recall from yesterday, I was really worried about the test I was set to give today. It's amazing, I honestly was worried to death about whether I'd made the test too hard, whether nobody would be able to finish it, and so on. I was convinced by several people that I'd made it too long for an hour, so I bumped up the time to two hours, but I was having horrible visions of nobody being able to finish even in that time and having everybody fail and hate me.

Well, I gave out the test today (here it is, in case you're curious). First of all, four of my six students finished in one hour. Second, I actually think it was too easy for most of them — pretty much everybody got the idea of everything, and most pretty much did everything right. If I'd have known that, I probably would have changed problem 2 to deal with 2-3-4 trees instead of plain trinary trees and I'd've made the function they had to write for it something fancier, maybe making them drop every leaf to the minimum value a la Dave's example (albeit not using Haskell craziness and therefore not nearly as awesome).

I learned a lot about test-designing mistakes from the responses I got. The first problem wasn't clear enough about how I wanted each kind of data represented, which led some people to give superheroes an integer number of powers rather than a list of powers as I'd intended. My fault; I'll do better next time. I also really should've made people write me a third function using map at the end of problem 3; without it students can pursue the "smash two functions together with a cond and switch based an a symbol" method of abstraction and not hit a brick wall at the end that makes them rethink their logic. Also, I awarded way too many points for the bonus. Ten would've been plenty. I will do better on all these fronts in the future.

But overall: the test went great, and I am completely in awe of my class for doing as well as it has. It's only been three weeks since they wrote their first program, and now a test everybody told me was too hard and that makes them come up with their own tree representation and discover map on their own turns out to be too easy for them. If you're one of my students: you rule, a point on which I'll elaborate on Monday. :)

In other news, the programming contest phase 2 starts tomorrow morning. I stayed in the office late working on it (which is why this post is appearing now, quite a bit after worker-bee bedtime). I'm glad I did; I didn't actually do anything useful, but I was convinced that there was a potential bug lurking somewhere nobody else thought there'd be a bug, and due to my insistence two of us made a somewhat complicated test case to find it. That test case proved me wrong, but at the same time exposed another bug that happened to be the very bug that was completely dumbfounding the third member of the team. So, uh, I rule indirectly.


Today was essentially dedicated to the craft of test-writing, a craft to which I'm not at all accustomed but I found I actually kind of like. I'm glad to report that I'm a perfectly decent Java programmer, at least according to the midterm exam I took for my officemate, who's giving the test to his Java class tomorrow. He, as it turns out, is also a perfectly decent Scheme programmer, though his Scheme is possibly slightly rustier than my Java (I didn't even know that was possible!). My test is going to be pretty tough, I expect, but I think also fair. I'll find out tomorrow, I suppose.

The process of writing a test itself is really difficult, particularly for an intro class midterm — these are people with barely any programming practice at all, essentially anything they could possibly do on paper in any reasonable time looks easy to me. Writing a good intro test, then, seems like a game of extraordinary empathy, where you have to really put yourself in your class's shoes and figure out exactly how much it takes to challenge them but not break their backs. My initial draft was probably on the tough side, and the point weightings for different problems were all over the place, but I think I've rebalanced and tweaked things to the point where the test is probably fair. (Ironically, I made the test easier by approximately doubling the length. That's because I rewrote problems of the form "Do task A" to problems of the form "1. Do subtask X. 2. Do subtask Y. 3. Do subtask Z." Many more pages, but the result is that you don't get hit with one big problem, you get hit with lots of littler problems telling you how to do what you would've had to do anyway.)

In the process of writing the test, I ended up ditching the TeX macros I was writing for the problems in favor a Scheme program that takes a logical test description and spits out LaTeX. It's amazing how much easier it is to generate LaTeX using Scheme programs than it is to generate LaTeX using LaTeX macros. I was able to add quite a bit to what I was able to express and make the code much simpler. (Probably I just don't understand LaTeX very well, but I've been using it for a long while and the Zen that makes everything make sense and work beautifully has not yet hit me.)

Other than that, the only major thing I did was one more revision pass at the programming contest phase two specification; lots of red ink but the spec looks like it's in good shape and hopefully the contestants will like it.


Today I got to the point in my course when I was finally able to teach my students why you see a big lambda every time you start up DrScheme. As I was explaining it, something clicked for me about why the HTDP curriculum works. As has been said many times before, it's not syntax-based, which is definitely good — you don't want your students thinking that they need a new piece of syntax for every problem or that the kinds of syntax available in language X are somehow a mirror of the kinds of problems in computing. But what's not so obvious is that once you're teaching, you start to realize that it's actually small-step semantics-based. Unlike SICP, which doesn't seem to have much of a unifying pedagogical principle, I've started to realize more and more that the secret weapon of HTDP is that you teach the students a simple algebraic-simplification-based view of program evaluation, and then slowly enrich the set of reduction rules in the language and show them what tricks are possible with those new reductions. That's why the introduction of local (a teaching form for introducing internal definitions) becomes a big deal in HTDP, whereas introducing lambda is not all that big of a deal — local is a new kind of reduction rule that adds definitions to the world; lambda on the other hand just follows the same rules we've been using all along.

That's not to say that students don't still need to practice and struggle with both local and lambda to figure out how they tick; that's more of a pragmatics issue. But as far as explaining them, when you get to lambda, you just say, "Remember our rule for how to simplify named functions? You do that here too." Then you do an example or two, and pretty soon people are able to feed you the right answers when you ask what to do next and they've got their first handholds on a concept that might otherwise be very very difficult to grasp.

I have appreciated the pragmatics of HTDP, in particular the design-recipe idea, for a long time, and I still have to say that the notion that data leads directly to code is a fantastic first lesson in programming that's underappreciated in most curricula and by many professional programmers. But I hadn't until just today appreciated the powerful impact that taking a very careful look at the semantic model you're teaching your students when you introduce them to programming can have.


After a very relaxing July 4th weekend, my nose was back to the grindstone today as I finally got to some long-overdue PLaneT work. PLaneT is now up to date with the rest of the PLT's infrastructure: the server is using the latest PLT build from subversion, PLaneT's web page uses the new web page look, and most importantly a really longstanding bug in the way archives got unpacked was fixed (in an embarassingly simple way) the result of which is that documentation is properly linked on the PLaneT page again. (I went through and fixed all the old packages that were affected by the bug, too, so the page should now work.)

This smacks of software development to me. I'm not sure whether it's a good or a bad thing that I'm in a research group that does real software development alongside its more academic pursuits: on the one hand, I'm getting lots of experience with real development that I wouldn't get in most places; on the other, every time I spend a half hour tracking down a crash bug that turns out to come from the fact that ImageMagick is installed on my development machine but not my production machine is a half-hour of my life that's not contributing to anything except ulcer development.