Automatic Delegation Would Be Nice

Last night I finished the core of the extended Class implementation supporting annotations with subtyping. I load default values, but I punted on the order of the members in the toString() method. As far as I know, it is implementation-specific anyway.

Today I decided not to go to the office, but instead work from home. My workstation here has a better setup for coding, and I felt I was at the office long enough yesterday and that my presence wasn’t necessary for grading anymore, because as far as I know the missing grad TA had returned.

So I spent most of today writing extended versions of the Constructor, Method, Field and Package classes. I was able to factor most common code out, so implementing the core functionality wasn’t hard. Now I’m working on the supporting methods, e.g. those that allow you to get a Method from a Class object, without having to refer back to Java’s original Class object.

In essence, I’m creating gigantic wrappers for Java’s classes, and I’m forwarding each call to the corresponding method in the original class. It would be nice if this could be automated, and in fact, I think that could easily be done, again through annotations and bytecode rewriting. Consider the following listing:

class A {
public void foo() { }
public void bar() { }
}

@DelegateTo(A.class)
class B { }

@DelegateTo(A.class)
class C {
public void bar() { }
}

The A class defines two methods, foo() and bar(). Classes B and C are then annotated with @DelegateTo(A.class). When the bytecode rewriting framework sees this annotation, it automatically adds all of A‘s methods to B and C and generates bytecode to forward the calls. In the case of C, only calls to foo() are automatically forwarded, because an implementation of bar() has been provided.

The problem with this is that many times some processing has to be done before and after the delegation. For example, in the public MethodEx getMethod(String name, ClassEx... parameterTypes)() method of my extended Class class, I have to extract the original java.lang.Class objects from the elements in the paramTypes array, then pass the new array to the original method, and then finally create a new extended MethodEx instance using the return value from the forwarded call:

