Wednesday, April 10, 2013

Rearranging RB104

My Advanced Programming (CS222) class meets in RB104, which is an unremarkable classroom, as evidenced by the following photos.

Student view from the corner
Instructor view facing side
Instructor view facing back
On Monday, I told the students that they had five minutes to rearrange the room to better suit our needs. We have been working together for over ten weeks, and they know what kind of thing I like to do. I suggested that they begin by explicitly identifying their design constraints, then moving into implementing a plan. I offered that after five minutes, they could get another five by simple majority vote, but only once. Then, I left the room.

After five minutes, I poked my head into the room and asked if they needed more time. I was greeted by a clever little barricade built from an overturned table, but it did not stop me from seeing that they were asking for another five minutes.

Another five minutes passed, and then I made my official return. The first thing I noticed was that most of the chairs were pushed into the back of the room, and in their place, the students had constructed four circular arrangements of desks.

View from instructor's station

Detail of center group
One of the clusters had no one sitting at it, and it was the only one with a trash can in the middle.

View from front center, looking left
The next thing I focused on was the odd construction at the front center of the room. Notice the eraser inuksuk, which was just completed as I entered.

Front center
I have a grad student, Jason, who is sitting in on the class. He always sits in the back center of the room, behind the last row of chair-desks. The students pointed out that they had left his chair accessible to him. I pointed out that it looked a bit like the kind of fort my boys would build in the family room:
Rear center
With this revised arrangement, I proceeded with a fairly normal class. First, I brought up the rubric I used to evaluate their first milestone submission on our six-week project, and I discussed the trends that I saw in the submissions. Then, I led a discussion of Alistair Cockburn's articulation of Human Success and Failure Modes, which I have written about before. I distributed a handout that summarized the key points and then explained and interpreted them. Then, I asked the students to get into small groups with people not on their project teams to discuss how they have witnessed these success and failure modes. This kind of structure—my introducing an idea and then asking them to discuss it in small groups—is fairly standard for the class.

I will share a few of my observations of the students' room design. First, because the students were facing each other, about half the class had a physically awkward time listening to me: they had to twist awkwardly in their seats, and in some cases, they simply kept their heads bowed and faced away from me. Second, many students could not see the whole projected screen, where I was showing the project rubric: the sculpture at the front of the room obscured their view, as the shadows in the photograph above demonstrate. Third, and perhaps most difficult for the students to observe, I didn't have a table to sit on, and this made me uncomfortable. When I am explaining concepts to the students and not using the projector—as with the Human Success and Failure Modes discussion—I like to sit on the table. It puts me just a little higher than them so they can all see me, and I can be in the middle of the room and talk to all sides with an informal air. Without that, I found myself stuck at the teacher's station, where I could set down and pick up my coffee cup easily. I felt like I was talking directly to the circle of students before me, and less so to those further away. Finally, when I did move around the room, I noticed how much easier it was to move from group to group compared to having twenty unused chair-desks in the way.

Toward the end of the meeting, I asked the students to individually write evaluations of their design. Most of them mentioned foregrounding the small group work, knowing that it was something they did regularly. As one student put it, "it's much easier to have a discussion in a cluster formation already facing your group." Several of them pointed out something I had not noticed: they had purposefully positioned the clusters next to the chalkboards, knowing that I regularly have them write notes and diagrams on the board. The only individuals to write about how the "art" at the front of the room blocked the projector were those in the group closest to the instructor station—those whose view was actually blocked. It makes me wonder if the other students didn't notice or if they simply didn't find this worth writing.

I find it interesting that they created four clusters of desks and also rationalized these as being for group discussion. There were six teams created for the six-week project, and since these groups were formed, we have used these teams as discussion and activity groups during class meetings. However, some of the groups have very poor attendance, and so their one or two attending students tend to get swept into another group for the sake of the discussion. So, frequently, we have three or four discussion groups even though there are six teams. The students did not comment on this phenomenon in their reflections, but their design reveals a focus on what actually happens in class, not what could happen if everyone showed up.

