Archive for December, 2007

On the Ground in Iowa

One of the many phrases we hear ad nauseum during the campaign season.

On the Ground in Iowa

Privacy? Google Crossed the Line.

With the release of Google Stalker Buddy, they no longer even pretend to respect our privacy. Damn these guys are good: GPS, mapping, cellular triangulation…it’s so perfect.

Google Stalker Buddy

Google Did Not Ruin My Christmas

Having a 102+ fever all day…THAT ruined my Christmas.

You can find my shared items right here.

Comic: Stevey on Bloated Code

Steve Yegge’s recent rant (his own term) “Code’s Worst Enemy” is stirring up quite a bit of chatter. That’s all the background you need.

Yegge

2007 Year in Review

2007 year in review…

  • 2007 was not The Year of the Linux Desktop.
  • 2007 was the year of Google. They released app upgrades at at astonishing rate, and the pace is accelerating.
  • Phrase of the year: wide stanced.
  • Actually, 2007 was the year of the taser. Don’t tase me, bro.
  • 2007 brought us the most disgusting video in the history of the internet. That’s saying something. Recording people’s reactions to the video is a popular YouTube meme.
  • Vista is about a year old. We have far more device drivers and stability is just fine. It is still a resource hog compared to XP, the bundled apps (Paint, Notepad, etc) still suck, and usability is hampered by constant popups (affectionately known as barkware, a term I learned from Brad Shuler). Overall impression? Meh.
  • Apple didn’t tell us how they feel about Java.
  • An astronaut wore a diaper and drove 900 miles to confront a romantic rival.
  • Celebrities in the news: OJ Simpson, Paris Hilton, Britney Spears, Dog the Bounty Hunter, Lindsey Lohan.
  • In 2007, the Zune finally caught up to iPod. The 2005 iPod.
  • A never-ending list of Java 7 features are on everyone’s mind. Meanwhile, thousands of corporate IT departments still use 1.4.

That’s all I can think of right now.

Best Spam of 2007

I just received the best spam email of 2007:

Subject: “Drop up to 20 pounds in a day”
Sender: “colon cure”
Content: “America’s Favorite Colon Cleanse!”

America has a favorite colon cleanse? Uh…

I hear a similar ad on the radio all the time, describing the backup as “like spackle” on the walls of your intestines. Reminds me of the colon blow skit on SNL.

This is funny because somewhere out there, someone actually believes there is 20 POUNDS of shit backed up in their system. Better get your plunger ready.

IE 8 Passes Acid2 Test

Didn’t see this one coming…today the IEBlog breaks the IE 8 cone of silence:

Last week, we achieved an important milestone that should interest web developers. IE8 now renders the “Acid2 Face” correctly in IE8 standards mode.

Here is how Acid2 renders today, under IE7 on Vista:

Acid2 on IE7 Vista

Under IE8 “in standards mode”, the face renders like this:

Acid2 on IE8

Standards Mode or Quirks Mode?

Here is the first line of the Acid2 Browser Test test page:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">

That line actually puts IE7 into something called “Almost Standards Mode”, according to the Wikipedia Quirks mode article.

Watch the Video

When you visit the Acid2 Browser Test page, will IE8 be in “Almost Standards Mode”, or will it render in “Standards Mode”?

The IEBlog did not make this clear. I found myself wondering if they did this:

  1. Visit the Acid2 Browser Test page
  2. Save the source to a file
  3. Edit the first line of HTML to something that puts IE8 into standards mode
  4. Load that slightly modified file

Fortunately, the Video on Channel 9 clears this up. Fast forward to around 21:30 in the video to see that the smiley face renders correctly on the live site, not on a modified local copy.

This is really good news. Let’s hope they continue improving standards compliance in IE8 and beyond.

Java Upgrade Hammer

Enjoy the new comic…

Java Upgrade Hammer

Generics Journey Continues

Brain Explode
WARNING: Brain Might Explode

I’m not sure I will ever fully grok Java generics. Kevin’s explanation of Set.contains() was enough to prod me into well over 1 TimeUnit.HOURS of experimentation tonight.

While I can say that I follow his examples and could verify all of the behavior he describes, I cannot say I have a sense of deep confidence in this dark corner of the language.

What I Did