public class ClassEx {
// ...
public MethodEx getMethod(String name, ClassEx... parameterTypes)
throws NoSuchMethodException, SecurityException {
Class[] pt = new Class[parameterTypes.length];
for(int i=0; i

This kind of processing is very common. Even though I'm writing several dozen methods that delegate, there are only about half a dozen ways to process data. This made me think of C++'s conversion operators (e.g. operator int() { return ...; }), which are basically user-designed casts with the ability to perform processing.

In the above example, the two processing methods I need are from ClassEx[] to Class[], and from Method to MethodEx. I could write a class with static methods to perform these conversions:

class Conversions {
public static Class[] convertToClassArray(ClassEx[] input) {
Class[] output = new Class[input.length];
for(int i=0; i

The names aren't really important, because the bytecode rewriting framework would look for a method with the correct input and output types for the conversion it has to perform. Some care needs to be taken, though, because Java doesn't allow overloading if only the return type differs. That's why I have suffixed the methods above with a description of the return type.

Now I can change the @DelegateTo annotation to specify a class that contains the conversion methods:

@DelegateTo(target=java.lang.Class.class, conversions=Conversions.class)
public class ClassEx { }

The bytecode rewriting framework will add all methods from java.lang.Class to ClassEx, but all occurrences of Class[] will be replaced by ClassEx[], and all occurrences of Method will be replaced by MethodEx. Instead of having a method public Method getMethod(String name, Class... parameterTypes)() like java.lang.Class, ClassEx will have a method public MethodEx getMethod(String name, ClassEx... parameterTypes)(). The String name is not processed in any way, because there is no conversion method from String to String, but Class... parameterTypes will be changed to ClassEx... parameterTypes, and the Class[] convertToClassArray(ClassEx[] input) will be used for the conversion. The return value will be changed from Method to MethodEx, and the MethodEx convertToMethodEx(Method input) method will be used for the conversion.

It probably makes sense to allow an array of classes with conversion methods, since the conversion methods may be spread out across several classes. The framework will have to check that there is no ambiguity as to which conversion method is used, i.e. there may not be two or more methods in all specified classes with the same input and output types. It may also be a good idea to allow different conversion methods for input and output. That would lead us to a syntax like this:

@DelegateTo(target=java.lang.Class.class,
input={InputConversions.class},
output={OutputConversions.class})
public class ClassEx { }

class InputConversions {
public static Class[] convertToClassArray(ClassEx[] input) {
Class[] output = new Class[input.length];
for(int i=0; i

Considering that this will handle the conversions for more than one method, I think the effort would well be worth it.

There's still a problem with type checking, of course: Since classes for which the forwarding methods should be generated automatically don't actually contain the methods in the source code, the Java compiler will emit errors whenever the methods are used. Compiling should therefore probably happen in three phases: First, all classes except the ones to be generated automatically are compiled; second, the automatic bytecode rewriting is done; third, all classes except the ones generated automatically are compiled again.

Share
Posted in Research, xajavac | Leave a comment

Print This Post Print This Post  

Long Day

This was a long but productive day so far: I got to the office at 10 AM to grade COMP 311 midterm exams because one of the graduate TAs was out of town. Due to scheduling conflicts, we didn’t actually grade, but that was fine with me, instead I had nothing better to do than work on subtyping for annotations.

I still don’t load default values, but annotations and arrays as members are now implemented. There’s still one small problem: I don’t quite know the order in which annotation members appear in the return value of a toString() call. At first I thought the members were sorted alphabetically, so I implemented my toString() method that way, but now that I have a few more test cases, I see both @TestTwoAnnotation(s="foo", i=123) and @TestTwoAnnotation(i=123, s="foo") as output, and so far I can’t a difference in their contexts.

Share
Posted in Graduate School, Research, xajavac | Leave a comment

Print This Post Print This Post  

From the Trenches

I’m still working on the API improvements to support annotations with subtyping. It turned out there is much more to do than I thought: Reading the class files, parsing the annotations and then creating the corresponding runtime objects is quite a bit of work, not difficult but tedious. I still have to deal with annotations as members, and with arrays of annotations and arrays of arrays. Additionally, I have to read out the default values of annotation members; right now, if a member isn’t specified, its value is null.

The high level parts of my framework make extensive use of the Visitor and Template Method design patterns. Unfortunately, I made a mistake again that I’ve made often, and that I’ve pointed out very often too. Consider the visitor interface and the abstract class implementing it:

interface IVisitor {
public R intCase(IntLeaf host, P param);
public R addCase(AddNode host, P param);
public R mulCase(MulNode host, P param);
}
abstract class ADefaultVisitor {
public abstract R defaultCase(INode host, P param);
public R intCase(IntLeaf host, P param) {
return defaultCase(host, param);
}
public R addCase(AddNode host, P param) {
return defaultCase(host, param);
}
public R mulCase(MulNode host, P param) {
return defaultCase(host, param);
}
}

The abstract class implements a very simple Template Method pattern: It adds an abstract method that needs to be implemented, and then implements all the methods from the interface so that they call the new method. A default visitor like this is useful when most cases of a visitor are treated the same, e.g. during error checking when only one case is acceptable and all other cases should throw an exception:

class LeafOnlyVisitor {
public Void defaultCase(INode host, Void param) {
// called by addCase and mulCase
throw new RuntimeException("leaf expected");
}
public Void intCase(IntLeaf host, Void param) {
return Void.TYPE;
}
}

Unfortunately, it’s very easy to accidentally change the signature of the method that we’re trying to override, and therefore not override the method but add another method, one that is never called. In the first of the two examples below, the method name is misspelled; in the second, the type of the first parameter is different.

class LeafOnlyVisitorFlawed {
public Void defaultCase(INode host, Void param) {
// called by addCase and mulCase
throw new RuntimeException("leaf expected");
}
public Void untCase(IntLeaf host, Void param) {
return Void.TYPE;
}
}

class LeafOnlyVisitorFlawed2 {
public Void defaultCase(INode host, Void param) {
// called by addCase and mulCase
throw new RuntimeException("leaf expected");
}
public Void intCase(INode host, Void param) {
return Void.TYPE;
}
}

In both cases, there is no compiler error, because all methods from the interface and the method from the abstract class have been implemented, so it’s often difficult to discover this problem. I just realized how nice it would be to specify that subclasses of a class may only override methods, never add new methods. Using annotations, the syntax could look like this:

@OverrideOnly
abstract class ADefaultVisitor {
public abstract R defaultCase(INode host, P param);
public R intCase(IntLeaf host, P param) {
return defaultCase(host, param);
}
public R addCase(AddNode host, P param) {
return defaultCase(host, param);
}
public R mulCase(MulNode host, P param) {
return defaultCase(host, param);
}
}

When the classes LeafOnlyVisitorFlawed and LeafOnlyVisitorFlawed2 accidentally add a method instead of overriding one, an annotation-based checker could emit errors.

To allow better code reuse, it probably makes sense to allow private methods to be added to a class marked @OverrideOnly.

Share
Posted in Research, xajavac | Leave a comment

Print This Post Print This Post  

Subtyping for Annotations

Last night, I managed to change the Java compiler to parse and encode annotations with inheritance. I’ve complained about this shortcoming many times already: Even though subtyping (inheritance) is one of the core concepts in Java, and even though annotations are represented using (slightly enhanced) interfaces, which support inheritance, Java disallows inheritance for annotations. I never quite understood why.

I’ve now created a modified compiler, based on the LAPT-javac compiler I wrote a while back. The new compiler is called xajavac, for “eXtended Annotation javac”, and supports annotations on local variables, like LAPT-javac, and subtyping for annotations.

Now I can write the following:

@interface InvariantAnnotation { }
@interface OnlyThreadWithName extends InvariantAnnotation {
String value();
}
@interface OnlyEventThread extends InvariantAnnotation { }
@interface Or extends InvariantAnnotation {
InvariantAnnotation value();
}

@Or({@OnlyThreadWithName("main"),
@OnlyEventThread})
void foo() { ... }

I’m now working on providing an API that supports access to these annotations at runtime.

Share
Posted in Research, xajavac | Leave a comment

Print This Post Print This Post  

Submitted!

I submitted my thesis today. I had verified and changed a few things in my bibliography, I made some changes in chapters that I hadn’t proofread so well (chapters 5 and 6), and then, just a little before 7 AM, I began printing. I had to print at night or early in the morning, because otherwise someone might start a print job and use up my $25 per ream paper. After I’d printed, I diligently went through both copies and made sure that all 145 pages were there and in the right order.

After that, I had to go on a scavenger hunt sort of trip. From my office, I went to the Registrar to drop off my Application for Degree. Then I went to the Cashier’s Office to pay $93 of fees for binding and microfilming. After that, I took all my copies and forms and the yellow receipt from the Cashier, which right now is the ABSOLUTELY MOST IMPORTANT PIECE OF PAPER I HAVE, up to the Office for Graduate Studies. There, it was checked that all my copies and forms were in order, distributed in four different piles, the yellow receipt was signed again, and then I was sent to the library. There, I dropped my two envelopes with the thesis copies off for binding, and got another signature on the yellow form of life and death. Then, I had to go to the Registrar again, to turn another few forms in and get the final signature on the yellow form. And that was it. Now the yellow form is in a water-proof safe. There’s nothing else I have to do to get the Master’s degree, but until I get that, the receipt is pretty much the substitute for it. I’m actually consider getting it framed until then.

In addition to the $93 for the fees, I have to pay for a diploma frame, starting at $180, which is probably the one I’ll take, because it matches best with the one I already have. And then there’s the cost of having it framed: Sheepskin needs to be framed as soon as possible, or it deteriorates. And I’m also getting a book set for $147. So… getting a graduate degree is pretty expensive: probably about $600, but it’s worth it.

Now I’ve started to hack around in the Java compiler again, because I just cannot accept that adding inheritance to annotations was so hard.

Share
Posted in Concurrent Unit Testing, Graduate School, MS Thesis | Leave a comment

Print This Post Print This Post  

Thesis: A Framework for Testing Concurrent Programs

A Framework for Testing Concurrent Programs

Rice University

A Framework for Testing Concurrent Programs
by
Mathias Guenter Ricken

A thesis submitted
in partial fulfillment of the
requirements for the degree

Master of Science

Incremental, test-driven development is sweeping the software industry, elevating testing from an ancillary activity to an integral part of the programming process. Unfortunately, in our recent experience developing production programs in Java, unit testing has only proven effective in assuring the reliability of code with a single thread of control; it is much less effective in concurrent programs.

To facilitate the development of concurrent programs, we are developing:

  1. An extension of the JUnit framework that actively supports the developer by treating tests that could silently ignore failures in auxiliary threads as test errors;
  2. A lightweight Java annotation language that can be used to specify and check the threading invariants of both existing and new code;
  3. A testing framework that can record and analyze the schedules of unit tests, detect deadlocks, and run the tests using modified schedules, increasing the likelihood that concurrency problems are discovered.
Share
Posted in Concurrent Unit Testing, MS Thesis, Publications | Leave a comment

Print This Post Print This Post  

Final Stages

I’m about to start with the final submission process. I’m going to go through the thesis a couple more times, check my bibliography, fill out the forms, pay the fees, and then submit.

Just out of curiosity, I generated new readability test scores just like I did in July. This time I got:

Total sentences: 819 (was 1534)
Total words: 12106 (was 18006)
Average words per Sentence: 14.78 (was 11.74)

Words with 1 Syllable: 7551 (was 11817)
Words with 2 Syllables: 2444 (was 3377)
Words with 3 Syllables: 1292 (was 1697)
Words with 4 or more Syllables: 819 (was 1115)
Percentage of word with three or more syllables: 17.44% (was 15.62%)
Average Syllables per Word: 1.62 (1.56)

Gunning Fog Index: 12.89 (was 10.94)
Flesch Reading Ease: 54.92 (was 62.79)
Flesch-Kincaid Grade: 9.27 (was 7.42)

It’s obvious that the number of words and sentences decreased quite dramatically. I’ve cut a few sections from my thesis, but not that much. This time, I spent more time removing listings and other text that wasn’t formatted properly in the text version of my thesis used for these readability tests. I’m pretty sure that bad formatting must have caused the July scores to be off.

I’m quite happy about the Flesch Reading Ease score. It’s recommended that authors keep it in the 60-70 range. According to my Gunning Fog Index, my writing has also graduated from the “Times, Newsweek” category to the “Wall Street Journal” ;)

Share
Posted in Concurrent Unit Testing, Graduate School, MS Thesis | Leave a comment

Print This Post Print This Post  

What Has Happened?

I haven’t written in 1.5 months. Hard to believe. I’ve actually felt a bit guilty about this already, so guilty in fact that I password-protected the blog so the lack of writing isn’t immediately apparent to the outside world. So what has happened in the last few weeks?

Well, not much, sadly, but even more sadly, also a lot. There hasn’t been too much going on in my research lately, but in my personal life a lot changed, and that definitely makes me depressed. My mother had to move out of her house, the house I grew up in, but my grief over this can only give me a small glimpse of how bad my mother must feel. And after nearly two years, my girlfriend and I split up. We’ve had our problems during the last half year, but I really thought we were going to solve them. It had been very comforting to know that, regardless of where my work will take me, I will be together with her. Now this certainty is gone, and quite frankly, I’m lost at sea. It’s a pretty hard time for me right now.

On the work side, I’ve gone through one major revision of my thesis, but unfortunately I missed the end of September to turn it in. Corky and I are now working on another revision, and we’re also looking at the concepts of a future extension of the invariant checking, and I plan to submit my thesis at the end of October. I feel that the text has become a lot more “crisp” after that first revision. Often I was unnecessarily verbose. I’ve also improved the samples in the listings, added benchmarks for different invariants, and removed two parts that seemed to criticize my own approach, even though the current alternatives also suffer from them and my work is in no aspect worse than what was already available.

I demonstrated some of my tools to Walid, and when I did that, I realized how much knowledge about the internals a user actually needs. For example, there was no simple way to relate the class-method-PC information in the deadlock monitor to a location in the source code. I could easily do that by disassembling the class file, looking at the line number table, getting the line number, then opening the correct file… This wasn’t convenient, but up to that point it seemed like that convenience would have a very high price.

After the demonstration, I decided to find a way to integrate DrJava into my tools. DrJava is an excellent IDE and has syntax highlighting and many other features, so it would have been absurd to replicate them. What I came up with now is a form of “remote control”: You can connect to an existing instance of DrJava and make it open files and jump to a certain line. Now I retrieve the file and line number from the class file automatically, then make DrJava display that file and line.

This also implements a feature request posted on SourceForge. However, now that I look at it again, I’m running exactly into the problem that Chris has mentioned there: When user A is already running DrJava on a machine and user B attempts to run DrJava on the same machine, user B’s DrJava connects to user A’s DrJava. Right now, I’m just listening on a particular socket, and as far as I know, only one process can have a socket open at any time. I’d have to write some sort of registry, even though the RMI registry probably already has that ability. We don’t want to make the RMI registry required, though. I don’t quite know how to solve that problem right now.

I also gave another talk on concurrent programming and testing, this time hosted by the Rice Computer Science Club. As expected, the audience consisted mostly of undergraduate students, so I’m glad I focussed more on the fundamentals, like race conditions, locking, deadlocks, etc. I think I used some very simple yet powerful examples to demonstrate the problems, simple enough to make them accessible to students in the 2nd or 3rd semester. Maybe I’ll get around to writing this up in a paper.

I also spend some time as interim TA for COMP 311, but I think this sums up most of what happened since my last post.

Share
Posted in Concurrent Unit Testing, DrJava, Graduate School, MS Thesis | Leave a comment

Print This Post Print This Post  

Presentation: Testing Concurrent Programs

Testing Concurrent Programs

Where: Rice University Computer Science Department, Rice Computer Science Club
When: October 4, 2007

A talk directed mostly at undergraduate students.

Programming examples from the presentation.

Share
Posted in Concurrent Unit Testing, Publications | Leave a comment

Print This Post Print This Post  

First Day of the Semester

Today is the first day of the semester again, and I had the pleasure of being the first presenter in COMP 600, the noon PhD seminar series. It was a little bit chaotic because it was the first day and the food arrived later, so I lost about 10 to 15 minutes of my time, but in general I don’t think my presentation was all that bad. This year, there are evaluation forms, so I can read exactly how badly I did.

Obviously, I spent the last few days creating this presentation, which was based on my MS defense presentation, but much shorter and simpler. I finished the presentation on Sunday around noon (after an all-nighter), but then decided a few minutes before the presentation to cut a large but not that exciting part. I’m glad I did.

Other than that, I have worked a little on DrJava, though I didn’t manage to change our license and make a new release. I’ve also thought more about schedule generation, but I think I’m going to put that on a back-burner for a while again so I can do a final edit of my thesis and then submit it.

Update

About half of the feedback forms were pretty much useless to me, because they only included numbered ratings from 1 (good) to 5 (bad), and the audience seemed to be split evenly between people who liked my presentation and rated me with 1s and 2s, and people who didn’t like the presentation and dealt out 4s and 5s.

The most important comments for me probably were:

  • red on black not well visible (I should take into account that the
    projector’s contrast isn’t as good as my monitor’s)
  • still lots of text
  • needs more examples, if possible a demo
  • the invariant subtyping was a little dense on theory (I tried to
    stretch it out and make it easier, but it’s difficult to do that
    without spending a lot of time explaining subtyping in the lambda
    calculus)
  • include page numbers
Share
Posted in Concurrent Unit Testing, Graduate School, MS Thesis | Leave a comment

Print This Post Print This Post  

Presentation: A Framework for Testing Concurrent Programs

A Framework for Testing Concurrent Programs

Where: Rice University Computer Science Department, PhD Student Lunch Seminar
When: August 27, 2007

Incremental, test-driven development is sweeping the software industry, elevating testing from an ancillary activity to an integral part of the programming process. Unfortunately, in our recent experience developing production programs in Java, unit testing has only proven effective in assuring the reliability of code with a single thread of control; it is much less effective in concurrent programs. To facilitate the development of concurrent programs, we are developing:

  1. An extension of the JUnit framework that actively supports the developer by treating tests that could silently ignore failures in auxiliary threads as test errors;
  2. A lightweight Java annotation language that can be used to specify and check the threading invariants of both existing and new code;
  3. A testing framework that can record and analyze the schedules of unit tests, detect deadlocks, and run the tests using modified schedules, increasing the likelihood that concurrency problems are discovered.
Share
Posted in Concurrent Unit Testing, Publications | Leave a comment

Print This Post Print This Post  

Lists and Implication Done

I’m back in Los Angeles now. I didn’t have time to do anything or write yesterday, it was a full day of walking around at ComicCon, taking in the beautiful beach at La Jolla, and sitting in the car to get back to LA.

I finished implementing implication and the unit tests, and I also successfully converted my program from sets to lists the day before yesterday already. Negation is now unary, and implication has to be binary as a two-member array. Now I need to change a few sections of my thesis because they are no longer accurate, but that may have to wait until I’m back in Houston on Tuesday night/Wednesday.

Share
Posted in Concurrent Unit Testing, MS Thesis | Leave a comment

Print This Post Print This Post  

Lists Instead of Sets

I’m currently being anti-social and sitting in the public library of San Diego. I decided not to go to ComicCon this morning. What I was interested in was getting an autograph from Ray Bradbury, perhaps my favorite author, but I would have had to stand in line to participate in a raffle whether I’d be allowed to stand in line for the autograph. I think I’ll just continue appreciate Bradbury unsigned. I may go later to to a Futurama panel.

Instead, I walked around in San Diego a bit. I visited the Maritime Museum, looked at the USS Midway carrier, then walked inland to a sandwich shop with WiFi that I had picked out for breakfast. It was closed. I then walked to the library, which was nearby and also had free WiFi, with the plan of picking out another place for food. I’d walked over two miles by then and was getting a bit toasty, though, so I stayed and flipped through the book on graph enumeration and Polya’s theorem. So far I’ve preferred the nice temperature inside the library over food, and I still haven’t eaten.

I continued writing the unit test for the implication operation that I couldn’t finish yesterday night. I wanted to do something like

@Combine(Combine.Mode.IMPLIES)
@interface ImpliesTest {
@IsNonZeroAnnotation[] value() default {
@IsNonZeroAnnotation(0),
@IsNonZeroAnnotation(0)};
}

but my program told me I couldn’t do that. For optimization reasons, I had used sets of annotations to be combined, not lists. I figured there was no reason to specify exactly the same annotation twice, so a set was more appropriate than a list. I still think it’s not strictly necessary to have the same annotation twice, but it can definitely be convenient. So now I’m changing my code from sets to lists, a pretty big change for a short stay at the library.

I think I should go eat soon, though. I can hear my stomach growl, even though I’m listening to the Rolling Stones with earphones.

Share
Posted in Concurrent Unit Testing | Leave a comment

Print This Post Print This Post  

San Diego

We just got to San Diego and checked into the hotel. Don’t have much time to write. Earlier today, I think I got IMPLIES for @Combine annotations implemented. I had to implement it as one member annotation that is an array of two elements. Otherwise, there’d be no way to guarantee a consistent ordering, since implication is not permutable.

Share
Posted in Concurrent Unit Testing | Leave a comment

Print This Post Print This Post  

Implication for @Combine

As during the last few days, I’m in the process of implementing some of Bill’s excellent suggestions. I have written an XOR operator for @Combine annotations and am now testing it more extensively. I have found a few bugs in the process already.

Soon I’ll begin to implement an implications operator. The problem is that I can’t really think of a way to generalize implication to more than two operands, and it definitely doesn’t work for less than two. So I think I’ll require it to have exactly two operands, and then I’ll also reverse my stance on the NOT operator and make it unary instead of using de Morgan’s law to generalize not to ANDN. That’s what the operation (NOT a) AND (NOT b) is called, as Dr. Greiner informed me.

My girlfriend informed me that I’d be really trendy if I worked on my thesis here in the cafe with free wireless. I feel like I’m a “Spassbremse” — a fun stopper. It’s a tad bit difficult to get work done right now, because officially I’m on vacation. I always have to maintain that casual, relaxed vacation look on my face. But I’ll try ;)

Share
Posted in Concurrent Unit Testing, MS Thesis | Leave a comment

Print This Post Print This Post  

Greetings from LA

My girlfriend and I are in LA right now, staying with her brother and his wife. The weather is beautiful here, but I don’t have constant internet access. I’ll try to go to a cafe about once a day to check my messages.

On Saturday, we’re going to San Diego, and Tuesday night we’ll be back in Houston. I’ll try to stay in touch.

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

Connexions

Ok, Moesday (Monday+Tuesday) was a little rough on me. I felt too sick to come to the office on Monday to work with Dr. Nguyen on Connexions, instead I extended the Thread Checker to support XOR @Combine annotations, as suggested by Bill.

At the group meeting, Corky announced today that IT had agreed to add RedHad 5 virtualization techniques to at least some of the computers within our reach. That would enable us to automatically test both on Linux and then on a virtualized Windows. MacOS seems more difficult, unless you use an x86 Mac and Parallels, for example. I think this is a great idea. I wonder if it’s based on my comment a few weeks ago about Parallels and always running tests on all major operating systems. It feels like I can take some credit for this decision.

Connexions is a terrible user experience. To take some HTML website (and HTML kind of resembles XML), the best way we have found so far is to paste it into Microsoft Word, mark the different paragraphs, headings and code examples with the CNX template values, then import the Word file into CNX. Doing so wrecks everything else you have done so far, so if you have uploaded assignment files and used their URLs for hyperlinks, the files will be gone, and you need to-reupload them. Of course, then the URLs change, so you need do change your document again… Since everything is running on a boneheaded-thick server and think clients, clicking on one “Next” button can make you wait 20 seconds.

I think there’s great value in formatting teaching material in a coherent way. But saying “hey, we’re making teaching material coherent, let’s first invent our own language”, that’s completely wrong. The inventors of Connexions project said it would change Computer Science curricula: When Corky, Stephen and Zung asked how it’s going to change CS curricula, they received no answer. After making a few attempts at translating my “Programming for Change” lecture and assignment for COMP 201 and the SIGCSE 2006 workshop to Connexions, I know exactly how it’s going to change CS curricula. CNX is going to mutate entire CS departments into packs of monkeys that take existing material, then use the mouse to select text passages and mark them with CNXML styles…

I really think Connexions would make a wonderful study of what went wrong in human-computer interaction. What they really need are good converters from plain text, HTML, DocBook, and perhaps TeX to CNXML so you don’t have to go through Microsoft Word, which is incredibly boring and tedious. The translations doesn’t have to be perfect, but work the most common cases. Then, Connexions needs a local editing system: There either needs to be a CNX system that can be installed on localhost so that all the work can first be done locally, with very low latency, or an offline-editing application.

I’m also usually a very late packer, but I already had all my things packed by 9 PM on Monday, because we had planned to spend the night at Diana’s mom’s place, so I wouldn’t have to be dropped off and picked up again. I was ready to spend an additional day away from my apartment. Then I found out I was a persona non grata in that household. Very encouraging, but I’m not going to let that spoil anything, at least not on my side.

Diana and I went to our first ballroom dancing lesson today, and I wasn’t surprised when we started with Foxtrot. It was taught a bit differently than what I had learned in Germany (during the four lessons I received; I don’t know much); for example, the men’s leading foot is the left in the US, but it was the right foot in Germany. I think Both Diana and I had fun, and we’ll definitely do it again. Sadly, we miss the Waltz lesson next Tuesday, so maybe we’ll just have to Waltz on our own ;)

The instructor was less forceful than the instructors I had at the “wedding dance crash course”; it was a more enjoyable experience, even though I think the biggest part was that I was dancing with Diana, my girlfriend (or stepping on the toes). I’m sure we’ll do it again.

After that, though, I was so tired, I pretty much fell asleep right away. When I woke up at midnight and 2 AM, I was surprised to find Diana still here. I thought she’d go home to finish packing. But we’ll make it, no doubt. I still have to pack my computer. We were able to change our seats to an exit row and sit next to each other, by the way. And I packed extra batteries so Diana can play her video game… ;)

For those who somehow do not know, Diana and I will be going to California for a week. I don’t know how accessible I will be, but I will let you know.

I’m looking forward to this trip. It’s going to be completely different. Of course, I’ve still taken all my code and two versions of my thesis with me…

Share
Posted in Concurrent Unit Testing, DrJava, Ramblings | Leave a comment

Print This Post Print This Post  

TSA, Here We Go Again

About half a year ago, Diana and I went to Kansas City, MO, to attend Ben and Becca’s wedding. While we had a great time at the ceremony, the reception, spent December 31st leisurely, and then had fun at the New Year’s party, our nice getaway was marred by the strictness of a TSA inspection we had to endure.

Tomorrow, we’re flying again, this time to California. I hope bigger airports mean bigger brains when it comes to determining what couldn’t be a threat, so my brand-new 4 oz too-big tube of toothpaste may survive confiscation. I’ll probably have a score to settle when we return, but there’s one thing that I can do right now: I just bought 1-quart ziplock bags. The bags we had last time too. At the Kansas City airport, we were stripped of our bags because they were too large and were given sandwich-sized bags. So, here’s the size comparison.

This is the sandwich-sized bag with all my stuff crammed into it:
TSA-Issued Sandwich-Sized Bag With My stuff

This is just my liquid stuff I want to take aboard: deo, toothpaste, two kinds of eye drops (I wear contacts), two bottles of shampoo swiped from a previous hotel, and a bottle of contact lens cleaner:
Bought New Bags, Officially Designated “Quart-Sized”, at Store

This is a comparison of the two bags: The smaller one, on the left and on top, is the TSA-issued bag. The bottom one is the 1-quart bag I just bought that meets TSA specification. As you can see, the TSA employees took away our 1-quart bags, which were fine, and gave us new bags that were about 25% smaller:
The TSA-Issued Bag Was About 25% Smaller Than Quart-Sized

Here, finally is all my stuff, which now easily fits into the bag. I wonder if I could even throw in my 6 oz flask to make the flight a bit shorter ;)
A Quart-Sized Bag Fits Quart-Sized Stuff

Share
Posted in Pictures, Ramblings | Leave a comment

Print This Post Print This Post  

Thesis, Quantitatively

Google added a few figures to their “Word Count” feature that are supposed to measure how easy to read a document is. I tried to find out more about these figures, because the “Fleisch-Kincaid Grade Level” didn’t really tell me all that much. While searching, I found the Juicy Studio: Readability website that gave me even more numbers. Even after reading what the numbers mean, still find them pretty meaningless, but they are interesting enough to share.

Currently, my thesis generates the following results:

Total sentences: 1534
Total words: 18006
Average words per Sentence: 11.74

Words with 1 Syllable: 11817
Words with 2 Syllables: 3377
Words with 3 Syllables: 1697
Words with 4 or more Syllables: 1115
Percentage of word with three or more syllables: 15.62%
Average Syllables per Word: 1.56

Gunning Fog Index: 10.94
Flesch Reading Ease: 62.79
Flesch-Kincaid Grade: 7.42

Both the Gunning Fog Index and the Flesch-Kincaid Grade are supposed to represent the years of schooling the reader will have to have received to understand the text. My thesis apparently is accessible to high school juniors or even freshmen, depending on what figure you use. Typical Gunning Fog Index values for academic papers are 15 to 20.

Share
Posted in MS Thesis, Ramblings, Research | Leave a comment

Print This Post Print This Post  

DrJava and the Order of the Phoenix

Today I took another look at the DrJava 1.6 compiler problem and tried to implement it the way Dan had set it up. It seems to work. Please check out revision 4201 and take a look.

I also made some changes requested by Walid in the timed Java interpreter stuff, and I’m trying to add unit tests for the predicate exceptions. Honestly, though, I’m too tired to continue this now, though.

I just got back from an all-you-can-eat Sushi buffet and watching the latest “Harry Potter” movie. At times, I felt like fast-forwarding, and often it seemed like a best-of clip from the previous movies, but I think the 5th movie was better than the 4th

Share
Posted in DrJava, Ramblings, Research | Leave a comment

Print This Post Print This Post