One of the students explained that the group of chairs around the trash can provided a "symbolic receptacle for bad ideas." While no one was sitting at this cluster originally, it was used once I had them split into interteam groups for discussion. 

At the end of the meeting, I asked the students to help rearrange the room into its conventional form for the next class. Someone pointed out the last alteration, which I had not noticed. Several students commented on a mix of serious and silly design ideas, and I'm glad to see that they weren't afraid to get their hands dirty.
Side Board
This was my first time using this exercise in class, but I plan to use it again. It was a manageable design and evaluation problem. In fact, it worked better than some of the paper prototyping exercises I have used, which I attribute to the physicality of the classroom space and concreteness of the problem: it's a real design problem that we face three times a week, Monday-Wednesday-Friday at 8AM. This exercise also gave the students an opportunity to control their environment, to exercise agency in a setting that is too often formal and stuffy. Finally, it was memorable—when else do they get to create eraser art in a Computer Science classroom?—which means it is something I can draw upon later when talking about design, evaluation, and what we learned this semester.

Wednesday, April 3, 2013

Java Generics Trivia: A Tale of Syntax Discovery and Clean Code

I have spent years working with Java, although never as intensively as during my graduate school years. A significant part of my effort in graduate school was in gaining a deep understanding of the semantics of Java. There have been a lot of changes in Java since then—generics being among them. Today, while doing some programming, I came across something that I didn't know you could do.
I am writing a generic fixed-size grid class: it contains width*height elements that are indexed by <column,row> pairs. When faced with the problem of making a grid in a specific size, my first thought was to do it this way:
class Grid<T> {

  public static Grid create(int width, int height) {
    return new Grid(width,height);
  }

  private Grid(int width, int height) {
    ...
  }

}

However, I am also trying to follow Clean Code as closely as I can. In particular, I wanted to reduce all my methods to zero or one parameter, so I decided to introduce a builder here instead of the static factory method. In fact, I had just shown a similar example in CS222 last week—though, notably, without generics.

My refactored version, then, looked like this:
class Grid<T> {
  public static <T> Builder<T> width(int width) {
    return new Builder<T>(width);
  }

  public static final class Builder<R> {
    private final int width;

  private Builder(int width) {
    this.width = width;
  }

  public Grid<T> height(int height) {
    return new Grid<T>(width, height);
  }
}

Isn't it pretty? No method has more than one parameter, and the structure of the method calls enforces that I cannot get a Grid object without specifying its width and height. I returned to my calling code—a private createGrid utility method within my test suite for this class—and replaced the call to the static factory method with the following. (Note that Integer here is the data stored in the grid and is not related to the int width and height; the dimensions are always int regardless of the stored data since I am dealing with a discrete grid.)
Grid<Integer> grid = Grid.width(10).height(10);

I was surprised when the compiler complained. It sure looks a lot like the handy type-inferring methods of Guava such as Lists.newArrayList, that keep me from having to pepper new and angular braces throughout my code. Yet, the compiler insists that it cannot convert a Grid<Object> into a Grid<Integer>.

Clearly the problem is with the generics. To test my understanding of type inference, I converted the code to the following:
Grid.Builder<Integer> builder = Grid.width(10);
Grid<Integer> grid = builder.height(10);

This worked fine, but it obviously is not the kind of code I want to write when creating grid objects. If I was happy with this kind of awkwardness, I wouldn't have pedantically followed Clean Code in the first place.

I could not see a clear escape from here, but I began to wonder what kind of syntactic stunts I could pull to get this to work in fewer characters. I tried the following on a whim:
Grid<Integer> grid = Grid.<Integer>width(10).height(10);

If this kind of code showed up in Naftalin and Wadler's book on generics that I read six years ago, I certainly don't remember it. I pride myself on my mental Java compiler, but my brain still stutters when I look at this code.

The good news is that it works, and I learned something about the language in which I like to claim expertise. (I suppose I knew enough to know what to try, and that says something.) The bad news is that there is still a DRY violation in the generic types. If you can see a way to eliminate that, let me know!