I wanted to experiment with different variations of Set.contains(...), but modifying the JDK Set interface would be quite complex. Instead, I wrote my own little interface:

public interface MySet<E> {
  boolean contains(Object o);
  boolean add(E o);
}

Along with a simple implementation (that merely delegates to the real HashSet), this is enough to tinker with the concepts.

Step 1: Verify Kevin’s Claims

As expected, the code below works exactly as he describes:

public class Main {
  public static void main(String[] args) {
    MySet<Long> set = new MyHashSet<Long>();
    set.add(10L);
    if (set.contains(10)) {
      System.out.println(”10 is contained!”);
    } else {
      System.out.println(”10 is NOT contained!”);
    }

    MySet<Foo> foos = new MyHashSet<Foo>();
    MySet<SubFoo> subFoos = new MyHashSet<SubFoo>();
    doSomeReading(foos);
    doSomeReading(subFoos);
  }

  public static void doSomeReading(MySet<? extends Foo> foos) {
    // EDIT: my first post incorrectly said new Foo() {}; here
    Foo aFoo = new Foo();
    System.out.println(foos.contains(aFoo));
  }
}

When you run the above code, it prints “10 is NOT contained!”, plus a few “false” messages from the dummy method.

Step 2: Modify Set.contains(…)

Now I tried changing my contains(...) method to this:

boolean contains(E o);

This breaks the sample program in two places. First, this line fails (which is actually good):

if (set.contains(10)) {

That’s nice because 10 is boxed into an Integer, and our Set expects a Long. Changing the parameter to 10L fixes that issue.

The second breakage is a problem, however:

System.out.println(foos.contains(aFoo));

I tried all sorts of mojo and came up with this ugly hack:

public static <T extends Foo> void doSomeReading(MySet<T> foos) {
  T aFoo = (T) new Foo();
  System.out.println(foos.contains(aFoo));
}

You know what? Everything compiles now. Only…with a warning:

Unchecked cast: ‘Foo’ to ‘T’

Damn.

Step 3: Try Something Else

So now I tried changing contains(...) to this:

boolean contains(? extends E o);

That won’t even compile. IDEA says “Wildcards may be used only as reference parameters”. Uh, yeah.

Step 4: Try Again

Then I tried this:

<T extends E> boolean contains(T o);

Hey, at least that compiles! As in my earlier attempt, the sample program fails to compile in the same two spots. I can fix the first issue by passing 10L, just like before.

And the same doSomeReading(...) hack also compiles, although with the same ugly warning as before.

Closing Thoughts

  • Given the way generics work today, contains(Object o) seems better than any alternative.
  • IDEA’s “Suspicious call to ‘Set.contains’” warning only works with the built-in collections. The warning does not fire for my custom MySet interface.
  • I have to wonder…is there some underlying language improvement that could simultaneously allow both strict contains(E o) signatures while also supporting the substitutability principle for collections?

One more thing…all this talk of adding closures to Java…that scares me to death. Spontaneous brain explosion is a serious concern, already affecting 3% of Java programmers. With closures added to mix, that number will undoubtedly rise.

JavaBeans PropertyChangeSupport Trick

I’ve always written bound properties like this:

public class Rect {
  private PropertyChangeSupport changes = new PropertyChangeSupport(this);
  private int width;

  public void setWidth(int width) {
    int old = this.width;
    this.width = width;
    changes.firePropertyChange("width", old, width);
  }
}

I just realized that the 3-line setWidth(...) method can be compressed to a single line:

public void setWidth(int width) {
  changes.firePropertyChange("width", this.width, this.width = width);
}

It seems like this might reduce a significant amount of boilerplate code for some types of apps.

UPDATE

As pointed out in the comments, for non-primitive properties, null values (both old and new) will trigger unwanted events. Although generally harmless, firing too many events can cause significant performance problems, particularly if you trigger repainting in the GUI for properties that didn’t really change.

So you might want to do this:

public void setName(String name) {
  if (this.name != null || name != null) {
    changes.firePropertyChange("name", this.name, this.name = name);
  }
}

Or this, depending on your style:

public void setName(String name) {
  if (this.name == null && name == null) {
    return;
  }
  changes.firePropertyChange("name", this.name, this.name = name);
}