Just a heads up that, following what seems to become an established previous tradition, I'll be attending the JAOO conference this year as well. See ya in Aarhus next week!
Friday, September 21, 2007
Thursday, September 20, 2007
Laugh-Out-Loud Cats
I'll admit that I was mildly annoyed by the whole LOLCats meme. I don't say I didn't get it; I did, I just felt it overdone after a while and couldn't be bothered to pay attention to yet another photo with funnilz missspelt all-caps would-be-jokes superimposed on them.
Until Ape Lad created something wonderful out of it.
Ape Lad, or Adam Koford is an illustrator maybe best known for his graphical interpretation of various hobos from John Hodgman's book "Areas of My Expertise", but I think that soon he'll be referred to primarily as "the guy who created Laugh-Out-Loud Cats".
So, what is it he did with the LOLCats phenomenon? He created a 1920-style cartoon featuring two vagabond cats, as he himself says "one Meowlin Q. Kitteh (a sort of cat hobo-raconteur) and his young hapless kitten friend, Pip"
. These cartoons are produced traditionally, pen-and-paper, and have an incredibly authentically-feeling atmosphere of the '20s, plus a fantastic chemistry resulting from mixture of innocence, mischief, and cuteness overload in the characters. Just click on the image to the left for the gallery -- it's all available for free viewing on his Flickr account, and I'm looking at its RSS feed with most anticipation every morning for updates (and I'm seldom disappointed, because the guy is really prolific)!
Of course, you might as well check out his other fine works, like his graphical interpretations of various HTTP error codes (to the left, you can see "415 Unsupported Media Type").
Tuesday, September 18, 2007
Liquids on planes in Europe will be allowed again!
Frequent air travelers rejoice!
Apparently, Norwegian Ministry of Transportation asked the European Parliament to move to lift the liquid ban on airplanes. They say it is "annoying for the travellers", and a "large cost for society".
And apparently, the European Parliament agrees!
Sorry if I'm sounding euphoric about this, but this mindless fake security measure did cause me lot of headache in the past. Sometimes literally - there are those situations when I need to catch a transfer and the itinerary is so tight I barely can run from one gate to the other and I don't have time to grab an (overpriced) bottle of water at the airport, so I get a headache of dehydration by the end of the trip. small glasses of water and orange juice served at the airplane are not the same thing. Actually, lately I switched to carrying apples with me for liquid replenishment.
In the meantime, I need to find an (a) aerosol deodorant not exceeding 100ml and (b) shaving foam container not exceeding 100ml for my next week's trip to JAOO in Aarhus (I'm flying with hand baggage only). I figure I can just use the hotel bathroom soap in dire need instead of the shaving foam though. Oh man, can't wait for this madness to end.
Sunday, September 16, 2007
Closures in Java NOW!
I remember Neal Gafter's talk about his idea of how to implement closures in Java that he gave at TSSJS in Las Vegas this March, and I have to say, if we had this feature today, it'd be none too soon.
Lack of closures does give Java a reeeally bad feel in 2007. It makes it very backwards looking in terms of modern programming language amenities, compared to languages that already have them.
Here, let me show you an example.
As we all know, in Java, objects can't control their own locking - they can't customize their behavior when used in a synchronized block. Now, that's one entertaining problem in its own right, and would deserve its very own discussion, as basically, it makes correctness of synchronization dependent on implementation. But that's not the point of this post. The point of this post is how one might try to work around this and similar lackings, and how one will inevitably fail...
Okay, the example: let's suppose I have a class A. I sometimes need to lock instances of it. This is a no-brainer in Java and usually has the form of
synchronized(a) {
... do something...
}
Let's suppose I also have a subclass B of A. Instances of B have a reference to another object of some class S, and various instances of B share some of their state through shared instances of S for some reason:
public class B extends A {
private final S shared;
...
}
Since the S instance is actually shared among several B instances, the correct locking semantics for B would be to always synchronize on the "shared" field of a B, when client code synchronizes on an instance of B. Unfortunately, there's no way in Java to declare to do a synchronized(b.shared) within every synchronized(b).
What's the next best thing I can do - provided I want to encapsulate the behavior and want to avoid some manual monster code1 at every synchronization site? A smart aleck like me would add a method to A:
public void runLocked(Runnable r) {
synchronized(this) {
r.run();
}
}
Then, I can override it in B:
@Override
public void runLocked(Runnable r) {
synchronized(this) {
synchronized(shared) {
r.run();
}
}
}
Finally, I can replace all occurrences of a synchronized(a) block with:
a.runLocked(new Runnable() {
public void run() {
... do something...
}
});
Sounds okay? Well, it isn't. Aside from the very obvious "too much visual clutter" problem, there are further problems with this:
- What if "do something" throws a checked exception? (Answer: more monster code2)
- What if "do something" modifies a local variable? (Answer: yet more monster code3)
- What if "do something" contains a return, continue, or break statement? (Answer: you are seriously out of luck, but some really horrid monster code might help you out. It is so ugly though that it does question the ROI of the whole approach. No, I won't give an example.)
So, what happens is that you eliminate ugliness in one place, only to have it resurface because of these other problems in another place. It is not really possible to arrive at a win-win situation with current language constructs. (Alternatively, I'm not smart enough to figure it out. Either way, pity). Needless to say, if we had real closures in Java instead of the very weak imitation attempt in form of java.lang.Runnable, none of these would be a problem.
1 the monster code in question would look something like:
synchronized(a) {
if(a instanceof B) {
synchronized(((B)a).getShared()) {
... do something ...
}
} else {
... repeat do something ...
}
}
2 the monster code for working around checked exceptions would be:
try {
a.runLocked(new Runnable() {
public void run() {
try {
... do something ...
} catch(RuntimeException e) {
throw e;
} catch(Exception e) {
throw new UndeclareThrowableException(e);
}
}
});
} catch(UndeclaredThrowableException e) {
Throwable t = e.getCause();
if(t instanceof Exception) throw (Exception)e;
if(t instanceof Error) throw (Error)e;
throw e;
}
And it can get even more fun if you're trying to only get a specific type of a checked exception (say, IOException) and not a generic Exception across the scope.
3 the monster code for working out local variable modifications would be:
final Object[] embeddedLocalVar = new Object[1];
embeddedLocalVar[0] = realLocalVar;
a.runLocked(new Runnable() {
public void run() {
... do something ...
embeddedLocalVar[0] = newValue;
}
});
realLocalVar = embeddedLocalVar[0];
Pure beauty, innit?
Friday, September 07, 2007
"How can a spinozan cast a dualism spell?"
If you enjoy reading works of Jostein Gaarder (come on, you must've read at least "Sophie's World", haven't you?), and if you likewise enjoy reading any or all of Greg Egan, Charles Stross, or Neil Gaiman, then you'd adore a hilarious webcomic about (in no particular order): philosophy (if you can actually get the joke in the post title), quantum physics, psychology (with regular appearances of "Tiny Carl Jung"!), all with a big dose of surrealism.
That's exactly what Dresden Codak is.
If I may recommend, start reading from this one, as it and the next few ones are extraordinarily brilliant (contrasted with the rest, which are just, well, ordinarily brilliant). Then revisit the older ones after you reached the end.
My only woe is that there aren't too many of them yet, and it's not updated too frequently. But hey, quality work needs time!